警告:自BINLOG_FORMAT = STATEMENT以来,使用语句格式将不安全语句写入二进制日志

时间:2013-06-12 04:17:21

标签: mysql master-slave

完整错误:

Warning: Unsafe statement written to the binary log using statement format 
since BINLOG_FORMAT = STATEMENT. Statements writing to a table with an 
auto-increment column after selecting from another table are unsafe because 
the order in which rows are retrieved determines what (if any) rows will be
written. This order cannot be predicted and may differ on master and the 
slave.

在尝试从Django运行原始SQL时,我似乎只遇到此错误。如果我从MySQL CLI客户端运行SQL,我不会得到相同的错误。这是SQL:

UPDATE picture p
JOIN (
    SELECT @inc := @inc + 1 AS new_weight, id
    FROM (SELECT @inc := 0) temp, (
        SELECT id FROM picture
        WHERE album_id = 5
        ORDER BY taken_date ASC
    ) AS pw
) AS pw
ON p.id = pw.id
SET p.weight = pw.new_weight;

这样做的目的是对记录进行排序,并对权重应用序号,以便在数据库中保留此顺序。

我已尝试在客户端中运行此命令,看看我是否可以复制该问题,但它仍然可以成功运行:

mysql> SET GLOBAL binlog_format = 'STATEMENT';

此外,重要的是我要么解决或重写SQL来使用这个约束,因为最终的应用程序几乎肯定会在主从数据库设置中运行。

*编辑:在阅读了更多binlog_format之后,好像ROW或MIXED似乎完全可以接受,但是我主要担心的是无法在MySQL CLI中复制此问题以测试是否MIXED / ROW可以解决这个问题吗?

1 个答案:

答案 0 :(得分:9)

没有办法重写sql以不抛出该错误消息。任何类型的命令都将抛出该消息,因为从属可能具有与主服务器不同的行。 mixed将解决此问题,因为只有在使用row复制语句时,它才会切换到基于statement的复制。