使用 BinLog 进行数据库复制

使用 BinLog 进行数据库复制

我在用mysql-binlog 连接器监听任何 binlog 事件,然后在从属数据库上执行复制。我的问题是,binlog 在执行之后和提交之前立即注册事件,因此如果有任何回滚,事件仍会从 binlog 条目中获取并复制到从属数据库上。有没有办法解决这个问题?

答案1

来自binlog手册我的印象是该机制的工作方式略有不同:

在未提交的事务中,所有更改事务表(如 InnoDB 表)的更新(UPDATE、DELETE 或 INSERT)都是缓存直到提交语句被服务器接收。此时,mysqld 在执行 COMMIT 之前将整个事务写入二进制日志。

换句话说,直到实际发出 COMMIT 之前,事务中的任何内容都不会写入二进制日志,或者,事务写入二进制日志这一事实意味着没有发出 ROLLBACK!

一旦发出了 COMMIT:那么首先完整的事务被写入二进制日志,然后执行 COMMIT,最后,只有在 COMMIT 成功完成后,COMMIT 才会记录在二进制日志中。

然后,本手册继续介绍几个极端情况及其缓解措施(sync_binlog=1&--innodb_support_xa)可能会减轻你的担忧:

从 MySQL 5.7.7 开始,默认情况下二进制日志在每次写入时同步到磁盘 ( sync_binlog=1)。在 MySQL 5.7.7 之前,情况并非如此 ( sync_binlog=0)。因此,在 MySQL 5.7.7 之前,如果操作系统或计算机(不仅是 MySQL 服务器)崩溃,则二进制日志的最后几条语句可能会丢失。为防止这种情况,请使用系统sync_binlog变量在每 N 个提交组之后将二进制日志同步到磁盘。请参见第 5.1.4 节“服务器系统变量”。sync_binlog 最安全的值是 1,但这也是最慢的。即使将 sync_binlog 设置为 1,在发生崩溃的情况下,表内容和二进制日志内容之间仍然有可能不一致。

例如,如果您使用的是 InnoDB 表,并且 MySQL 服务器处理 COMMIT 语句,它会按顺序将许多准备好的事务写入二进制日志,同步二进制日志,然后将此事务提交到 InnoDB。如果服务器在这两个操作之间崩溃,则事务会在重新启动时由 InnoDB 回滚,但仍存在于二进制日志中。如果设置--innodb_support_xa1

相关内容