MySQL复制中语句的“ 安全性 ”是指是否可以使用基于语句的格式正确复制该语句及其影响。如果该陈述是正确的,则我们将该陈述称为安全;否则,我们将其称为不安全。
通常,如果语句是确定性的,则它是安全的;否则,则是不安全的。但是,某些非确定性函数 不被认为是不安全的(请参阅 本节后面的非确定性函数被视为不安全的)。另外,使用浮点数学函数的结果(取决于硬件)的语句始终被认为是不安全的(请参见 第17.4.1.12节“复制和浮点值”)。
处理安全和不安全的声明。 根据该语句是否被认为安全,以及相对于二进制日志记录格式(即的当前值binlog_format),对语句进行不同的处理 。
使用基于行的日志记录时,在安全和不安全语句的处理上没有区别。
使用混合格式日志记录时,标记为不安全的语句将使用基于行的格式记录;使用基于语句的格式记录被视为安全的语句。
使用基于语句的日志记录时,标记为不安全的语句会产生警告。安全语句正常记录。
每个标记为不安全的语句都会生成警告。以前,如果在主服务器上执行了大量此类语句,则可能导致错误日志文件过大。为防止这种情况,MySQL提供了一种警告抑制机制(在MySQL 5.6.7中引入),其行为如下:只要ER_BINLOG_UNSAFE_STATEMENT 在任何50秒钟的时间内生成了50条最近的 警告超过50次,就会启用警告抑制。激活后,这将导致此类警告不会写入错误日志;相反,对于这种类型的每50条警告,都会有一个注释The last warning was repeated N times in last S seconds被写入错误日志。只要在50秒或更短的时间内发出了最近的50条警告,这种情况就会持续下去;一旦速率降低到此阈值以下,警告将再次正常记录。警告抑制不影响如何确定基于语句的日志记录的语句安全性,也不影响如何将警告发送到客户端。MySQL客户端仍然为每个这样的语句收到一个警告。
有关更多信息,请参见第17.1.2节“复制格式”。
声明不安全。 具有以下特征的语句被认为是不安全的:
包含系统功能的语句可能会在从属服务器上返回不同的值。 这些功能包括 FOUND_ROWS(), GET_LOCK(), IS_FREE_LOCK(), IS_USED_LOCK(), LOAD_FILE(), MASTER_POS_WAIT(), PASSWORD(), RAND(), RELEASE_LOCK(), ROW_COUNT(), SESSION_USER(), SLEEP(), SYSDATE(), SYSTEM_USER(), USER(), UUID(),和 UUID_SHORT()。
非确定性功能不被认为是不安全的。 虽然这些功能是不确定的,它们被视为安全的记录和复制的目的: CONNECTION_ID(), CURDATE(), CURRENT_DATE(), CURRENT_TIME(), CURRENT_TIMESTAMP(), CURTIME(),, , LAST_INSERT_ID(), LOCALTIME(), LOCALTIMESTAMP(), NOW(), UNIX_TIMESTAMP(), UTC_DATE(), UTC_TIME()和 UTC_TIMESTAMP()。
有关更多信息,请参见 第17.4.1.15节“复制和系统功能”。
对系统变量的引用。 使用基于语句的格式不能正确复制大多数系统变量。请参见 第17.4.1.35节“复制和变量”。有关例外,请参见第5.4.4.3节“混合二进制日志记录格式”。
UDF。 由于我们无法控制UDF的工作,因此我们必须假定它正在执行不安全的语句。
触发器或存储的程序将更新具有AUTO_INCREMENT列的表。 这是不安全的,因为在主服务器和从服务器上,行的更新顺序可能不同。
此外,INSERT到包含复合主键的表中的表AUTO_INCREMENT是不安全的,该主键包含的 列不是该复合键的第一列。
有关更多信息,请参见 第17.4.1.1节“复制和AUTO_INCREMENT”。
INSERT DELAYED语句。 该语句被认为是不安全的,因为行的插入可能会与同时执行的语句交错。
对具有多个主键或唯一键的表执行INSERT … ON DUPLICATE KEY UPDATE语句。 当对包含多个主键或唯一键的表执行该语句时,该语句被认为是不安全的,它对存储引擎检查键的顺序(不确定的)以及由行更新的行的选择敏感。 MySQL Server取决于。
INSERT … ON DUPLICATE KEY UPDATE从MySQL 5.6.6开始,针对具有多个唯一或主键的表 的 语句被标记为不安全。(缺陷#11765650,错误#58637)
使用LIMIT更新。 未指定行的检索顺序,因此被认为是不安全的。请参见 第17.4.1.17节“复制和限制”。
访问或引用日志表。 主服务器和从服务器之间的系统日志表的内容可能有所不同。
交易操作之后的非交易操作。 在事务内,允许任何非事务性读取或写入在任何事务性读取或写入之后执行是不安全的。
有关更多信息,请参见 第17.4.1.32节“复制和事务”。
访问或引用自记录表。 对自记录表的所有读取和写入均被视为不安全。在事务中,对自记录表进行读取或写入之后的任何语句也被认为是不安全的。
LOAD DATA语句。 LOAD DATA当binlog_format=mixed该语句以基于行的格式记录时,被视为不安全 。与其他不安全的语句不同,何时 不生成警告。 binlog_format=statement LOAD DATA
有关更多信息,请参见 第17.4.1节“复制功能和问题”。




