
作者:Wayne Leutwyler,Percona 技术客户经理
原文:https://percona.community/blog/2025/12/03/mysql-replication-best-practices-how-to-keep-your-replicas-sane-and-your-nights-quiet/,December 3, 2025
爱可生开源社区翻译,本文约 1600 字,预计阅读需要 5 分钟。

MySQL 复制功能已经存在很久了,然而……人们仍然会以各种方式配置它,导致它在最糟糕的时刻崩溃。即使到了 2025 年,微小的模式差异、缺失的主键或一个被遗忘的配置都可能让你付出代价。我见过一些副本之间的同步偏差如此之大,简直就像存在于另一个平行宇宙中一样。
本文涵盖了实用的最佳实践 —— 一线 DBA 每天都在使用的技巧,以确保复制过程稳定、可预测且高效。 在数据库领域,“高效”是一种赞美。
基于 GTID 的复制是人们一开始不太愿意启用,但一旦启用就再也不想关闭的功能之一。
为什么需要 GTID?
您的 my.cnf 文件必须包含以下内容:
gtid_mode=ON
enforce_gtid_consistency=ON
log_replica_updates=ON
启用 GTID 后,切勿与老式复制方式混用,否则只会造成混乱。
基于语句的复制是一种没人想要的怀旧方式。它会在以下情况下失效:
省去痛苦,直接使用:
binlog_format=ROW
RBR 的语法略显冗长,但可预测性却高出 100 倍。当出现问题时,绝不是因为你选择了 ROW 模式。
如果你从本文中只能记住一点,那就记住这一点:
没有主键的复制是个糟糕的选择。
基于行的复制需要一种方法来查找发生更改的行。如果没有主键(或至少有一个唯一索引),服务器就必须使用每一列进行查找。这速度慢、容易出错,有时甚至根本无法实现。
常见症状:
Error 1032: Can't find record in table省去你数小时的调试时间,只需确保每个表都有一个主键即可。
复制机制的前提是所有用户都使用相同的数据库模式。即使数据库模式不匹配,MySQL 也能继续运行——然后悄悄地逐渐失去同步。
以下是一些保持模式一致的实用方法:
仅导出模式:
mysqldump --no-data mydb > schema.sql
那么,从两个服务器上:
diff source-schema.sql replica-schema.sql
这种方法非常适合自动化:
SELECT table_name, column_name, column_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_schema = 'mydb'
ORDER BY table_name, ordinal_position;
在每台服务器上执行此查询并比较结果。更新 mydb 以匹配要检查其架构元数据的数据库。
它不比较模式,而是检测数据漂移。您应该考虑按计划运行它,例如:
pt-table-checksum --replicate=percona.checksums
您可以通过以下方式解决漂移问题:
pt-table-sync --execute --replicate=percona.checksums
架构检查 + 数据检查 = 安全复制。
二进制日志是复制的基石,请妥善处理。
sync_binlog=1
binlog_row_image=FULL
binlog_expire_logs_seconds=604800 # 7 days
sync_binlog=1 是最重要的 —— 如果没有它,崩溃可能会损坏 binlog 或 GTID 位置,这将导致非常糟糕的后果。
请在 my.cnf 文件中设置:永远不要允许意外写入副本:
read_only=ON
super_read_only=ON
super_read_only 堵住了即使是 SUPER 用户之前也可以用来写入副本的漏洞。
授予最小权限:
CREATE USER 'repl'@'%' IDENTIFIED BY 'strong_password';
GRANT REPLICATION REPLICA ON *.* TO 'repl'@'%';
这个用户应该只做一件事:复制。不要重复使用应用用户 —— 否则只会自找麻烦。
Seconds_Behind_Source 这个数据比你想象的更不可靠。快速浏览一下还可以,但不要完全依赖它。
更好的选择:
延迟是导致服务中断的主要原因之一 —— 务必持续监控。延迟通常是出现问题的第一个迹象 —— 尽早发现并解决。
如果您的主进程有多个写入器或多个并发事务,请在 my.cnf 文件中启用并行工作进程:
replica_parallel_type=LOGICAL_CLOCK
replica_parallel_workers=4
对于大多数系统来说,4-8 个工作线程是最佳数量。工作线程越多,速度越快;超过一定数量后,只会增加内存占用,而没有实际收益。
但如果它能起到作用,那真的很有帮助——比如减少 80-90% 的延迟。
复制流量不应该暴露在外。
source_ssl=1
source_ssl_ca=/path/ca.pem
早期版本使用 master_ssl_* 变量,但思路是一样的:当连接离开您的受信任网络时对其进行加密。
MySQL 复制可以非常稳定可靠,但前提是您必须遵循一些经验丰富的 DBA 熟记于心的规则:
遵循这些步骤,你的副本数据库就能保持健康、稳定,并且(基本)隐形——这正是你想要的效果 。∎
本文关键字:#MySQL #GTID #PMM #翻译