16.2.1.3 确定二进制日志中的安全和不安全语句

MySQL 复制中语句的“安全性”是指是否可以使用基于语句的格式正确复制该语句及其影响。如果该声明是正确的,则我们将该声明称为“安全”。否则,我们将其称为不安全。

通常,如果语句是确定性的,则它是安全的;否则,则是不安全的。但是,某些不确定的函数不被认为是不安全的(请参阅非确定性功能不被认为是不安全的,本节后面的内容)。此外,使用浮点 math 函数的结果(取决于硬件)的语句始终被认为是不安全的(请参阅第 16.4.1.12 节,“复制和浮点值”)。

处理安全和不安全的语句. 根据语句是否被认为安全以及相对于二进制日志记录格式(即binlog_format的当前值)的不同,对语句的处理方式不同。

每个标记为不安全的语句都会生成警告。以前,如果在源上执行了大量此类语句,则可能导致错误日志文件过大。为了防止这种情况,MySQL 5.7 提供了一种警告抑制机制,其行为如下:每当在任何 50 秒钟的时间内生成 50 次最近的ER_BINLOG_UNSAFE_STATEMENT警告超过 50 次时,就会启用警告抑制。激活后,这将导致这样的警告不被写入错误日志;而是,对于这种类型的每 50 条警告,都会在错误日志中写入 CommentsThe last warning was repeated N times in last S seconds。只要在 50 秒或更短的时间内发出了最近的 50 条警告,这种情况就会持续下去;一旦速率降低到此阈值以下,警告将再次正常记录。警告抑制不影响如何确定基于语句的日志记录的语句安全性,也不影响如何将警告发送给 Client 端。 MySQLClient 端仍然为每个这样的语句收到一个警告。

有关更多信息,请参见第 16.2.1 节“复制格式”

Statements 被认为是不安全的. 具有以下 Feature 的 Statements 被认为是不安全的:

确定性功能不被认为是不安全的. 尽管这些功能不是确定性的,但出于记录和复制的目的,它们被视为安全的:CONNECTION_ID()CURDATE()CURRENT_DATE()CURRENT_TIME()CURRENT_TIMESTAMP()CURTIME()LAST_INSERT_ID()LOCALTIME()LOCALTIMESTAMP()NOW()UNIX_TIMESTAMP()UTC_DATE()UTC_TIME()UTC_TIMESTAMP()

有关更多信息,请参见第 16.4.1.15 节,“复制和系统功能”

此外,table 中的INSERT具有一个复合主键,该主键包含一个AUTO_INCREMENT列,该列不是此复合键的第一列,这是不安全的。

有关更多信息,请参见第 16.4.1.1 节“复制和 AUTO_INCREMENT”

对于具有多个唯一或主键的 table 的插入...在重复的密钥更新上语句对于基于语句的复制被标记为不安全。 (缺陷#11765650,错误#58637)

有关更多信息,请参见第 16.4.1.33 节,“复制和事务”

有关更多信息,请参见第 16.4.1 节“复制功能和问题”

首页