Модифікація стовпців дуже великих таблиць mysql з невеликим простоєм або взагалі


18

Мені періодично потрібно вносити зміни до таблиць у mysql 5.1, в основному додаючи стовпці. Дуже просто з командою alter table. Але в моїх таблицях зараз до 40 мільйонів рядків, і вони швидко зростають ... Тож ці команди змінних таблиць займають кілька годин. Через пару місяців вони займуть дні, я здогадуюсь.

Оскільки я використовую amazon RDS, я не можу мати невільників-серверів, щоб грати, а потім просувати їх до майстерності. Тож моє запитання, чи є спосіб зробити це з мінімальним простоєм? Я не заперечую за тим, щоб операція займала години чи навіть дні, якщо користувачі все-таки можуть використовувати db, звичайно ... Чи можуть вони хоча б читати під час додавання стовпців? Що станеться, якщо мій додаток намагається записати? Вставити чи оновити? Якщо це не вдається відразу, це насправді не так вже й погано, якщо він просто зависає і створює проблеми для db-сервера, це велика проблема ..

Це має бути досить поширеним питанням масштабування, кожен повинен додати стовпці. Що зазвичай робиться для виробничого db? Раб -> майстер міграції?

Оновлення - я забув згадати, що я використовую механізм зберігання innodb


1
У випадку, якщо хтось все ще шукає відповідь .. blog.staginginstance.com/… ^^
Coder анонімний

Відповіді:


10

Мені періодично потрібно вносити зміни до таблиць у mysql 5.1, в основному додаючи стовпці.

Не варто. Насправді ні. Просто ні. Це має бути дуже рідкісним випадком, коли це коли-небудь необхідно.

Якщо припустити, що ваші дані дійсно нормалізуються для початку, правильним способом вирішення проблеми є додавання нової таблиці зі співвідношенням 1: 1 до базової таблиці (необов'язково для нової таблиці).

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

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

  1. Переконайтеся, що у вас є стовпець часової позначки в базі даних або що вона генерує журнали реплікації
  2. Створіть копію (B) таблиці (A)
  3. додайте нові стовпці до B (це все одно блокуватиметься з myisam)
  4. відключення транзакцій
  5. перейменуйте оригінальну таблицю (A) як щось інше (резервне копіювання)
  6. перейменуйте нову таблицю (B) з назвою вихідної таблиці (A)
  7. відтворити транзакції з початку операції з журналу реплікації або з таблиці резервного копіювання
  8. включити транзакції.

2
Дякуємо вам за покроковий підхід. Дійсно змінювати таблиці? Я розумію, що замість цього я можу додати ще одну таблицю з новим стовпцем (у випадку, якщо потрібно додати стовпець), і посилатимуться на оригінальну велику таблицю у співвідношенні 1: 1. Але не здається правильним мати 15 дуже великих таблиць 1: 1, коли вони повинні бути в одній таблиці ... Виконання запитів, звичайно, також страждає, не кажучи вже про проблеми індексації. Я не експерт, але моя база даних досить добре нормалізується, і, здається, природно, що мені потрібно періодично змінювати ..
apptree

2
"Чи дійсно рідко змінювати таблиці?" - Так.
symcbean

1
Ні, але можна стверджувати, що якщо це трапиться РЕГУЛЬНО - не як частина капітального оновлення програмного забезпечення - то когось потрібно звільнити за те, що він не усвідомлює, що всі таблиці повинні бути там в першу чергу. Проблема / хитрість тут - "регулярно", а не "Раз на пару місяців".
TomTom

22
Як розробник, особливо той, що працює у стартапах та молодих компаніях, я не міг менше погодитися з symcbean та @TomTom. Все змінюється, змінюються продукти, змінюються бізнес-цілі, і структура бази даних повинна змінюватися разом з ними. Надання хорошого обслуговування DBA означає "так" цим змінам, а потім з'ясувати, як їх ефективно впровадити. Сильно нормалізовані бази даних - це концепція, яка давно померла. Вони призводять до поганої продуктивності та повільних циклів розвитку.
pents90

4
Нечасто змінювати таблиці ??? Можливо, у великих компаніях, але у спритній команді, що трапляється досить часто, вимоги змінюються ...
tibo

12

Мені довелося це зробити недавно. Що рекомендував Amazon, це використання інструментарію Percona. Я завантажив його і зміг запустити щось на кшталт:

./pt-online-schema-change h=databasenameHostName,D=databasename,t=tablename --recursion-method=none --execute --user username --password password --alter "MODIFY someColumn newDataType"

і це чудово працює. Він говорить вам, скільки часу залишилось у процесі.

Він фактично створює нову таблицю з новим стовпцем, а потім копіює наявні дані. Крім того, він створює тригер, щоб нові дані також були перенесені на нову таблицю. Потім він автоматично перейменовує таблиці, скидає стару таблицю, і ви працюєте з новим стовпцем і без простоїв, поки ви чекали оновлень.


Команда Percona має короткий запис про включення функції log_bin_trust_function_creators через групи параметрів RDS (оскільки SET GLOBAL log_bin_trust_function_creators = 1 не працює на RDS), необхідний інструментом pt-online-schema-change. Детальніше: percona.com/blog/2016/07/01/pt-online-schema-change-amazon-rds
user1652110

це працювало для мене
Адіії

4

symcbean дає деякі ґрунтовні рекомендації .

Щоб відповісти на ваше запитання, найпростіший і найкращий спосіб пом'якшити вплив - це реплікація декількох баз даних. Подвійний майстер із відповідною процедурою відмови, зупиняючи реплікацію на активний, що дозволяє змінювати неактивний, не впливаючи на активний.

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

Зрештою, якщо ваш набір даних зростає настільки великим, вам слід також врахувати архіви між базами даних OLTP та OLAP . Набір даних транзакцій не повинен бути настільки великим, якщо ви розробляєте належним чином.


2

З посібника: http://dev.mysql.com/doc/refman/5.1/uk/alter-table.html

У більшості випадків ALTER TABLE робить тимчасову копію оригінальної таблиці. MySQL включає в себе зміну в копію, потім видаляє оригінальну таблицю і перейменовує нову. Поки ALTER TABLE виконується, оригінальна таблиця читається іншими сесіями. Оновлення та записи до таблиці зупиняються до тих пір, поки нова таблиця не буде готова, а потім автоматично переспрямована до нової таблиці без невдалих оновлень.

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


Тому я це зробив і відключив частини мого сайту, які записують у таблицю, що я зараз змінюю. Поки я отримав кілька винятків "Блокування очікування блокування; перевищити спробу перезапустити транзакцію", це не дуже погано. Однак вони були на операціях читання PURELY ...
apptree

0

Я перебуваю в подібній ситуації, коли мені потрібно змінити 1 мою таблицю транзакцій, яка становить майже 65 Гб. Я чую 2 рішення

  1. Скористайтеся прямим НАЗАДАМИ та нехай він працює (X кількість годин або день)
  2. Переконайтеся, що у вас є стовпець часової позначки в базі даних або що вона генерує журнали реплікації
    • Створіть копію (B) таблиці (A)
    • додайте нові стовпці до B (це все одно блокуватиметься з myisam)
    • відключення транзакцій
    • перейменуйте оригінальну таблицю (A) як щось інше (резервне копіювання)
    • перейменуйте нову таблицю (B) з назвою вихідної таблиці (A)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.