Изменить таблицу в живых производственных базах

24

Как наиболее «популярная» (MySQL, Postgres ...) система баз данных обрабатывает изменение таблиц в действующих производственных базах данных (например, добавление, удаление или изменение типа столбцов)?

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

Но ... поддерживает ли какая-либо текущая система баз данных выполнение этих операций в режиме онлайн без каких-либо остановок? (возможно, просто задерживает запросы, которые ссылаются на столбец, который только что был изменен / удален)

И что это происходит, когда я просто делаю ALTER TABLE...на работающей базе данных? Все ли останавливается, когда это происходит? Могут ли данные быть повреждены? и т.п.

Опять же, я в основном имею в виду Postgres или MySQL, поскольку с этим я сталкиваюсь.

(И да, в любое время мне приходилось делать это, прежде чем я сделал это «правильным образом», резервное копирование, планирование понижения и т. Д. ... но я просто хочу знать, возможно ли сделать это и так быстро и быстро » «грязный» или если есть какая-либо система БД, которая на самом деле поддерживает «быстрые, живые и грязные» изменения схемы)


Кто-то только что предложил Online Schema Change для MySQL из скрипта Facebook (с учебником здесь и источником здесь ) ... кажется хорошим способом автоматизировать набор "хакерских" способов сделать это ... кто-нибудь когда-либо использовал его в чем-то похожим на производство?

NeuronQ
источник
3
Примечание. Указанный «правильный путь» относится к MySQL, а не к PostgreSQL. «Правильный путь» в PostgreSQL, как правило, очень прост, хотя он может быть задействован. Использование pg_reorgможет помочь с более сложными сценариями.
Шон
Я хотел бы иметь подробное видео на эту тему, где кто-то объясняет как можно больше стратегий.
Сандипан Нат

Ответы:

22

Когда вы запускаете ALTER TABLEв PostgreSQL, он берет ACCESS EXCLUSIVEблокировку, которая блокирует все, включаяSELECT . Тем не менее, эта блокировка может быть весьма кратко , если таблица не требует переписывания, никаких новых UNIQUE, CHECKили FOREIGN KEYограничения не нужны дорогие полного сканирования таблицы для проверки и т.д.

Если вы сомневаетесь, вы можете просто попробовать это! Весь DDL в PostgreSQL является транзакционным, поэтому вполне нормально отменить, ALTER TABLEесли он занимает слишком много времени и начинает задерживать другие запросы. Уровни блокировки, требуемые различными командами, описаны на странице блокировки .

Некоторые обычно медленные операции могут быть ускорены, чтобы их можно было безопасно выполнять без простоев. Например, если у вас есть таблица tи вы хотите изменить столбец customercode integer NOT NULLна, textпотому что клиент решил, что все коды клиентов теперь должны начинаться с X, вы можете написать:

ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );

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

ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;

Это будет только предотвратить операции записи в tходе процесса; имя замка EXCLUSIVEнесколько обманчиво в том смысле, что оно исключает все, кромеSELECT ; ACCESS EXCLUSIVEрежим является только один , который не включает абсолютно Everyting. Смотрите режимы блокировки . Существует риск того, что эта операция может привести к взаимному откату блокировки из-за необходимости обновления блокировки ALTER TABLE, но в худшем случае вам просто придется сделать это снова.

Вы даже можете избежать этого замок и делать все это вживую, создав функцию триггера на tтом , что всякий раз , когда INSERTили UPDATEприходит, заполнятся автоматически customercode_newс customercode.

Существуют также встроенные инструменты, такие как CREATE INDEX CONCURRENTLYи ALTER TABLE ... ADD table_constraint_using_indexпредназначенные для того, чтобы администраторы баз данных могли сократить длительность исключительной блокировки, выполняя работу медленнее и в условиях параллелизма.

pg_reorgИнструмент или его преемник pg_repackможет быть использован для некоторых операций по реструктуризации таблиц , а также.

Крейг Рингер
источник
1
Ключевым моментом в том, что сказал @Craig, было «если это не требует переписывания». Использование ALTER TABLE t ADD COLUMN i INT- это быстрая операция (обычно <1 мс) после получения блокировки. Однако получение блокировки может поставить в очередь соединения, так что это не «бесплатно» ... хотя в мире это лучше, чем то, что вы должны делать в MySQL. Добавление NOT NULLограничения является более трудным и не для притворства сердца.
Шон
Кажется, что консенсус pg_repackявляется улучшенным преемником pg_reorg.
Эрвин Брандштеттер,
Хороший ответ, касающийся добавления столбца с заданным по умолчанию (или вычисляемым) менее «блокирующим» способом, заключается в создании всей новой таблицы, блокировании старой таблицы для вставки / обновления / удаления, но с возможностью выбора и заполнения новой. Наконец, выполните короткую монопольную блокировку старой таблицы для выбора, удалите ее и переименуйте новую в старую. В зависимости от сценария вы можете даже начать заполнять новый без блокировки вставки в старых и вопрос , что эксклюзивная блокировка только при решении диф (надеюсь , просто вставив несколько новых записей)
жан
7

Percona предлагает собственный инструмент для изменения схем в сети

Инструмент называется pt-online-schema-change

Это включает триггеры, поэтому, пожалуйста, внимательно прочитайте документацию.

Согласно Документации, основные операции выполнены

  • Проверки вменяемости
  • лязг
  • Изменение схемы онлайн
    • Создать и изменить временную таблицу
    • Захват изменений из таблицы во временную таблицу
    • Скопировать строки из таблицы во временную таблицу
    • Синхронизировать таблицу и временную таблицу
    • Поменяйте местами / переименуйте таблицу и временную таблицу
    • уборка
RolandoMySQLDBA
источник
спасибо, похоже на «упрощенную» версию подхода Facebook, которой я мог бы доверять больше ...
NeuronQ
pt-online-schema-change определенно является предпочтительным способом сделать это, если вы используете свой собственный сервер MySQL. Начиная с Percona Tools 2.2, (к сожалению) они не поддерживают RDS / Aurora в AWS. pt-online-schema-change вставляет триггер в исходную таблицу для копирования строк (низкий приоритет для MyISAM) в целевой table_temp и выполняет однократное быстрое удаление блокировки и переименование в конце, когда все строки синхронизируются между источником и назначением столы.
phpguru
6

Выключение системы и одновременное выполнение всех изменений может быть очень рискованным. Если что-то идет не так, как это часто случается, обратного пути нет.

Как разработчику Agile, мне иногда нужно реорганизовывать таблицы без каких-либо простоев, так как эти таблицы изменяются и читаются.

Следующий подход имеет низкий уровень риска, поскольку изменение выполняется в несколько этапов с низким уровнем риска, которые очень легко откатить:

  • Убедитесь, что все модули, обращающиеся к таблице, хорошо защищены автоматическими тестами.
  • Создать новую таблицу. Измените все процедуры, которые изменяют старую таблицу, чтобы они изменяли как старые, так и новые таблицы.
  • Перенос существующих данных в новую структуру. Делайте это небольшими партиями, чтобы это не оказало серьезного влияния на общую производительность сервера.
  • Убедитесь, что миграция данных прошла успешно.
  • Перенаправьте некоторые процедуры выбора из старой таблицы в новую. Используйте автоматические тесты, чтобы убедиться, что измененные модули по-прежнему правильны. Убедитесь, что их производительность приемлема. Разверните измененные процедуры.
  • Повторяйте предыдущий шаг, пока все отчеты не будут использовать новую таблицу.
  • Измените процедуры, которые изменяют таблицы, чтобы они имели доступ только к новой таблице.
  • Архивируйте старую таблицу и удалите ее из системы.

Мы много раз использовали этот подход для изменения больших рабочих таблиц без простоев, без каких-либо проблем.

Аляска
источник
3
здорово ... но это именно тот тип "боли", которого я
стараюсь
@NeuronQ «Обратного пути нет » - есть в Postgres: просто вложите все в транзакцию и rollbackесли что-то пойдет не так.
a_horse_with_no_name
2

Да, многие современные базы данных позволят вам просто добавить столбец или изменить характеристики столбца, например добавить или удалить nullable.

Если вы уроните столбец, данные будут потеряны, но не будет большого страха коррупции.

Марлин Пирс
источник
0

Инструмент Percona использует триггеры, чтобы помочь в его изменении, и он не очень хорошо играет, если на вашем столе уже есть триггеры. В итоге мне пришлось написать тот, который действительно хорошо обрабатывает существующие триггеры, поскольку они очень важны для нашей базы данных https://github.com/StirlingMarketingGroup/smg-live-alter

Брайан говорит восстановить Монику
источник
-1

Чтобы ответить на вопрос о том, что происходит с ALTER TABLEзаявлением, это зависит от степени ваших изменений. В определенных случаях, если вы добавляете новый столбец, по крайней мере, в MS SQL Server, механизм создает временную копию таблицы, создает новое определение таблицы и затем вставляет туда данные. Таким образом, во время изменения таблица будет недоступна для пользователей.

Пример конкретных операций для сервера MSSQL приведен здесь: http://support.microsoft.com/kb/956176/en-us

Я бы предположил, что другие RMDB имеют аналогичные методы, хотя точную реализацию вы должны будете проверить с помощью документации поставщика.

SchmitzIT
источник
-1 Это совершенно неправильно для SQL Server: «Если вы добавите новый столбец, по крайней мере в MS SQL Server, механизм создаст временную копию таблицы, в то время как он создаст новое определение таблицы, а затем вставит данные обратно там "
АК
@AlexKuznetsov - я понял предыдущую строку, а также связь с некоторыми из перечисленных случаев, прояснившая это, не всегда бывает. Я изменил предложение, чтобы лучше отразить это.
SchmitzIT
1
Вы упоминаете о поведении GUI, SSMS, а не о поведении самого SQL Server. Следуя вашей ссылке, советуем использовать T-SQL напрямую для внесения изменений в DDL. SSMS не очень хороший инструмент для изменения DDL.
AK
@AlexKuznetsov - Я прочитал статью, в которой говорилось, что есть риски, но не как уныние. Во всяком случае, я не связывал статью с битом GUI, но как указание на некоторые операции, которые приводят к выражению ALTER, ведущему к созданию временной таблицы из-за изменений в базовой структуре данных. Я не проверял, применяется ли точно такая же вещь при выдаче оператора непосредственно из T-SQL, но я думаю, что процесс довольно похож и что SL Server выполняет свою работу за кулисами.
SchmitzIT
Вы можете запустить Profiler, выполнить инструкцию ALTER TABLE напрямую и посмотреть, что происходит. Затем вы можете изменить таблицу в диалоговом окне и посмотреть, какие команды выполняются.
АК