MySQL主从复制(Master-Slave Replication)是数据库高可用架构的基础组件,本质上是通过二进制日志(binlog)实现的数据同步机制。我在生产环境部署过数十套主从架构,发现很多新手DBA只停留在配置层面,却不理解背后的工作原理,遇到同步异常时往往束手无策。
主从复制的核心流程可以概括为"三个线程+两种日志":
关键理解:主从复制是异步过程,默认存在毫秒级延迟。对延迟敏感的业务需要考虑半同步复制方案
典型应用场景包括:
主从配置前需要确保以下基础条件满足:
网络连通性:
telnet 主库IP 3306时间同步:
bash复制# 安装ntpdate工具(CentOS)
yum install -y ntpdate
# 同步国家授时中心时间
ntpdate ntp.ntsc.ac.cn
# 配置定时任务(每天同步一次)
echo "0 3 * * * /usr/sbin/ntpdate ntp.ntsc.ac.cn > /dev/null 2>&1" >> /etc/crontab
MySQL版本兼容性:
主库的my.cnf配置需要重点关注以下参数:
ini复制[mysqld]
server-id = 1 # 必须全局唯一,建议用IP末段
log-bin = mysql-bin # 开启二进制日志
binlog_format = ROW # 推荐ROW格式,数据变更更安全
sync_binlog = 1 # 每次事务提交都刷盘,保证数据安全
expire_logs_days = 7 # 自动清理7天前的日志
binlog_row_image = FULL # 记录完整的行数据
gtid_mode = ON # 启用GTID全局事务标识
enforce_gtid_consistency = ON # 强制GTID一致性
生产环境建议:binlog-do-db和binlog-ignore-db二选一即可,避免同时使用导致规则冲突
从库配置需要特别注意这些参数:
ini复制[mysqld]
server-id = 2 # 不能与主库重复
relay-log = mysql-relay-bin # 中继日志路径
relay_log_recovery = ON # 崩溃后自动恢复中继日志
read_only = ON # 从库只读(不影响复制线程)
log_slave_updates = ON # 级联复制时需要开启
slave_parallel_workers = 4 # 并行复制线程数(建议CPU核心数50%)
创建复制账号时需要注意安全规范:
sql复制-- 创建带IP限制的复制账号(生产环境必须限制IP)
CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY 'Complex@Password123!';
-- 最小权限原则
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'192.168.1.%';
-- 密码复杂度要求(MySQL 8.0+)
ALTER USER 'repl'@'192.168.1.%' REQUIRE
PASSWORD HISTORY 5
PASSWORD REUSE INTERVAL 90 DAY
FAILED_LOGIN_ATTEMPTS 3;
GTID复制(全局事务标识)是MySQL 5.6引入的重大改进,与传统基于binlog位置的复制相比:
| 特性 | GTID复制 | 传统复制 |
|---|---|---|
| 故障切换 | 自动定位位置 | 需手动指定binlog位置 |
| 级联复制 | 支持完善 | 配置复杂 |
| 一致性 | 全局事务ID保证 | 依赖binlog位置准确性 |
| 兼容性 | MySQL 5.6+ | 所有版本支持 |
启用GTID后的配置命令:
sql复制CHANGE MASTER TO
MASTER_HOST='master_ip',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_AUTO_POSITION=1; -- 关键参数启用GTID
配置完成后必须验证数据一致性,推荐使用pt-table-checksum工具:
bash复制# 安装Percona工具包
yum install percona-toolkit
# 在主库执行校验(会自动在从库对比)
pt-table-checksum --replicate=test.checksums \
--create-replicate-table \
--empty-replicate-table \
--databases=test_db \
h=localhost,u=root,p=password
校验结果解读:
必须监控的关键指标及推荐阈值:
| 指标名称 | 监控命令 | 危险阈值 |
|---|---|---|
| 主从延迟(秒) | SHOW SLAVE STATUS中的Seconds_Behind_Master |
> 30 |
| IO线程状态 | Slave_IO_Running |
!= Yes |
| SQL线程状态 | Slave_SQL_Running |
!= Yes |
| 中继日志空间 | SHOW SLAVE STATUS中的Relay_Log_Space |
> 10GB |
| 复制错误数 | Last_IO_Errno/Last_SQL_Errno |
!= 0 |
推荐使用Prometheus+Grafana搭建可视化监控:
yaml复制# Prometheus配置示例
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['master:9104', 'slave:9104']
现象:Slave_SQL_Running=No,Last_SQL_Error显示错误
解决方案:
sql复制-- 临时跳过错误(慎用)
STOP SLAVE;
SET GLOBAL sql_slave_skip_counter=1;
START SLAVE;
-- 或针对GTID复制跳过特定事务
STOP SLAVE;
SET GTID_NEXT='aaa-bbb-ccc-ddd:N';
BEGIN; COMMIT;
SET GTID_NEXT='AUTOMATIC';
START SLAVE;
修复步骤:
bash复制pt-table-sync --replicate=test.checksums \
--sync-to-master h=slave_ip,u=root,p=password \
--databases=test_db --print
并行复制优化:
ini复制slave_parallel_workers=8 # 根据CPU核心数调整
slave_parallel_type=LOGICAL_CLOCK
网络压缩(跨机房场景):
sql复制CHANGE MASTER TO MASTER_COMPRESSION_ALGORITHMS='zstd';
批量事务处理:
ini复制slave_preserve_commit_order=1
从库缓存优化:
ini复制innodb_buffer_pool_size=12G # 物理内存的70-80%
sync_relay_log=1000 # 每1000次同步刷盘
大规模场景下的典型三级架构:
code复制主库(Master) → 级联从库(Relay Slave) → 多个从库(Slaves)
配置要点:
log_slave_updates平衡安全与性能的方案:
ini复制# 主库配置
plugin-load="rpl_semi_sync_master=semisync_master.so"
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=10000 # 10秒后降级为异步
# 从库配置
plugin-load="rpl_semi_sync_slave=semisync_slave.so"
rpl_semi_sync_slave_enabled=1
用于数据误删恢复:
sql复制CHANGE MASTER TO MASTER_DELAY=3600; # 延迟1小时执行
监控命令:
sql复制SHOW SLAVE STATUS\G
/* 关注SQL_Delay字段 */
我在实际运维中发现,主从复制90%的问题都源于配置不规范或权限设置不当。建议每次修改配置后使用mysqladmin flush-hosts命令清除连接缓存,避免旧的连接信息干扰新配置生效。对于重要业务数据库,最好配置双主从架构实现双向同步,但要注意避免循环复制问题。