HeadlinesBriefing favicon HeadlinesBriefing.com

Ошибка обновления реплики MySQL: несоответствие AUTO_INCREMENT

Hacker News •
×

Рутинное обновление MySQL на AWS RDS вызвало скрытое повреждение данных при продвижении зеленой реплики. После обновления реплики и проверки ее функциональности автор переключил трафик. Через час появилась критическая ошибка: одна таблица (таблица X) имела свои автоинкрементные ID, назначенные в разном порядке на реплике по сравнению с источником. Строка, которая ранее имела ID 1, теперь имела ID 26.

Основная причина восходит к предыдущей миграции, которая добавила первичный ключ AUTO_INCREMENT к таблице X с помощью `ALTER TABLE X ADD COLUMN id INT NOT NULL AUTO_INCREMENT PRIMARY KEY`. Шесть связанных таблиц были обновлены для ссылки на этот новый ID с использованием операторов UPDATE на основе JOIN. Однако документация MySQL предупреждает, что добавление столбцов AUTO_INCREMENT в реплицируемые таблицы может привести к различному порядку строк на источнике и реплике в зависимости от движка хранения и порядка обработки.

Разница проявилась из-за формата бинарного журнала исходной базы данных `binlog_format=MIXED`. Пять таблиц реплицировали свои операторы UPDATE в режиме STATEMENT, что привело к тому, что реплика повторно выполнила JOIN относительно своих локальных (различных) значений ID — правильно сопоставляя ссылки. Но шестая таблица, которая также имела столбец AUTO_INCREMENT, была признана небезопасной для репликации на основе операторов и залогирована в режиме ROW. Реплика применила необработанные изменения строк из источника, скопировав значения `x_id`, сгенерированные источником, которые теперь указывали на неправильные строки в реплике.

Это тонкое взаимодействие между порядком назначения AUTO_INCREMENT, смешанным бинарным журналированием и обнаружением небезопасных операторов привело к скрытому нарушению ссылочной целостности. Автор предупреждает, что такие проблемы легко упустить из виду во время обновлений, но они могут быстро повредить данные.

Ключевые сущности: Компании: AWS, MySQL