首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MySQL 复制最佳实践:如何保持副本稳定运行?

MySQL 复制最佳实践:如何保持副本稳定运行?

作者头像
爱可生开源社区
发布2026-02-28 16:39:34
发布2026-02-28 16:39:34
490
举报

作者: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 的复制是人们一开始不太愿意启用,但一旦启用就再也不想关闭的功能之一。

为什么需要 GTID?

  • 故障转移变得合理
  • 新创建副本不再是件令人头疼的事
  • 缺失的事务很容易被发现。

您的 my.cnf 文件必须包含以下内容:

代码语言:javascript
复制
gtid_mode=ON
enforce_gtid_consistency=ON
log_replica_updates=ON

启用 GTID 后,切勿与老式复制方式混用,否则只会造成混乱。

二、使用基于行的复制 (RBR)

基于语句的复制是一种没人想要的怀旧方式。它会在以下情况下失效:

  • NOW()、UUID() 和类似函数
  • 浮点差
  • 排序不匹配
  • 触发器的行为方式不同

省去痛苦,直接使用:

代码语言:javascript
复制
binlog_format=ROW

RBR 的语法略显冗长,但可预测性却高出 100 倍。当出现问题时,绝不是因为你选择了 ROW 模式。

三、每个表都需要主键

如果你从本文中只能记住一点,那就记住这一点:

没有主键的复制是个糟糕的选择。

基于行的复制需要一种方法来查找发生更改的行。如果没有主键(或至少有一个唯一索引),服务器就必须使用每一列进行查找。这速度慢、容易出错,有时甚至根本无法实现。

常见症状:

  • 复制延迟缓慢增加
  • 副本在更新时执行全表扫描
  • 行应用失败
  • 错误类型 Error 1032: Can't find record in table

省去你数小时的调试时间,只需确保每个表都有一个主键即可。

四、保持所有地方的模式一致

复制机制的前提是所有用户都使用相同的数据库模式。即使数据库模式不匹配,MySQL 也能继续运行——然后悄悄地逐渐失去同步。

以下是一些保持模式一致的实用方法:

方法 A — mysqldump(最常用)

仅导出模式:

代码语言:javascript
复制
mysqldump --no-data mydb > schema.sql

那么,从两个服务器上:

代码语言:javascript
复制
diff source-schema.sql replica-schema.sql

方法 B — 信息模式元数据

这种方法非常适合自动化:

代码语言:javascript
复制
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 以匹配要检查其架构元数据的数据库。

方法 C — pt-table-checksum(仅数据)

它不比较模式,而是检测数据漂移。您应该考虑按计划运行它,例如:

  • 高变更率的 OLTP 数据库每周甚至每天都会运行
  • 庞大的多 TB 数据库每季度运行一次
  • 某些敏感系统会避免在高峰时段运行
代码语言:javascript
复制
pt-table-checksum --replicate=percona.checksums

您可以通过以下方式解决漂移问题:

代码语言:javascript
复制
pt-table-sync --execute --replicate=percona.checksums

架构检查 + 数据检查 = 安全复制。

五、加强二进制日志设置

二进制日志是复制的基石,请妥善处理。

代码语言:javascript
复制
sync_binlog=1
binlog_row_image=FULL
binlog_expire_logs_seconds=604800  # 7 days

sync_binlog=1 是最重要的 —— 如果没有它,崩溃可能会损坏 binlog 或 GTID 位置,这将导致非常糟糕的后果。

六、使用 super_read_only 保护您的副本

请在 my.cnf 文件中设置:永远不要允许意外写入副本:

代码语言:javascript
复制
read_only=ON
super_read_only=ON

super_read_only 堵住了即使是 SUPER 用户之前也可以用来写入副本的漏洞。

七、使用专用复制用户

授予最小权限:

代码语言:javascript
复制
CREATE USER 'repl'@'%' IDENTIFIED BY 'strong_password';
GRANT REPLICATION REPLICA ON *.* TO 'repl'@'%';

这个用户应该只做一件事:复制。不要重复使用应用用户 —— 否则只会自找麻烦。

八、复制延迟(密切关注)

Seconds_Behind_Source 这个数据比你想象的更不可靠。快速浏览一下还可以,但不要完全依赖它。

更好的选择:

  • Performance Schema:按工作节点复制应用状态
  • Percona 监测与管理(PMM)
  • 自定义心跳表:pt-heartbeat

延迟是导致服务中断的主要原因之一 —— 务必持续监控。延迟通常是出现问题的第一个迹象 —— 尽早发现并解决。

九、使用并行复制(但不要过度使用)

如果您的主进程有多个写入器或多个并发事务,请在 my.cnf 文件中启用并行工作进程:

代码语言:javascript
复制
replica_parallel_type=LOGICAL_CLOCK
replica_parallel_workers=4

对于大多数系统来说,4-8 个工作线程是最佳数量。工作线程越多,速度越快;超过一定数量后,只会增加内存占用,而没有实际收益。

但如果它能起到作用,那真的很有帮助——比如减少 80-90% 的延迟。

十、在局域网之外的任何位置使用 SSL

复制流量不应该暴露在外。

代码语言:javascript
复制
source_ssl=1
source_ssl_ca=/path/ca.pem

早期版本使用 master_ssl_* 变量,但思路是一样的:当连接离开您的受信任网络时对其进行加密。

最后想说的话

MySQL 复制可以非常稳定可靠,但前提是您必须遵循一些经验丰富的 DBA 熟记于心的规则:

  • 使用 GTID
  • 使用 RBR
  • 始终要有主键
  • 保持模式一致
  • 检查数据漂移
  • 强化 binlog 设置
  • 防止副本被意外写入
  • 正确监控延迟
  • 在适当的时候使用并行工作线程
  • 对通过不受信任的网络建立的连接进行加密

遵循这些步骤,你的副本数据库就能保持健康、稳定,并且(基本)隐形——这正是你想要的效果 。∎

本文关键字:#MySQL #GTID #PMM #翻译

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-02-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱可生开源社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、务必使用 GTID
  • 二、使用基于行的复制 (RBR)
  • 三、每个表都需要主键
  • 四、保持所有地方的模式一致
    • 方法 A — mysqldump(最常用)
    • 方法 B — 信息模式元数据
    • 方法 C — pt-table-checksum(仅数据)
  • 五、加强二进制日志设置
  • 六、使用 super_read_only 保护您的副本
  • 七、使用专用复制用户
  • 八、复制延迟(密切关注)
  • 九、使用并行复制(但不要过度使用)
  • 十、在局域网之外的任何位置使用 SSL
  • 最后想说的话
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档