MySQL 主从复制是实现高可用、读写分离和灾难恢复的核心机制,其本质是主库(Master)将数据变更异步同步到从库(Slave)。以下是深度解析:
线程 | 所在位置 | 职责 |
---|---|---|
Binlog Dump Thread | 主库 | 监听从库请求,推送二进制日志(binlog) |
I/O Thread | 从库 | 连接主库请求binlog,写入中继日志(relay log) |
SQL Thread | 从库 | 读取relay log,解析并重放SQL(实现数据同步) |
STATEMENT
(SQL语句)、ROW
(行数据变更)、MIXED
(混合模式)CHANGE MASTER TO
命令指定主库信息关键点:
- 主从同步是异步的(默认模式),主库不等待从库确认
- 从库通过
master_log_file
+master_log_pos
记录同步位置
配置步骤:
my.cnf
):[mysqld]
server_id = 1 # 唯一ID(主从不能重复)
log_bin = /var/lib/mysql/mysql-bin # 开启binlog
binlog_format = ROW # 推荐ROW格式(数据一致性更强)
CREATE USER 'repl'@'%' IDENTIFIED BY 'Slave@123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
my.cnf
):[mysqld]
server_id = 2 # 不同于主库
relay_log = /var/lib/mysql/relay-bin
read_only = ON # 从库设为只读(防止误写)
# 主库备份
mysqldump -uroot -p --master-data=2 --single-transaction -A > master_db.sql
# 从库导入
mysql -uroot -p < master_db.sql
CHANGE MASTER TO
MASTER_HOST = '192.168.1.100',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'Slave@123',
MASTER_LOG_FILE = 'mysql-bin.000001', -- 备份文件中的值
MASTER_LOG_POS = 154; -- 备份文件中的值
START SLAVE;
优势:自动跟踪事务位置,无需手动维护binlog位置
配置步骤:
my.cnf
新增):gtid_mode = ON
enforce_gtid_consistency = ON
CHANGE MASTER TO
MASTER_HOST = '192.168.1.100',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'Slave@123',
MASTER_AUTO_POSITION = 1; # 启用GTID自动定位
START SLAVE;
GTID 格式:
server_uuid:transaction_id
(如 3E11FA47-71CA-11E1-9E33-C80AA9429562:5
)
复制模式 | 原理 | 优点 | 缺点 |
---|---|---|---|
异步复制 | 主库提交事务后立即返回,不等待从库确认(默认模式) | 性能高 | 数据可能丢失(主库宕机时) |
半同步复制 | 主库提交事务后需等待至少一个从库确认收到binlog | 保证数据安全 | 性能下降(可调超时时间) |
组复制(MGR) | 基于Paxos协议实现多主同步(MySQL 5.7+) | 高可用+自动故障切换 | 配置复杂 |
开启半同步复制:
-- 主从库安装插件
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
-- 主库
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 1000; -- 超时时间(ms)
-- 从库
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
方法 | 操作说明 |
---|---|
并行复制 | 启用多线程回放(需MySQL 5.6+):slave_parallel_workers = 8 |
增强半同步 | MySQL 5.7+ Loss-Less Semi-Sync(避免ACK等待导致延迟) |
分库分表 | 减少单库压力 |
MTS按逻辑时钟 | 5.7+ 设置 slave_parallel_type = LOGICAL_CLOCK |
跳过大事务 | 紧急处理:SET GLOBAL sql_slave_skip_counter = 1 |
-- 查看从库状态
SHOW SLAVE STATUS\G
关注字段:
Slave_IO_Running
: YesSlave_SQL_Running
: YesSeconds_Behind_Master
: 0 # 延迟秒数Last_IO_Error
: 错误信息Retrieved_Gtid_Set
: 已接收GTIDExecuted_Gtid_Set
: 已执行GTID问题 | 解决方案 |
---|---|
主键冲突 | 检查是否有人误写入从库 → 设置 read_only=ON |
数据不一致 | 使用 pt-table-checksum 校验数据,pt-table-sync 修复 |
SQL线程停止 | 查看 Last_SQL_Error ,跳过错误或手动修复数据 |
主库binlog被清除 | 重建从库或使用备份恢复 |
binlog_format = ROW # 避免函数导致主从不一致
mysqldump --single-transaction --master-data=2 -A > backup.sql
ALTER EVENT monitor_replica_delay
ON SCHEDULE EVERY 60 SECOND
DO
IF (SELECT Seconds_Behind_Master FROM sys.replica_status > 300) THEN
CALL send_alert('主从延迟超过5分钟!');
END IF;
终极建议:
- 生产环境必用 GTID + 半同步复制
- 从库至少部署2个(一个半同步,一个异步用于备份)
- 使用 ProxySQL 自动管理故障转移和读写分离
MySQL主从同步延迟是生产环境常见问题,会导致数据不一致、业务逻辑错误等严重后果。以下是系统性解决方案,按紧急程度和实施难度分层处理:
-- 查看同步错误(从库执行)
STOP SLAVE;
SHOW SLAVE STATUS\G -- 查看Last_SQL_Error
-- 跳过1个事务(GTID模式需额外处理)
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
-- 将读组指向主库
UPDATE mysql_query_rules SET destination_hostgroup=10
WHERE active=1 AND match_pattern='^SELECT';
LOAD RULES TO RUNTIME;
-- 从库配置 my.cnf
slave_parallel_workers = 8 # 推荐CPU核数的50%-80%
slave_parallel_type = LOGICAL_CLOCK # MySQL 5.7+ 必选
slave_preserve_commit_order = ON # 保证事务顺序
原理:LOGICAL_CLOCK 基于事务依赖关系并行重放,提升吞吐量
场景 | 优化方案 |
---|---|
大事务 | 拆分事务(如10万行DELETE → 每次删1000行) |
无主键/索引表写入 | 强制所有表必须有主键(innodb_force_primary_key=ON ) |
批量插入 | 使用LOAD DATA 替代INSERT INTO ... VALUES(...),(...) |
# 从库配置
innodb_flush_log_at_trx_commit = 2 # 牺牲部分持久性提升IO性能
sync_binlog = 0 # 禁用binlog刷盘
relay_log_recovery = ON # 崩溃后安全恢复
-- 从库配置多个主库通道
CHANGE MASTER TO MASTER_HOST='master1' ... FOR CHANNEL 'ch1';
CHANGE MASTER TO MASTER_HOST='master2' ... FOR CHANNEL 'ch2';
START SLAVE FOR CHANNEL 'ch1';
START SLAVE FOR CHANNEL 'ch2';
适用场景:多个业务库汇总到一个分析库
# 监控延迟脚本(从库执行)
mysql -e "SHOW SLAVE STATUS\G" | grep "Seconds_Behind_Master"
seconds_behind_master
slave_sql_running_state
配置项 | 主库 | 从库 | 作用 |
---|---|---|---|
log_slave_updates |
OFF | ON | 级联复制必备 |
read_only |
OFF | ON | 防止从库误写 |
innodb_buffer_pool_size |
70%内存 | > 主库 | 加速重放 |
LOCK TABLES
显式锁表information_schema.INNODB_TRX
)延迟原因 | 根治方案 |
---|---|
SQL单线程重放慢 | MySQL 8.0 的 WRITESET并行复制(binlog_transaction_dependency_tracking=WRITESET ) |
大事务阻塞 | 业务改造 → 小批量提交 + 错峰执行 |
从库硬件性能差 | 升级为同配置主机或使用物理机+NVMe SSD |
跨地域同步 | 使用 MySQL Group Replication + 代理层自动路由 |
MySQL 8.0 WRITESET 黑科技:
通过事务修改的数据行哈希值判断并行度,即使无主键表也能高效并行(比LOGICAL_CLOCK提升50%+性能)
关键设计:
pt-table-checksum
通过上述分层解决方案,可彻底根治主从延迟问题。核心要点: