MySQL主从复制是数据库领域最经典的高可用解决方案之一,它通过将数据从主库同步到一个或多个从库来实现数据冗余和负载均衡。我在金融行业的数据库运维实践中,这套架构帮助我们实现了99.99%的系统可用性。
主从复制的核心价值体现在三个维度:
二进制日志(Binlog)是MySQL复制的基石,它记录所有修改数据的SQL语句(Statement模式)或行变更数据(Row模式)。在电商大促期间,我们曾通过分析Binlog内容精准定位了性能瓶颈。
Binlog的三种格式对比:
| 格式类型 | 记录内容 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| STATEMENT | SQL语句 | 日志量小 | 函数结果可能不一致 | 简单查询 |
| ROW | 行数据变更 | 精确可靠 | 日志量大 | 事务密集型 |
| MIXED | 智能混合 | 平衡性好 | 需要监控 | 通用场景 |
生产环境建议使用ROW模式,特别是在涉及金额计算的金融系统中,可以绝对保证数据一致性。
主从复制通过三个核心线程协同工作:
我们在监控中发现,SQL线程重放效率往往是复制延迟的主要瓶颈。通过设置slave_parallel_workers=8,某系统的复制延迟从15分钟降到了30秒内。
ini复制[mysqld]
server-id = 1 # 必须唯一
log_bin = /var/lib/mysql/mysql-bin
binlog_format = ROW
binlog_row_image = FULL # 8.0+默认值
sync_binlog = 1 # 每次提交同步磁盘
expire_logs_days = 7 # 日志保留周期
创建复制账号时务必限制访问IP:
sql复制CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY 'ComplexPwd123!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
bash复制mysqldump --master-data=2 --single-transaction -uroot -p dbname > backup.sql
bash复制mysql -uroot -p dbname < backup.sql
bash复制head -n 50 backup.sql | grep "CHANGE MASTER"
sql复制CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_USER='repl',
MASTER_PASSWORD='ComplexPwd123!',
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=154;
START SLAVE;
主库安装插件:
sql复制INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled=1;
SET GLOBAL rpl_semi_sync_master_timeout=10000; # 10秒超时
从库配置:
sql复制INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled=1;
半同步复制会降低约15-20%的写入性能,需要根据业务容忍度调整超时时间。我们在支付系统采用动态切换策略:日间用异步模式,夜间对账时切换为半同步。
MySQL 5.7+支持从多个主库复制数据:
sql复制CHANGE MASTER TO
MASTER_HOST='master1'
FOR CHANNEL 'channel1';
CHANGE MASTER TO
MASTER_HOST='master2'
FOR CHANNEL 'channel2';
START SLAVE FOR CHANNEL 'channel1';
START SLAVE FOR CHANNEL 'channel2';
常见延迟原因及解决方案:
网络带宽不足
从库配置过低
ini复制slave_parallel_workers=8
slave_parallel_type=LOGICAL_CLOCK
innodb_buffer_pool_size=12G # 物理内存的70%
大事务阻塞
sql复制SET SESSION max_allowed_packet=256M;
SET GLOBAL slave_transaction_retries=10;
关键监控项SQL:
sql复制SHOW SLAVE STATUS\G
SELECT
UNIX_TIMESTAMP() - UNIX_TIMESTAMP(ts) AS delay_seconds
FROM heartbeat;
SELECT
table_schema,
SUM(data_length+index_length)/1024/1024 AS total_mb
FROM information_schema.tables
GROUP BY table_schema;
推荐部署Prometheus+Granfa监控看板,重点监控:
错误1062:主键冲突
sql复制STOP SLAVE;
SET GLOBAL sql_slave_skip_counter=1;
START SLAVE;
错误1236:Binlog丢失
sql复制-- 主库执行
FLUSH LOGS;
-- 从库执行
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.00000X', MASTER_LOG_POS=Y;
使用pt-table-checksum工具:
bash复制pt-table-checksum --replicate=test.checksums h=master,u=root,p=password
pt-table-sync --replicate=test.checksums h=master,u=root,p=password --print
校验过程会产生额外负载,建议在业务低峰期执行。我们在每月维护窗口进行全量校验,每周对核心表做抽样检查。
随着业务增长,可以考虑以下升级路径:
在最近的基础架构升级中,我们采用了两地三中心部署:
这种架构既保证了核心业务的RPO≈0,又防范了逻辑错误导致的数据污染风险。