GTID(global transaction identifier)是一个在master对每个已提交到数据库的事务的唯一ID,不仅在master是唯一的,而是在整个复制架构中的数据库都是唯一的。
--- GTID
GTID = source_id : transaction_id
--- 示例
3D23AE58-72BD-55C2-8P66-E80NC9685729:66
source_id:执行事务的源数据库的uuid(server_uuid)
transaction_id:数据库自增的序列号,master执行的第n个事务
GTID复制工作原理
- Master数据更新,在事务开始时生成GTID并记录到binlog
- slave的I/O线程将变更的binlog数据写入relaylog
- slave的SQL线程从relaylog获取GTID,比对本地binlog,存在即忽略
GTID复制优势
- GTID可以辨别事务所提交的数据库
- GTID在宕机切换时,快速定位快速切换
GTID复制劣势
- GTID的独特机制,无法与非GTID模式的实例进行数据复制
- 一个事务中更新事务表和非事务表会产生多个GTID
- 同时更新事务表和非事务表,如果非事务表是临时表,那么同一个事务或一条语句中非事务DML被视为事务DML
GTID复制配置
基础环境与半同步复制相同,请参考《 MySQL数据库复制技术 Part 5 : 半同步复制》
master&slaves配置my.cnf文件
--- 配置my.cnf
[mysqld]
log_bin = /app/mysql5.7/logs/ocean-bin
expire_logs_days = 7
log_slave_updates = 1
binlog_format = ROW
gtid_mode = on
enforce_gtid_consistency = ON
Master创建同步账户
grant replication slave on *.* to 'rep'@'10.11.12.%' identified by 'root1234';
flush privileges;
Master导出数据
mysqldump -A -B -X --set-gtid-purged=OFF | gzip > /bak/ocean_$(date +%F).sql.gz
注:"--set-gtid-purged=OFF",数据导入新slave后,产生新GTID序列
Slave恢复数据
gzip -d /bak/ocean_$(date + %F).sql.gz
mysql < /bak/ocean_20190401.sql
Slave配置参数
CHANGE MASTER TO MASTER_HOST='10.11.12.1',MASTER_PORT=3306,MASTER_USER='rep',MASTER_PASSWORD='root1234',MASTER_AUTO_POSITION=1;
注:不能使用非GTID复制模式参数,"MASTER_LOG_FILE","MASTER_LOG_POS"
Slave开启复制&检查状态
start slave;
show slave status\G;
查看复制关键参数
mysql -e "show slave status\G;" | egrep "IO_Running | SQL_Running; | _Behind_Master"
至此GTID复制配置完成
GTID复制故障处理
事务冲突影响数据复制,《MySQL数据库复制技术 Part 4 : 双主复制》中介绍过"set global sql_slave_skip_counter=1"解决复制过程中的错误。
GTID必须连续,同一个服务器产生的GTID是不会出现空挡,因此不能简单的skip,需要通过注入空事务的方式替换掉实际操作的事务,命令如下
--- 停止复制
stop slave;
--- "Retrieved_Gtid_Set"最大事务ID
set gtid_next='5c99ae22-0a0n-31d8-az2l-0000c231iki6w:8';
--- 注入空事务
begin;commit;
--- 自动比较GTID,继续数据复制
set gtid_next='AUTOMATIC';
--- 启动复制
start slave;
--- 检查复制状态
show slave status\G;
附录
GTID复制master&slave配置文件
GTID复制my.cnf参数对比 | |
Master | Slave |
[client] user = root password = root1234 [mysqld] server_id = 7 basedir = /app/mysql5.7 datadir = /app/mysql5.7/data log_bin = /app/mysql5.7/logs/ocean-bin log_slave_updates = 1 expire_logs_days = 7 binlog_format = ROW gtid_mode = on enforce_gtid_consistency = true [mysqld_safe] log-error = /app/mysql5.7/logs/ocean.err sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_STABLES | [client] user = root password = root1234 [mysqld] server_id = 8 basedir = /app/mysql5.7 datadir = /app/mysql5.7/data log_bin = /app/mysql5.7/logs/ocean-bin log_slave_updates = 1 expire_logs_days = 7 binlog_format = ROW gtid_mode = on enforce_gtid_consistency = true [mysqld_safe] log-error = /app/mysql5.7/logs/ocean.err sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_STABLES |
相关链接