Мне любопытно услышать стратегии и методы, которые люди используют для выполнения изменений в очень больших таблицах MySQL. Большой может быть любое количество строк или размер, которые могут повлиять на изменение. Для разговора предположим, что 2 миллиона + строк, любое изменение которых будет влиять на нормальную производительность приложения.
Две основные стратегии, которые я вижу, - либо выполнить изменение на ведомом устройстве, а затем сделать его ведущим после его завершения, либо создать копию таблицы с уже выполненными предполагаемыми изменениями, затем скопировать и догнать данные и сделайте переименование, чтобы поменять их местами, прежде чем отбрасывать старые.
В идеале я ищу способ сделать последнее. Меня больше всего беспокоит изменение триггеров в таблице и, конечно, обеспечение синхронизации данных в двух таблицах перед их заменой местами. Я думаю, что вероятность ошибки или отсутствия данных можно в некоторой степени уменьшить, используя переменную read_only в ключевых точках процесса, чтобы убедиться, что данные не меняются при работе с триггерами и после того, как вы догнали все данные. Я понимаю, что это повлияет на приложение, использующее базу данных, но это лучше, чем рисковать поврежденными данными.
Я искал утилиты и стратегии для этого, и их несколько. Примечательным является тот, который Facebook использовал в качестве основы для своих онлайн-изменений. : документация по openark kit. Далее процесс подробно описывается здесь: Мысли и идеи для изменения схемы онлайн
Каков ваш опыт использования любого метода? Какие подводные камни и подводные камни вы встретили? Что вы предпочитаете / предлагаете и почему?
Percona / Maatkit также имеют свои: pt-online-schema-change
Я сделал онлайн-изменения схемы таблиц, содержащих более 100 миллионов строк, с помощью метода триггера, и он работает очень хорошо.
Добавьте триггер в старую таблицу, чтобы скопировать вставленные данные в новую таблицу. Это выглядело бы примерно так:
DELIMITER |
CREATE TRIGGER original_to_new AFTER INSERT ON original_table
FOR EACH ROW BEGIN
INSERT INTO new_table SET col1 = NEW.col1, col2 = NEW.col2...
END;
|
DELIMITER ;
Обратите внимание на первый идентификатор автоинкремента, перемещенный в новую таблицу с триггером.
RENAME original_table TO original_table_backup, new_table TO original_table
Ребята из Continuent включают эту возможность в свой продукт Tungsten Enterprise. Например см .: https://s3.amazonaws.com/releases.continuent.com/doc/tungsten-1.3.3/html/Tungsten-Concepts-And-Administration-Guide/content/ch03s19.html