在同一笔交易中混合使用交易和非交易语句。 通常,应避免在复制环境中同时更新事务表和非事务表的事务。您还应该避免使用任何访问事务性(或临时)和非事务性表并对其进行写操作的语句。
MySQL服务器使用以下规则进行二进制日志记录:
如果事务中的初始语句是非事务性的,则它们将立即写入二进制日志。事务中的其余语句将被缓存,直到提交事务后才写入二进制日志。(如果回滚事务,则仅当高速缓存的语句进行了无法回滚的非事务更改时,才会将其写入二进制日志。否则,将丢弃它们。)
对于基于语句的日志记录,非事务性语句的日志记录受binlog_direct_non_transactional_updates 系统变量影响 。当此变量为 OFF默认值时,日志记录如前所述。当此变量ON为时,对于事务中任何地方发生的非事务性语句(不仅是初始的非事务性语句),都会立即进行日志记录。其他语句保留在事务缓存中,并在事务提交时记录。 binlog_direct_non_transactional_updates 对行格式或混合格式的二进制日志记录无效。
事务性,非事务性和混合语句。 要应用这些规则,如果服务器仅更改非事务表,则服务器将其视为非事务语句;如果仅更改事务表,则将其视为事务性语句。在MySQL 5.6中,引用非事务表和事务表并更新 任何涉及的表的语句被视为“ 混合 ”语句。(在以前的MySQL版本系列中,将更改了非事务表和事务表的语句视为混合语句。)事务提交时,将混合语句(如事务语句)缓存并记录下来。
如果该语句还执行以下任一操作,则更新该事务表的混合语句将被视为不安全:
更新或读取临时表
读取一个非事务表,并且事务隔离级别小于REPEATABLE_READ
如果在事务中更新事务表之后的混合语句执行以下任一操作,则被认为是不安全的:
更新任何表并从任何临时表中读取
更新非事务处理表并 binlog_direct_non_transactional_updates 关闭
有关更多信息,请参见 第17.1.2.3节“二进制日志记录中安全和不安全语句的确定”。
注意
混合语句与混合二进制日志记录格式无关。
在事务混合了对事务表和非事务表的更新的情况下,二进制日志中语句的顺序是正确的,并且即使在的情况下,所有需要的语句也会写入二进制日志 ROLLBACK。但是,当第二个连接在第一个连接事务完成之前更新了非事务表时,由于第二个连接更新是在执行之后立即写入的,所以无论第一个连接正在执行的事务状态如何,语句都可能被乱序记录。连接。
在主服务器和从服务器上使用不同的存储引擎。 可以使用从属服务器上的非事务表复制主服务器上的事务表。例如,您可以将InnoDB主表复制为 MyISAM从表。但是,如果这样做,则由于从站在BEGIN … COMMIT块的中间停止而导致问题,因为从站在BEGIN块的开头重新启动 。
在MySQL 5.6中,将事务从MyISAM主表复制到从表上的事务表(例如使用InnoDB存储引擎的表)也是安全的。在这种情况下,将AUTOCOMMIT=1 复制在主服务器上发出的 语句,从而AUTOCOMMIT在从服务器上强制执行 模式。
当从属服务器的存储引擎类型为非事务时,应避免在主服务器上混合事务和非事务表更新的事务,因为它们会导致主事务表和从属非事务表之间的数据不一致。也就是说,此类事务可能导致特定于主存储引擎的行为,并可能导致复制不同步的影响。MySQL当前未对此发出警告,因此在将事务表从主表复制到从属表上的非事务表时,应格外小心。
更改事务中的二进制日志记录格式。 binlog_format只要事务正在进行 ,系统变量就是只读的。(缺陷号47863)
每个事务(包括 autocommit事务)都被记录在二进制日志中,就像它以一条BEGIN 语句开始,以 a COMMIT或一条 ROLLBACK 语句结束一样。在MySQL 5.6中,甚至对于影响使用非事务性存储引擎(例如MyISAM)的表的语句也是如此。