【问题标题】:How to get rid of "Unsafe statement written to the binary log" message如何摆脱“写入二进制日志的不安全语句”消息
【发布时间】:2017-09-13 06:24:58
【问题描述】:

我正在执行一个简单的 UPDATE 语句,以根据 HTMLEmailLog 表中具有指定 ID 的记录更新联系人表中的字段。这是查询:

UPDATE Contact AS c 
INNER JOIN HTMLEmailLog AS h ON c.CustomerID = h.MemberID and c.Email1 = h.Email        
    SET c.ValidEmail1 = 'N'
WHERE h.id = 160605 ; 

我收到警告:

来自上次查询的警告: 注意:使用语句格式写入二进制日志的不安全语句 因为 BINLOG_FORMAT = STATEMENT。写入表的语句 从另一个表中选择后自动增加列是不安全的,因为 检索行的顺序决定了哪些(如果有)行 书面。此顺序无法预测,并且可能在主服务器和主服务器上有所不同 奴隶

谁能解释一下为什么我会收到此警告消息? 有什么办法可以摆脱这个警告? 如果我直接更新联系人表(不使用 JOIN),我不会收到警告消息。

谢谢。

【问题讨论】:

  • 这只是一个警告,而不是错误消息。
  • 我知道这只是一个警告,但是,我不明白为什么我会收到这个警告,因为没有涉及 ORDER 并且没有插入新记录,只是更新了一个字符字段。也许,这与我在联系人表中的时间戳字段有关。

标签: mysql


【解决方案1】:

首先,这不是错误消息,这是警告。这意味着mysql担心update语句是否可以使用基于语句的复制准确地复制到slave。

  1. 如果您不使用复制,则无需担心。

  2. 如果您使用复制,请考虑更改replication mode to mixed。在混合模式下,如果检测到潜在的不安全语句,mysql 将使用基于行的复制而不是基于语句的复制。

您也可以尝试重写更新以使用子查询而不是连接来指示仅要更新 contact 表:

UPDATE Contact AS c         
SET c.ValidEmail1 = 'N'
WHERE (c.CustomerID, c.Email1) IN (SELECT MemberID, Email FROM HTMLEmailLog WHERE id = 160605);

【讨论】:

  • 感谢您的建议。使用子查询的 UPDATE 查询也显示相同的警告。
  • 在这种情况下,如果您想摆脱警告,则需要使用混合模式复制。
猜你喜欢
  • 2016-07-08
  • 2023-03-16
  • 2014-01-22
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 2014-06-02
  • 1970-01-01
相关资源
最近更新 更多