Змініть таблицю на базі даних живого виробництва


24

Як більшість "популярних" (MySQL, Postgres ...) системних баз обробляють зміни таблиць на базах даних в реальному виробництві (наприклад, додавання, видалення або зміна типу колон)?

Я знаю, що правильний спосіб - створити резервну копію всього простою в розкладі, а потім зробити зміни.

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

А що трапляється, коли я просто роблю ALTER TABLE...базу даних, що працює в реальному часі? Чи все припиняється, коли це відбувається? Чи можуть дані пошкодитися? тощо.

Знову ж таки, я здебільшого маю на увазі Postgres або MySQL, оскільки це те, з чим я стикаюся.

(І так, будь-коли, коли я мав це робити, перш ніж зробити це "правильним способом", створивши резервну копію речей, склавши графік роботи і т.д. ..., але я просто хочу знати, чи можна робити такі речі та речі "швидко та швидко" брудно "або якщо є якась система БД, яка фактично підтримує зміни схеми" швидкі, живі та брудні ")


Хтось щойно запропонував змінити схему Інтернету для MySQL із сценарію Facebook (з підручником тут і джерелом тут ) ... здається, хороший спосіб автоматизувати набір "хакі" способів це зробити ... хтось коли-небудь використовував це в щось схоже на виробництво?


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_indexthat're розроблені , щоб дозволити Абду зменшити ексклюзивні замикають тривалості, роблячи роботу більш повільно в паралелізм дружнього способу.

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


1
Ключовим у тому, що сказав @Craig, було: "якщо це не потребує переписування". Використання анкети ALTER TABLE t ADD COLUMN i INT- це швидка операція (як правило, <1 мс) після придбання блокування. Придбання блокування може встановити черги на з'єднання, тому це не є "безкоштовним" ... хоча це в світі краще, ніж те, що потрібно робити в MySQL. Додавати NOT NULLобмеження важче і не для зухвалого серця.
Шон

Здається, є консенсус, що pg_repackсаме вдосконалений наступник Росії pg_reorg.
Erwin Brandstetter

Хороша відповідь щодо додавання стовпця з типовим (або обчисленим) менш "блокувальним" способом - це створити цілу нову таблицю, заблокувати стару таблицю для вставки / оновлення / видалення, але дозволяючи вибирати та заповнювати нову. Нарешті, виберіть короткий ексклюзивний замок на старій таблиці для вибору, видаліть його та перейменуйте новий на старий. Залежно від вашого сценарію, ви навіть можете почати заповнювати нове, не блокуючи вставки в старому та видаючи цей ексклюзивний замок лише під час вирішення розрізнення (сподіваємось, просто вставляючи кілька нових записів)
jean

7

Percona розробила власний інструмент для зміни онлайн-схем

Інструмент називається pt-online-schema-change

Це включає тригери, тому, будь ласка, уважно прочитайте документацію.

Згідно з Документацією, зроблені основні операції

  • Перевірки обгрунтованості
  • Чунчінг
  • Змінення онлайн-схеми
    • Створіть та змініть тимчасову таблицю
    • Захоплення змін від таблиці до тимчасової таблиці
    • Скопіюйте рядки з таблиці в тимчасову таблицю
    • Синхронізуйте таблицю та тимчасову таблицю
    • Замініть / перейменуйте таблицю та тимчасову таблицю
    • Прибирати

дякую, схоже на "солдатську" версію підходу Facebook, якому я можу довіряти більше ...
NeuronQ

pt-online-схема-зміна, безумовно, є кращим способом зробити це, якщо ви використовуєте власний сервер MySQL. Станом на Percona Tools 2.2 (на жаль) вони не підтримують RDS / Aurora на AWS. pt-online-схема-зміна вставляє тригер у вихідну таблицю для копіювання рядків (низький пріоритет для MyISAM) у таблицю призначення_значення та робить єдине швидке блокування та перейменування в кінці, коли всі рядки синхронізуються між джерелом та пунктом призначення столи.
phpguru

6

Вимкнення системи та здійснення всіх змін одразу може бути дуже ризикованим. Якщо щось піде не так, а часто це відбувається, немає простого шляху назад.

Як розробник Agile, мені іноді потрібно взагалі переробляти таблиці без простоїв, оскільки ці таблиці змінюються та читаються з них.

Наступний підхід має низький ризик, оскільки зміна проводиться в кілька кроків із низьким рівнем ризику, які дуже легко відкотити:

  • Переконайтесь, що всі модулі, що мають доступ до таблиці, добре покриті автоматизованими тестами.
  • Створіть нову таблицю. Змініть всі процедури, що змінюють стару таблицю, щоб вони модифікували і старі, і нові таблиці.
  • Міграція існуючих даних у нову структуру. Робіть це невеликими партіями, щоб це не впливало серйозно на загальну продуктивність на сервері.
  • Переконайтеся, що переміщення даних вдалося.
  • Перенаправіть деякі процедури вибору зі старої таблиці на нову. Використовуйте автоматизовані тести, щоб переконатися, що змінені модулі все ще є правильними. Переконайтесь, що їх продуктивність є прийнятною. Розгорніть змінені процедури.
  • Повторіть попередній крок, поки всі звіти не використовуватимуть нову таблицю.
  • Змініть процедури, що змінюють таблиці, щоб вони отримували доступ лише до нової таблиці.
  • Заархівуйте стару таблицю та вийміть її із системи.

Ми багато разів використовували такий підхід для зміни великих виробничих таблиць без простоїв, без проблем.


3
чудово ... але це саме той тип "болю", якого я хочу уникати :)
NeuronQ

@NeuronQ " Немає легкого шляху назад " - є в Postgres: просто покладіть все на транзакцію і rollbackякщо щось піде не так.
a_horse_with_no_name

2

Так, багато сучасних баз даних дозволять вам просто додати стовпчик або змінити характеристики стовпця, як-от додавання або видалення зведеного на ніч.

Якщо ви опустите стовпчик, дані будуть втрачені, але страх корупції не так вже й багато.


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 мають подібні методи, хоча точна реалізація буде те, що вам доведеться перевірити за допомогою документації постачальника.


-1 Це абсолютно неправильно для SQL Server: "Якщо ви додасте новий стовпець, принаймні в MS SQL Server, двигун створить тимчасову копію таблиці, тоді як вона створить нове визначення таблиці, а потім вставить дані назад там "
АК

@AlexKuznetsov - Я зрозумів, що попередній рядок, а також зв’язок з деякими з перелічених випадків уточнив би, що це не завжди буває. Я змінив речення, щоб краще відобразити це.
SchmitzIT

1
Ви згадуєте поведінку GUI, SSMS, а не поведінку самого SQL Server. Після вашого посилання порада полягає у використанні T-SQL безпосередньо для внесення змін у DDL. SSMS - не дуже хороший інструмент для зміни DDL.
АК

@AlexKuznetsov - Я читав статтю, як кажучи, що це пов'язано з ризиками, але не як розчарування. У будь-якому випадку, я не пов'язував статтю для біта GUI, але як вказівку на деякі операції, які призводять до оператора ALTER, що призводить до створення тимчасової таблиці через зміни основної структури даних. Я не перевіряв, чи застосовується саме те саме при видачі заяви безпосередньо з T-SQL, але я вважаю, що процес досить схожий і що SL Server виконує роботу за кадром.
SchmitzIT

Ви можете запустити Profiler, виконати операцію ALTER TABLE безпосередньо та побачити, що відбувається. Потім ви можете змінити таблицю за допомогою діалогового вікна і побачити для себе виконання команд.
АК
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.