重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
在GTID-based复制中,如何扩容一个只读实例?
创新互联公司成立与2013年,先为临泉等服务建站,临泉等地企业,进行企业商务咨询服务。为临泉企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
这里使用MySQLdump工具在Master节点上进行数据备份,注意一个关键参数:--set-gtid-purged[=name],该参数代表在备份文件中,哪些GTID已执行过了,在change master时,复制将从这些GTID之后进行。
--set-gtid-purged[=name]
Add 'SET @@GLOBAL.GTID_PURGED' to the output. Possible
values for this option are ON, OFF and AUTO. If ON is
used and GTIDs are not enabled on the server, an error is
generated. If OFF is used, this option does nothing. If
AUTO is used and GTIDs are enabled on the server, 'SET
@@GLOBAL.GTID_PURGED' is added to the output. If GTIDs
are disabled, AUTO does nothing. If no value is supplied
then the default (AUTO) value will be considered.
mysqldump命令如下:
$ bin/mysqldump --user=root --password='123456' --socket=/home/mysql/mysql3309/tmp/mysql.sock --default-character-set=utf8mb4 --events --routines --triggers --force --hex-blob --quick --single-transaction --set-gtid-purged=ON --databases db1 lg > /tmp/bak/data.sql
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.
观察备份文件data.sql,会发现两处值得注意的地方:
·使用备份文件导入数据时,将会话级系统变量@@SESSION.SQL_LOG_BIN设置为了0,即不产生二进制日志。
SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN= 0;
...
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
·设置了全局系统变量@@GLOBAL.GTID_PURGED。
SET @@GLOBAL.GTID_PURGED='0c34233d-b2e1-11e9-85cf-080027f22add:1-2,
32a0c858-b59f-11e9-b069-0800270c3d91:1-2,
447e96e1-b59f-11e9-95fe-0800270c3d91:1-2,
4fdc13e1-b59e-11e9-b5e0-080027f22add:1-9,
b8282f18-b59e-11e9-83b0-0800270c3d91:1-5';
同时也设置了@@GLOBAL.GTID_EXECUTED,这就是复制从何处开始的依据。确切的说是,@@GLOBAL.GTID_EXECUTED为空时,才能设置@@GLOBAL.GTID_PURGED,否则报错如下。同时@@GLOBAL.GTID_EXECUTED会设置成和@@GLOBAL.GTID_PURGED具有相同的值。
ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
Query OK, 1 row affected (0.00 sec)
导入备份数据前,观察新Slave节点上@@GLOBAL.GTID_PURGED,和@@GLOBAL.GTID_EXECUTED的值。
[root@mysql.sock][(none)]> select @@GLOBAL.GTID_PURGED;
+----------------------+
| @@GLOBAL.GTID_PURGED |
+----------------------+
| |
+----------------------+
1 row in set (0.00 sec)
[root@mysql.sock][(none)]>
[root@mysql.sock][(none)]> select @@GLOBAL.GTID_EXECUTED;
+------------------------+
| @@GLOBAL.GTID_EXECUTED |
+------------------------+
| |
+------------------------+
1 row in set (0.00 sec)
导入数据后,再观察。
[root@mysql.sock][(none)]> source /tmp/bak/data.sql;
...
[root@mysql.sock][lg]> select @@GLOBAL.GTID_PURGED;
+-------------------------------------------------+
| @@GLOBAL.GTID_PURGED |
+-------------------------------------------------+
| 0c34233d-b2e1-11e9-85cf-080027f22add:1-2,
32a0c858-b59f-11e9-b069-0800270c3d91:1-2,
447e96e1-b59f-11e9-95fe-0800270c3d91:1-2,
4fdc13e1-b59e-11e9-b5e0-080027f22add:1-9,
b8282f18-b59e-11e9-83b0-0800270c3d91:1-5 |
+-------------------------------------------------+
1 row in set (0.00 sec)
[root@mysql.sock][lg]> select @@GLOBAL.GTID_EXECUTED;
+-------------------------------------------------+
| @@GLOBAL.GTID_EXECUTED |
+-------------------------------------------------+
| 0c34233d-b2e1-11e9-85cf-080027f22add:1-2,
32a0c858-b59f-11e9-b069-0800270c3d91:1-2,
447e96e1-b59f-11e9-95fe-0800270c3d91:1-2,
4fdc13e1-b59e-11e9-b5e0-080027f22add:1-9,
b8282f18-b59e-11e9-83b0-0800270c3d91:1-5 |
+-------------------------------------------------+
1 row in set (0.00 sec)
最后change master即可。
CHANGE MASTER TO
MASTER_HOST='10.0.2.6',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_PORT=3309,
MASTER_AUTO_POSITION = 1;
注意,在一些特殊场景下,可能需要手动设置@@GLOBAL.GTID_PURGED。
在GTID-based的复制中,如何设置级联复制呢,要求复制拓扑如下,其中箭头代表数据的复制方向,括号中的部分还不存在。
S <- M (-> M' -> S')
若先建立M' -> S'的复制关系,使用mysqldump在M上备份数据,然后导入M',数据会从M'复制到S'吗,通过上面知道,导入数据时设置了@@SESSION.SQL_LOG_BIN= 0,所以数据不会从M'复制到S',这点是和Position-based复制不一样的,即如下方式不会设置SQL_LOG_BIN。
$ bin/mysqldump --user=root --password='123456' --socket=/home/mysql/mysql3309/tmp/mysql.sock --default-character-set=utf8mb4 --events --routines --triggers --force --hex-blob --quick --single-transaction --set-gtid-purged=OFF --master-data=2 --databases db1 lg > /tmp/bak/2data.sql
所以正确的思路是,用备份数据同时恢复M'和S',然后建立M' -> S',最后建立M -> M'。
对于Failover,由于不需要指定位点信息,直接change master即可,比Position-based复制简洁很多。另,通过前面几篇文章的介绍,也可以发现GTID-based的复制比Position-based复制在数据一致性方面更加严格,不像Position-based复制随便指定个位点,若复制过程无报错,就可以继续。
PS:使用xtrabackup备份数据时,上面的思路是完全成立的。