文档主页
MySQL 8.4 参考手册
相关文档 下载此手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


19.5.1.35 复制和事务

在同一个事务中混合事务性语句和非事务性语句。  一般情况下,应避免在复制环境中更新事务性表和非事务性表的事务。还应避免使用访问事务性表(或临时表)和非事务性表并写入其中任何一个的语句。

服务器使用以下规则进行二进制日志记录

  • 如果事务中的初始语句是非事务性的,则立即将它们写入二进制日志。事务中的剩余语句将被缓存,并且不会写入二进制日志,直到事务提交。(如果事务回滚,只有在它们进行无法回滚的非事务性更改时,才会将缓存的语句写入二进制日志。否则,它们将被丢弃。)

  • 对于基于语句的日志记录,非事务性语句的日志记录受binlog_direct_non_transactional_updates系统变量的影响。当此变量为OFF(默认值)时,日志记录与上述描述相同。当此变量为ON时,在事务中的任何位置(不仅仅是初始非事务性语句)发生的非事务性语句都会立即进行日志记录。其他语句将保留在事务缓存中,并在事务提交时进行日志记录。 binlog_direct_non_transactional_updates对行格式或混合格式的二进制日志记录没有影响。

事务性、非事务性和混合语句。  为了应用这些规则,服务器会将一个语句视为非事务性,如果它只更改非事务性表,而将其视为事务性,如果它只更改事务性表。引用非事务性表和事务性表并更新任何所涉及表的语句被视为混合语句。混合语句,就像事务性语句一样,会被缓存并在事务提交时进行日志记录。

更新事务性表的混合语句,如果该语句还执行以下任一操作,则被视为不安全

  • 更新或读取临时表

  • 读取非事务性表,并且事务隔离级别低于 REPEATABLE_READ

在事务中更新事务性表之后执行的混合语句,如果它执行以下任一操作,则被视为不安全

有关更多信息,请参见第 19.2.1.3 节,“确定二进制日志记录中的安全和不安全语句”

注意

混合语句与混合二进制日志记录格式无关。

在事务混合更新事务表和非事务表的情况下,二进制日志中语句的顺序是正确的,即使在出现ROLLBACK时,所有必要的语句也会写入二进制日志。但是,当第二个连接在第一个连接事务完成之前更新非事务表时,语句可能会以乱序方式记录,因为第二个连接更新会在执行后立即写入,而与第一个连接执行的事务状态无关。

在源和副本上使用不同的存储引擎。 可以使用副本上的非事务表复制源上的事务表。例如,可以将 InnoDB 源表复制为 MyISAM 副本表。但是,如果您这样做,如果副本在 BEGIN ... COMMIT 块的中间停止,则会出现问题,因为副本将从 BEGIN 块的开头重新启动。

同样,将源上的 MyISAM 表中的事务复制到副本上的事务表(例如,使用 InnoDB 存储引擎的表)也是安全的。在这种情况下,在源上发出的 AUTOCOMMIT=1 语句将被复制,从而在副本上强制执行 AUTOCOMMIT 模式。

当副本的存储引擎类型是非事务性的时,应避免在源上执行混合更新事务表和非事务表的交易,因为这会导致源事务表和副本非事务表之间的数据不一致。也就是说,这种交易会导致特定于源存储引擎的行为,可能导致复制不同步。MySQL 不会发出有关此问题的警告,因此在将事务表从源复制到副本上的非事务表时应格外小心。

在事务中更改二进制日志格式。 只要事务正在进行,binlog_formatbinlog_checksum 系统变量都是只读的。

每个事务(包括 autocommit 事务)都记录在二进制日志中,就好像它以 BEGIN 语句开头,以 COMMITROLLBACK 语句结尾。即使对于影响使用非事务存储引擎(如 MyISAM)的表的语句,也是如此。

注意

有关专门适用于 XA 事务的限制,请参见第 15.3.8.3 节,“XA 事务限制”