Код предупреждения Mysql 1592 — При выполнении ОБНОВЛЕНИЯ реплицируемого экземпляра mysql

#mysql #database-replication

#mysql #база данных-репликация

Вопрос:

[Есть похожие вопросы по SO — но ни один из них не относится к этому сценарию]

Я выдаю это утверждение:

 update a 
join b on a.fk = b.id
and b.f1 = 1
and b.f2 = 1
set a.f = 1;
  

И получите эту ошибку:

1592 Небезопасный оператор, записанный в двоичный журнал с использованием формата statement, начиная с BINLOG_FORMAT = STATEMENT . Инструкции, записываемые в таблицу с автоинкрементным столбцом после выбора из другой таблицы, небезопасны, поскольку порядок, в котором извлекаются строки, определяет, какие (если таковые имеются) строки будут записаны. Этот порядок невозможно предсказать и может отличаться для ведущего и ведомого устройства.

Насколько я понимаю, это означает:

  • Mysql регистрирует инструкции, выполняемые на главном сервере, и воспроизводит их на подчиненном устройстве для выполнения репликации
  • Если результаты инструкции не являются детерминированными, могут быть расхождения между master и salve

Я понимаю, что если я выполняю вставку на основе запроса с недетерминированным порядком и использую автоматически сгенерированный идентификатор (или любое другое поле), другой порядок результатов приведет к разным значениям, присвоенным полю id.

Однако этот запрос обновляет уже существующую запись — просто перезаписывает некоторые из ее полей постоянным значением. В частности, я не вижу никакой связи между порядком внутреннего запроса и конечным состоянием БД.

Безопасен ли этот запрос или есть какие-то другие проблемы, которые я не заметил? Если нет, есть ли способ переписать запрос безопасным способом?

Комментарии:

1. Вероятно, нам потребуется просмотреть фактический запрос и определения таблиц. Оптимизатор (соответственно) агрессивен при определении небезопасности операторов, поэтому многие запросы, помеченные как небезопасные, на самом деле являются детерминированными. Однако лучшим решением является использование MIXED формата binlog. Затем репликация выберет ведение журнала инструкций, когда сможет, и ведение журнала строк, когда сочтет инструкцию небезопасной, и эти предупреждения не будут возникать.