MySQL 复制:“主键的重复条目”

HTF*_*HTF 12 mysql replication mysqldump

你能帮我理解为什么我在完全重新同步后在从服务器上收到“主键的重复条目”。

基本上'mysqldump'几乎整晚都在运行,然后恢复过程花了几个小时,所以当我启动slave时,它比master慢了~63874秒。

从服务器是只读的(read_only)并且在重新同步过程中没有任何写入,所以我不明白为什么会有重复的密钥。

二进制日志格式在 master 上设置为 MIXED。

用于备份数据库的命令:

mysqldump --opt --single-transaction -Q --master-data=2 db | bzip2 -cz > db.sql.bz2
Run Code Online (Sandbox Code Playgroud)

从站仅从主站(db -> db_backup)复制一个数据库,并使用以下选项:

replicate-wild-do-table = db_backup.%
replicate-rewrite-db = db->db_backup
Run Code Online (Sandbox Code Playgroud)

Rol*_*DBA 14

方面#1:复制

我不认为

replicate-wild-do-table = db_backup.%
replicate-rewrite-db = db->db_backup
Run Code Online (Sandbox Code Playgroud)

永远在一起。

其他人也想知道这个问题

问题源于处理复制规则的顺序。根据关于复制规则MySQL 文档

如果指定了任何 --replicate-rewrite-db 选项,则会在测试 --replicate-* 过滤规则之前应用它们。

甚至replicate-rewrite-db上MySQL文档也说:

数据库名称转换是在测试 --replicate-* 规则之前完成的。

replicate-wild-do-table重写后执行。如果这种排序以某种方式将 INSERT 强加到已经有数据的表中,那就不足为奇了。

您可能会问数据是如何到达那里的?

方面#2:mysqldump

这样做mysqldump --single-transaction似乎是时间点转储数据的最佳方式。不幸的是,mysqldump --single-transaction有一个阿喀琉斯之踵:ALTER TABLE。如果一个表受制于任何ALTER TABLE命令,例如 a DROP TABLEand CREATE TABLE,这可能会破坏 mysqldump 试图在其中进行转储的事务的完整性。截断一个表(在 MySQL Universe 中是 DDL)并删除和添加索引可以也一样具有破坏性。

您可以从 MySQL 性能博客的最佳 MySQLDump Secret 中找到更多信息。我实际上在过去的一个问题中解决了这一点,该问题描述了 12 个可以破坏 mysqldump 事务完整性的命令:MySQL 备份 InnoDB

警告

结语

由于重写规则或 mysqldump 的隔离被覆盖,这两个方面中的一个或两个可能导致在 mysqldump 期间滑入不应该存在的行。

建议

自 mysqldump 开始以来,我将对所有中继日志进行 mysqlbinlog 转储,以查看 Slave 将处理的所有 INSERT,并查看 Slave 上是否已存在这些行。如果他们这样做,你可能会做两件事:

1 : 跳过所有重复键错误

只需将此添加到 Slave 上的 my.cnf

[mysqld]
slave-skip-errors=1062
skip-slave-start
Run Code Online (Sandbox Code Playgroud)

并重新启动mysql。然后,运行START SLAVE;

所有重复键错误都将被绕过。当Seconds_Behind_Master达到 0 时,删除这些行并重新启动 mysql。

2:下载percona工具

你需要的工具是

使用这些来找出 Slave 中的差异,然后纠正它们