MySQL复制-GTID复制

1、GTID介绍(1) Global Transaction Id entifier – 全局事物ID (2)GTID = Server_UUID + Transaction_ID  Server_UUID 是全局唯一的  Transaction_ID 是自增的(3)GTID 的作用是替代 Filename + Position"root@localhost:mysql.sock  [(none)]>show variables like '%server_uuid%';+---------------+--------------------------------------+| Variable_name | Value                                |+---------------+--------------------------------------+| server_uuid   | 59b96e21-875e-11e8-aadd04a |+---------------+--------------------------------------+1 row in set (0.00 sec)在MySQL中看到的 UUID ,实际是保存在 $DATADIR/auto.cnf 中的,且该文件是服务器初始化的时候自动成的。[root@sf160132 ~]# cat /data/mysql_data/auto.cnf [auto]server-uuid=59b96e21-875e-11e8-aadd04a通过冷备做备份,拷贝 $DATADIR 时,记得要把备份中的 auto.cnf 给删除2、GTID作用如图:

假设现在没有GTID:当 Master宕机后,一个 Slave 被提升为New Master ,如果需要继续维持复制关系,就需要把另外两个Slave的 CHANGE MASTER 指向 New Master ;那问题来了,原来Slave是指向 Master 的 Filename_M + Position_M 的位置,现在要指向 New Master 上新的 Filename_N + Position_N 的位置,这 两个位置是比较难对应起来的 ; 此时两个Slave要继续复制(CHANGE MASTER)会比较麻烦。使用GTID:和上面一样的场景,两个Slave需要重新指向 New Master ,由于 使用了GTID ,目前 Slave-A 获取到的日志对应的 GTID=G_A , Slave-B 获取到的日志对应的 GTID=G_B ; 此时 New Master 上是存在 G_A 和 G_B ( 通过选举出来的,获取的日志应该是最多的 ),那两个Slave就可以直接使用 G_A和G_B 这两个GTID,通过指向 New Master 接着继续复制。3、GTID的配置[mysqld] log_bin = bin.loggtid_mode = onenforce_gtid_consistency = 1log_slave_updates=1注意各个版本的不同(1)MySQL 5.6 必须开启参数 log_slave_updates (5.6 版本的限制 ) log_slave_updates 详见级联复制(2)MySQL 5.6 升级到gtid模式需要停机重启 (3)MySQL 5.7 版本开始可以不开启 log_slave_updates (4)MySQL 5.7.6 版本开始可以在线升级成gtid模式4、基于gtid复制(1)注意事项在开启GTID后,使用 mysqldump 备份单个数据库时,会有 Warning ,大致意思为你只备份了部分数据库,但是启用GTID后包含了所有的事物,可以忽略该警告。当然我们还是看一下备份后的 metadata[root@Slave2 backup]> cat metadata SHOW MASTER STATUS:        Log: bin.        Pos: 194        GTID:c241b625-e932-11e5-bb11-5254f035dabc:1-11558 # 这里除了我们之前用过的 Filename 和 POS ,还有GTID注意:这个 metadata 中的 GTID:c241b625-e932-11e5-bb11-5254f035dabc:1-11558 的意思 等同于通过 mysqldump 备份得到的文件中的 SET @@GLOBAL.GTID_PURGED='c241b625-e932-11e5-bb11-5254f035dabc:1-11558'; 均表示为:这部分的GTIDs对应的事物已经在这个备份中了,Slave在还原备份后,进行复制时, 要跳过这些GTIDs (对应的事物)。(2) 跳过GTIDs如果备份使用 mysqldump 进行备份, 请跳过该步骤 ,因为在备份中已经存在下面这个语句-- GTID state at the beginning of the backup -SET @@GLOBAL.GTID_PURGED='c241b625-e932-11e5-bb11-5254f035dabc:1-11558';因为我们使用 mydumper 进行备份和还原, myloader 并不会帮我们执行上述语句,所以我们要手工执行该语句,让 Slave 知道这些GTIDs需要跳过--- Slave 1 端 mysql> SET @@GLOBAL.GTID_PURGED='c241b625-e932-11e5-bb11-5254f035dabc:1-11558'; ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.这里报出一个错误,意思为如果要设置 @@GLOBAL.GTID_PURGED ,则 @@GLOBAL.GTID_EXECUTED 必须为空我们需要使用 reset master; 命令,将 @@GLOBAL.GTID_EXECUTED 清空。--- Slave 1 端 -mysql> reset master; Query OK, 0 rows affected (0.07 sec)mysql> SET @@GLOBAL.GTID_PURGED='c241b625-e932-11e5-bb11-5254f035dabc:1-11558'; Query OK, 0 rows affected (0.02 sec)(3) CHANGE MASTER在Slave 1 端 change master to master_host="10.19.160.132", master_port=3306, master_user='rpl', master_password='1', master_auto_position=1; mysql> start slave;mysql> show slave status\G;后面验证数据与传统复制一样,这里就不解释了。5、GTID 与 Filename-Pos的对应通过扫 binlog中的GTID值,就可以知道 GTID与Filename-Pos对应的关系 ,但是如果binlog非常大,扫描的量也是会很大的,所以在binlog开头部分有一个 Previous_gtids 的event,如下所示"root@localhost:mysql.sock  [(none)]> show binlog events in 'bin.000007'\G;*************************** 1. row ***************************   Log_name: bin.000007        Pos: 4 Event_type: Format_desc  Server_id: 160132End_log_pos: 123       Info: Server ver: 5.7.17-log, Binlog ver: 4*************************** 2. row ***************************   Log_name: bin.000007        Pos: 123 Event_type: Previous_gtids   -- 表示在次之前,GTID运行到的范围是哪里  Server_id: 160132End_log_pos: 194       Info: 59b96e21-875e-11e8-a589-005056add04a:1-2979800