1. GTID主从复制基础认知
第一次接触GTID(Global Transaction Identifier)这个概念时,我正被传统主从复制中position号维护的问题困扰。GTID的出现彻底改变了MySQL复制的管理模式——它为每个事务分配全球唯一标识符,格式为source_id:transaction_id。这种机制下,从库不再需要记录复杂的binlog文件名和position偏移量,只需记住最后一个执行的GTID即可。
在GTID模式下,主库提交的每个事务都会获得一个类似3E11FA47-71CA-11E1-9E33-C80AA9429562:23的标识。前段是服务器的UUID,后段是单调递增的事务序列号。这种设计带来了几个革命性改进:
- 复制拓扑变更时无需手动定位binlog位置
- 故障切换后能自动识别未同步的事务
- 级联复制场景下可以追溯事务原始来源
重要提示:启用GTID需要MySQL 5.6及以上版本,且一旦启用就无法降级回传统模式。生产环境升级前务必做好完整备份。
2. 环境准备与配置要点
2.1 服务器基础配置
我习惯在两台CentOS 7.9虚拟机上做实验,配置4核CPU、8GB内存、100GB SSD存储。关键的系统参数调整包括:
bash复制# 关闭透明大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled
# 调整文件描述符限制
ulimit -n 65535
MySQL 5.7的安装建议使用官方YUM源,避免使用发行版自带的旧版本。安装后创建专用数据目录:
bash复制mkdir -p /data/mysql
chown -R mysql:mysql /data
2.2 my.cnf关键配置
主库配置示例(/etc/my.cnf):
ini复制[mysqld]
server-id = 1
log_bin = mysql-bin
binlog_format = ROW
binlog_row_image = FULL
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
从库配置差异点:
ini复制server-id = 2 # 必须不同
read_only = ON # 从库只读
super_read_only = ON # 防止特权账户写入
配置完成后需要重启MySQL服务。我遇到过因配置文件权限问题导致服务无法启动的情况,建议设置:
bash复制chmod 644 /etc/my.cnf
3. 主从建立全流程
3.1 主库用户授权
在主库执行:
sql复制CREATE USER 'repl'@'%' IDENTIFIED BY 'S3cureP@ss';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
安全建议:生产环境应限制从库IP范围,避免使用'%'通配符。密码复杂度需符合企业安全规范。
3.2 初始数据同步
传统做法是用mysqldump导出数据,但在大型数据库场景下效率较低。我推荐使用Percona的XtraBackup工具:
bash复制# 在主库执行热备份
innobackupex --user=root --password=xxxx --no-timestamp /backup/
# 准备备份文件
innobackupex --apply-log /backup/
# 传输到从库
rsync -avzP /backup/ slave1:/var/lib/mysql/
备份完成后注意保留GTID信息,查看备份目录中的xtrabackup_binlog_info文件。
3.3 启动复制线程
在从库执行关键命令:
sql复制CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='S3cureP@ss',
MASTER_AUTO_POSITION = 1;
START SLAVE;
验证复制状态:
sql复制SHOW SLAVE STATUS\G
重点关注:
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
- Retrieved_Gtid_Set
- Executed_Gtid_Set
4. 日常运维与故障处理
4.1 监控指标设计
我常用的监控脚本示例:
sql复制SELECT
UNIX_TIMESTAMP() - UNIX_TIMESTAMP(ts) AS lag_seconds,
thread_id,
processlist_command
FROM
performance_schema.threads
WHERE
processlist_command IS NOT NULL;
关键报警阈值:
- 复制延迟 > 300秒
- SQL线程错误代码非0
- IO线程连接中断
4.2 常见错误处理
错误1:GTID一致性冲突
code复制Last_SQL_Error: Could not execute Write_rows event on table test.t1;
Duplicate entry '1' for key 'PRIMARY', Error_code: 1062
解决方案:
sql复制STOP SLAVE;
SET GTID_NEXT='aaa-bbb-ccc:123';
BEGIN; COMMIT;
SET GTID_NEXT='AUTOMATIC';
START SLAVE;
错误2:主键冲突
临时跳过方法:
sql复制STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
注意:长期解决方案应该是修复数据一致性,跳过错误只是临时措施。
4.3 主从切换演练
计划内切换流程:
- 主库设置只读
sql复制SET GLOBAL read_only=ON; - 确认从库追上延迟
sql复制SHOW SLAVE STATUS\G - 从库停止复制线程
sql复制STOP SLAVE; RESET SLAVE ALL; - 新主库启用写入
sql复制SET GLOBAL read_only=OFF;
5. 性能优化实践
5.1 并行复制配置
MySQL 5.7引入的基于组提交的并行复制:
ini复制slave_parallel_workers = 8
slave_parallel_type = LOGICAL_CLOCK
监控并行复制效果:
sql复制SELECT * FROM performance_schema.replication_applier_status_by_worker;
5.2 网络优化
对于跨机房同步,建议:
- 使用专用网络通道
- 调整TCP参数:
ini复制net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 - 考虑使用压缩:
sql复制CHANGE MASTER TO MASTER_COMPRESSION_ALGORITHMS='zlib';
5.3 大事务处理
识别大事务:
sql复制SELECT * FROM performance_schema.events_statements_history_long
WHERE SQL_TEXT LIKE '%BEGIN%' ORDER BY TIMER_WAIT DESC LIMIT 10;
优化建议:
- 拆分单事务为多个小事务
- 避免在事务中执行DDL
- 设置事务超时:
ini复制innodb_rollback_on_timeout=1
6. 高可用架构设计
6.1 级联复制拓扑
典型的三层架构:
code复制Master -> Relay Slave -> Leaf Slave
配置要点:
- 中继从库需设置
log_slave_updates=ON - 监控每层级延迟
- 使用不同server-id
6.2 半同步复制
配置方法:
主库:
sql复制INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled=1;
从库:
sql复制INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled=1;
6.3 延迟从库配置
故意设置延迟的从库可用于数据恢复:
sql复制CHANGE MASTER TO MASTER_DELAY = 3600; # 延迟1小时
监控延迟:
sql复制SELECT
TIMESTAMPDIFF(SECOND, LAST_QUEUED_TRANS, NOW()) AS delay_seconds
FROM
performance_schema.replication_connection_status;
7. 版本升级注意事项
从MySQL 5.6升级到5.7的GTID变更点:
- 5.6需要手动设置
log_slave_updates - 5.7支持在线启用GTID:
sql复制SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN; SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON; SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE; SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE; SET @@GLOBAL.GTID_MODE = ON;
升级后必须验证:
sql复制SELECT @@GLOBAL.GTID_MODE, @@GLOBAL.ENFORCE_GTID_CONSISTENCY;
8. 备份恢复策略
8.1 GTID环境备份
使用mysqldump时需添加:
bash复制mysqldump --single-transaction --triggers --routines --set-gtid-purged=ON -uroot -p dbname > dump.sql
关键参数说明:
--set-gtid-purged=ON包含GTID信息--single-transaction保证一致性
8.2 时间点恢复
基于GTID的恢复步骤:
- 还原基础备份
- 定位需要停止的GTID:
sql复制SELECT * FROM mysql.gtid_executed WHERE interval_start <= 'aaa-bbb:100'; - 设置复制到指定位置:
sql复制START SLAVE UNTIL SQL_AFTER_GTIDS = 'aaa-bbb:100';
9. 安全加固措施
9.1 复制通道加密
配置SSL复制:
- 生成证书:
bash复制
openssl req -x509 -newkey rsa:2048 -keyout master-key.pem -out master-cert.pem -days 365 - 主库配置:
ini复制ssl-ca=/etc/mysql/ca.pem ssl-cert=/etc/mysql/server-cert.pem ssl-key=/etc/mysql/server-key.pem - 从库连接命令:
sql复制CHANGE MASTER TO MASTER_SSL=1, MASTER_SSL_CA='/etc/mysql/ca.pem';
9.2 权限最小化
建议权限矩阵:
| 操作类型 | 所需权限 |
|---|---|
| 复制连接 | REPLICATION SLAVE |
| 监控状态 | PROCESS, REPLICATION CLIENT |
| 故障处理 | SUPER |
10. 生产环境经验总结
经过多个生产集群的实践,我总结了这些GTID复制的黄金法则:
-
版本一致性:主从MySQL版本必须完全一致,小版本差异也可能导致复制中断
-
参数固化:关键参数应写入my.cnf而非动态设置,避免重启失效
-
监控全覆盖:除了常规复制状态,还需监控:
- 网络延迟
- 磁盘IOPS
- 内存使用率
-
定期演练:每季度执行一次完整的主从切换演练,包括:
- 计划内切换
- 故障模拟
- 数据一致性校验
-
文档更新:任何拓扑变更后立即更新架构图,标注:
- 各节点角色
- 同步方向
- 关键IP和端口
最后分享一个排查复制延迟的实用命令组合:
bash复制watch -n 1 "mysql -e 'SHOW SLAVE STATUS\G' | grep -E 'Seconds_Behind_Master|Running'"