文章目录
  1. 1. 步骤总览
  2. 2. 设置数据库只读
  3. 3. 导出和导入数据库
  4. 4. 修改 MyCAT 配置文件

MyCAT 在使用过程中可能出现性能不足,需要添加服务器的情况,在增加服务器过程中,需要做数据迁移,难免出现业务中断等情况。本文实现一个最简单的 MyCAT 数据迁移步骤。

步骤总览

假定 travelrecord 表共有10个分片,分布在一台mysql的10个数据库中(dbtest0~dbtest9),需要将10个分片中的2个分片(dbtest0、dbtest1)转移到第二台MySQL上。大致步骤如下,

  1. 将需要迁移的2个分片设置为只读
  2. 将2个分片的数据导出,并在新增的数据库上将数据导入;
  3. 修改相应的 MyCAT 配置,并重新加载;

当然,这样的步骤,业务中断时间会比较长,主要时间浪费在数据导出导入的过程中。实际使用中,应该使用主从复制的方式将数据同步到从数据库中,再以从数据库中的数据为基础,启动第二台 mysql,这样,中断时间会短很多。

假定 travelrecord 表中共有10万条数据,每个分片上1万条,再假定这10个分片数据库中,每个数据库都只有这一个表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
mysql> explain select * from travelrecord limit 10;
+-----------+-------------------------------------+
| DATA_NODE | SQL |
+-----------+-------------------------------------+
| dn0 | SELECT * FROM travelrecord LIMIT 10 |
| dn1 | SELECT * FROM travelrecord LIMIT 10 |
| dn2 | SELECT * FROM travelrecord LIMIT 10 |
| dn3 | SELECT * FROM travelrecord LIMIT 10 |
| dn4 | SELECT * FROM travelrecord LIMIT 10 |
| dn5 | SELECT * FROM travelrecord LIMIT 10 |
| dn6 | SELECT * FROM travelrecord LIMIT 10 |
| dn7 | SELECT * FROM travelrecord LIMIT 10 |
| dn8 | SELECT * FROM travelrecord LIMIT 10 |
| dn9 | SELECT * FROM travelrecord LIMIT 10 |
+-----------+-------------------------------------+
10 rows in set (0.01 sec)
mysql> select count(*) from travelrecord;
+--------+
| COUNT0 |
+--------+
| 100000 |
+--------+
1 row in set (0.03 sec)

设置数据库只读

先设置 dbtest0 为只读,

1
2
FLUSH TABLES WITH READ LOCK;
SET GLOBAL read_only = 1;

设置只读之后,数据库的写操作将被阻塞。如果发现数据迁移的过程中发生错误,可以放弃迁移,恢复数据库可写,如下,

1
2
SET GLOBAL read_only = 0;
UNLOCK TABLES;

此时,如果 MyCAT 再有数据插入,就会阻塞,直到超时,如下,

导出和导入数据库

通常情况下,mysql 数据库可以使用 mysqldump 做导入导出,做全量备份。如下,

1
mysqldump -hworkstation -uroot -P3306 -p111111 dbtest0 > dbtest0.sql

再将数据导入到目标数据库中,

1
mysql -hworkstation -uroot -P3316 -p111111 dbtest0 < dbtest0.sql

可以验证一下数据库中的数据是否已经导入成功。

修改 MyCAT 配置文件

原先,travelrecord 的分片是如下配置的,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
......
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="travelrecord" dataNode="dn0,dn1,dn2,dn3,dn4,dn5,dn6,dn7,dn8,dn9" rule="mod-10" />
</schema>
<dataNode name="dn0" dataHost="localhost1" database="dbtest0" />
<dataNode name="dn1" dataHost="localhost1" database="dbtest1" />
<dataNode name="dn2" dataHost="localhost1" database="dbtest2" />
<dataNode name="dn3" dataHost="localhost1" database="dbtest3" />
<dataNode name="dn4" dataHost="localhost1" database="dbtest4" />
<dataNode name="dn5" dataHost="localhost1" database="dbtest5" />
<dataNode name="dn6" dataHost="localhost1" database="dbtest6" />
<dataNode name="dn7" dataHost="localhost1" database="dbtest7" />
<dataNode name="dn8" dataHost="localhost1" database="dbtest8" />
<dataNode name="dn9" dataHost="localhost1" database="dbtest9" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="workstation:3306" user="root"
password="111111">
</writeHost>
</dataHost>

只有一个数据库服务器,上面有10个数据库,实现了10个分片,采用的是 mod-10 算法(按10取余数),如果新增加了数据库服务器,就需要修改配置。修改后的配置如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
......
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<table name="travelrecord" dataNode="dn0,dn1,dn2,dn3,dn4,dn5,dn6,dn7,dn8,dn9" rule="mod-10" />
</schema>
<dataNode name="dn0" dataHost="localhost2" database="dbtest0" />
<dataNode name="dn1" dataHost="localhost1" database="dbtest1" />
<dataNode name="dn2" dataHost="localhost1" database="dbtest2" />
<dataNode name="dn3" dataHost="localhost1" database="dbtest3" />
<dataNode name="dn4" dataHost="localhost1" database="dbtest4" />
<dataNode name="dn5" dataHost="localhost1" database="dbtest5" />
<dataNode name="dn6" dataHost="localhost1" database="dbtest6" />
<dataNode name="dn7" dataHost="localhost1" database="dbtest7" />
<dataNode name="dn8" dataHost="localhost1" database="dbtest8" />
<dataNode name="dn9" dataHost="localhost1" database="dbtest9" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="workstation:3306" user="root"
password="111111">
</writeHost>
</dataHost>
<dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="workstation:3316" user="root"
password="111111">
</writeHost>
</dataHost>
......

修改完配置,使用 MyCAT 管理端登陆,重新加载配置,如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ mysql -hworkstation -utest -DTESTDB -P9066 -ptest
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.8-mycat-1.5-RELEASE-20160301083012 MyCat Server (monitor)
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> reload @@config_all;
Query OK, 1 row affected (0.43 sec)
Reload config success

此时,再去做插入数据,发现已经是在向新的数据库做插入了。用以上同样的步骤,可以迁移 dbtest1 的数据,在此不再赘述。

文章目录
  1. 1. 步骤总览
  2. 2. 设置数据库只读
  3. 3. 导出和导入数据库
  4. 4. 修改 MyCAT 配置文件

欢迎来到Valleylord的博客!

本博的文章尽量原创。