MyCAT 在使用过程中可能出现性能不足,需要添加服务器的情况,在增加服务器过程中,需要做数据迁移,难免出现业务中断等情况。本文实现一个最简单的 MyCAT 数据迁移步骤。
步骤总览
假定 travelrecord 表共有10个分片,分布在一台mysql的10个数据库中(dbtest0~dbtest9),需要将10个分片中的2个分片(dbtest0、dbtest1)转移到第二台MySQL上。大致步骤如下,
- 将需要迁移的2个分片设置为只读
- 将2个分片的数据导出,并在新增的数据库上将数据导入;
- 修改相应的 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
| +-----------+-------------------------------------+ +-----------+-------------------------------------+ | 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 | +-----------+-------------------------------------+ 10 rows in set (0.01 sec) +--------+ +--------+ +--------+ 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 的数据,在此不再赘述。