【问题标题】:MySQL replication not running updates in binlogMySQL 复制未在 binlog 中运行更新
【发布时间】:2026-01-29 21:05:03
【问题描述】:

我有一些运行版本 5.1.63 的 mysql 服务器,在本周早些时候对从属服务器运行一些查询时,我注意到从属服务器上的一些数据应该使用主服务器上的更新语句删除。

我最初的想法是:

  • 团队中有人正在更新从站,我后来反驳了这一点
  • 正在更新的列已更改

所以,我通过运行 mysql 显示状态“表”查询进行了调查。这是针对每台服务器上的测试数据库运行的,以查看数据长度是多少,在很多情况下,它向我显示服务器之间的数据长度不同,但通过眼球查看数据,我可以看到数据是一样的,所以我不能用这个方法来查看是否有任何差异,因为它似乎容易出错。

接下来,我为每个表运行了一个简单的(跨所有数据库)行数,以确认行数相同 - 确实如此。

然后我开始查看 bin 日志以进行复制。我可以在日志中清楚地看到应该运行的更新语句,但更新从未运行。

我需要知道的是:

  1. 复制是否中断?我猜是
  2. 如果我创建新的从服务器,我会遇到同样的问题吗?
  3. 如何确定我的服务器上问题的严重程度?

感谢任何帮助。

【问题讨论】:

  • 您是否在从站上运行 SHOW SLAVE STATUS\G 以验证从站是否正在运行?可能是在从站上运行语句时出错,有人手动跳过了它。
  • 您使用的是基于行还是基于语句的复制?主从运行相同版本的 MySQL?
  • 嗨,Kadaan,我们每天运行命令以确保一切同步。不过感谢您的指点。

标签: mysql sql-update replication


【解决方案1】:

如果您使用的是基于语句的复制,那么由于构造错误的 INSERT 语句,很容易在 master 和 slave 上得到不同的结果。

在没有 ORDER BY 的情况下插入 SELECT,或者 ORDER BY 可能留下不确定结果的地方会导致从属节点与主节点分道扬镳。

来自 MySQL 网站http://dev.mysql.com/doc/refman/5.1/en/insert-select.html

SELECT 语句返回行的顺序,没有 ORDER BY 子句未确定。这意味着,当使用 复制,不能保证这样的 SELECT 返回行 master和slave上的顺序相同;这可能导致 他们之间的矛盾。为了防止这种情况发生,您 应始终编写 INSERT ... SELECT 语句 复制为 INSERT ... SELECT ... ORDER BY 列。的选择 列没有关系,只要返回的顺序相同 rows 在主服务器和从服务器上都强制执行。另见部分 16.4.1.15,“复制和限制”。

如果发生这种情况,则说明您的副本已经分道扬镳,唯一安全的恢复方式是从主数据库的最近备份中重建它们。最糟糕的部分是错误可能永远不会导致复制失败,但结果却不一致。通常,当 UPDATE 或 DELETE 语句影响的行数与 master 上不同的行数时,复制失败,这令人困惑,因为实际上导致错误的不是 UPDATE,我知道解决问题的唯一方法是检查每个 INSERT 查询代码库!

【讨论】:

  • 这几乎就是我当时最终做的事情。只是为了确保。
【解决方案2】:

有一个名为 pt-table-checksum 的工具来验证复制

【讨论】:

    【解决方案3】:

    状态详细信息来自 information_schema,它从数据库统计数据中为 Mysql 实例整理数据,并且在每次执行时都不会保持不变。它可以被认为只是以字节为单位的数据大小的粗略估计,而不是索引和数据长度的精确值。它可以用于估计,但不能用于交叉检查。对于复制,您可以检查从属 io 和 sql 与主服务器是否正在运行。和 relay-info 你可能会看到来自 master 和 slave 的相应日志详细信息。

    当然,(1)的做法是count(*) of tables EOD保证master和slave上表中的数据是否一致。但要准确,(2)采用随机值字段并与主从进行交叉检查。此外,如果您对它不满意,(3)您可以将它们放入 outfile 并获取差异或校验和。我更喜欢(1)和(2)。如果(1)不可能(2)仍然说服我。 ;)

    【讨论】: