8

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

我最初的想法是:

  • 团队中的某个人正在更新奴隶,我后来反驳了
  • 正在更新的列已更改

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

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

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

我需要知道的是:

  1. 复制被破坏了吗?我假设它是
  2. 如果我创建新的从服务器,我会遇到同样的问题吗?
  3. 如何在我的服务器上找出问题的严重程度?

任何帮助表示赞赏。

4

3 回答 3

0

If you are using statement based replication then it is easily possible to end up with different results on master and slave due to badly constructed INSERT statements.

INSERT SELECT without ORDER BY, or where the ORDER BY can leave non deterministic results will cause the slaves to diverge from master.

From the MySQL site http://dev.mysql.com/doc/refman/5.1/en/insert-select.html

The order in which rows are returned by a SELECT statement with no ORDER BY clause is not determined. This means that, when using replication, there is no guarantee that such a SELECT returns rows in the same order on the master and the slave; this can lead to inconsistencies between them. To prevent this from occurring, you should always write INSERT ... SELECT statements that are to be replicated as INSERT ... SELECT ... ORDER BY column. The choice of column does not matter as long as the same order for returning the rows is enforced on both the master and the slave. See also Section 16.4.1.15, “Replication and LIMIT”.

If this has happened then your replicas have diverged and the only safe way to bring them back in line is to rebuild them from a recent backup of the master DB. The worst part of this is the error may never cause the replication to fail, yet the results are inconsistent. Normally replication fails when an UPDATE or DELETE statement affects a different number of rows than on master, this is confusing as it was not the UPDATE that actually caused the error and the only way I know to fix the issue is to inspect every INSERT query in the code base!

于 2014-09-05T11:17:06.230 回答
0

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

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

于 2012-08-28T09:14:16.150 回答
0

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

于 2014-04-23T12:54:07.910 回答