[2017] Оновлення: MySQL 5.6 підтримує оновлення індексу в Інтернеті
https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html#online-ddl-index-syntax-notes
У MySQL 5.6 і новіших версій таблиця залишається доступною для операцій читання і запису під час створення або падіння індексу. Оператор CREATE INDEX або DROP INDEX закінчується лише після завершення всіх транзакцій, які отримують доступ до таблиці, так що початковий стан індексу відображає останній вміст таблиці. Раніше зміна таблиці під час створення або випадання індексу зазвичай призводило до тупикової ситуації, яка скасовувала в таблиці оператор INSERT, UPDATE або DELETE.
[2015] Оновлення блоків індексів таблиці записується в MySQL 5.5
З відповіді вище:
"Якщо ваша версія версії, що перевищує 5,1 індексу, створюється під час роботи бази даних в Інтернеті. Тож не хвилюйтеся, ви не перервете використання виробничої системи."
Це **** FALSE **** (принаймні для таблиць MyISAM / InnoDB, якими користуються 99,999% людей там. Кластерна версія відрізняється.)
Виконання операцій UPDATE на таблиці БЛОКУЄ під час створення індексу. MySQL насправді, дуже дурний щодо цього (та кількох інших речей).
Тестовий сценарій:
(
for n in {1..50}; do
#(time mysql -uroot -e 'select * from website_development.users where id = 41225\G'>/dev/null) 2>&1 | grep real;
(time mysql -uroot -e 'update website_development.users set bio="" where id = 41225\G'>/dev/null) 2>&1 | grep real;
done
) | cat -n &
PID=$!
sleep 0.05
echo "Index Update - START"
mysql -uroot website_development -e 'alter table users add index ddopsonfu (last_name, email, first_name, confirmation_token, current_sign_in_ip);'
echo "Index Update - FINISH"
sleep 0.05
kill $PID
time mysql -uroot website_development -e 'drop index ddopsonfu on users;'
Мій сервер (InnoDB):
Server version: 5.5.25a Source distribution
Вихідні дані (зауважте, як 6-й блок операцій за ~ 400 мс потрібно для завершення оновлення індексу):
1 real 0m0.009s
2 real 0m0.009s
3 real 0m0.009s
4 real 0m0.012s
5 real 0m0.009s
Index Update - START
Index Update - FINISH
6 real 0m0.388s
7 real 0m0.009s
8 real 0m0.009s
9 real 0m0.009s
10 real 0m0.009s
11 real 0m0.009s
Прочитайте операції, які не блокуються (поміняйте коментар до рядка в сценарії):
1 real 0m0.010s
2 real 0m0.009s
3 real 0m0.009s
4 real 0m0.010s
5 real 0m0.009s
Index Update - START
6 real 0m0.010s
7 real 0m0.010s
8 real 0m0.011s
9 real 0m0.010s
...
41 real 0m0.009s
42 real 0m0.010s
43 real 0m0.009s
Index Update - FINISH
44 real 0m0.012s
45 real 0m0.009s
46 real 0m0.009s
47 real 0m0.010s
48 real 0m0.009s
Оновлення схеми MySQL без простоїв
Таким чином, існує лише один метод, який я знаю, щоб оновити схему MySql і не зазнати відключення доступності. Майстри кругової галузі:
- У програмі Master A працює ваша база даних MySQL
- Принесіть майстра B на службу і повторіть його написання від Master A (B є рабом A)
- Проведіть оновлення схеми на Master B. Це буде відставати під час оновлення
- Нехай майстер Б наздожене. Інваріант: Ваша зміна схеми ОБОВ'ЯЗКОВО має бути здатна обробляти команди, реплікувані із схеми зниження рівня. Зміни індексації підлягають визнанню. Прості доповнення до стовпців зазвичай відповідають вимогам. Видалення стовпця? певно, ні.
- АТОМИЧНО обміняйте всіх клієнтів з Master A на Master B. Якщо ви хочете бути в безпеці (довіртесь, ви це робите), ви повинні переконатися, що останнє записування в A повторюється на B ПЕРЕДБ бере своє перше написання. Якщо ви дозволите одночасне записування для 2+ майстрів, ... ви краще зрозумієте реплікацію MySQL на рівні DEEP або ви прямуєте до світу болю. Сильний біль. Мовляв, чи є у вас стовпець, який є АВТОМОБІЛЬНИМ ??? вас накрутили (якщо ви не використовуєте парних чисел на одному майстрі та коефіцієнтів на іншому). НЕ довіряйте реплікації MySQL "робити все правильно". Це НЕ розумно і не врятує вас. Це просто трохи менш безпечно, ніж копіювати бінарні журнали транзакцій з командного рядка та відтворювати їх вручну. Тим не менш, відключення всіх клієнтів від старого майстра та перехід їх до нового ведучого можна зробити за лічені секунди, набагато швидше, ніж чекати багатогодинного оновлення схеми.
- Тепер майстер Б - ваш новий господар. У вас є нова схема. Життя чудове. Випити пива; найгірше закінчилося
- Повторіть процес з Master A, удосконаливши його схему, щоб він став вашим новим вторинним майстром, готовим перейняти його у випадку, якщо ваш основний господар (майстер B зараз) втратить силу або просто вгору і помирає на вас.
Це не простий спосіб оновити схему. Працює у серйозних виробничих умовах; Так. Будь ласка, будь ласка, якщо є більш простий спосіб додати індекс до таблиці MySQL без блокування записів, дайте мені знати.
Гуглінг веде мене до цієї статті де описана подібна техніка. Ще краще, вони радять пити в той самий момент процедури (зауважте, що я написав свою відповідь перед читанням статті)!
Пер-Пен-онлайн-зміна схем
Статті я пов'язаний вище переговори про інструменті, пт-онлайн-схема заміни , яка працює наступним чином :
- Створіть нову таблицю з такою ж структурою, як оригінал.
- Оновлення схеми в новій таблиці.
- Додайте тригер в оригінальну таблицю, щоб зміни не синхронізувалися з копією
- Скопіюйте рядки партіями з оригінальної таблиці.
- Відсуньте оригінальну таблицю з дороги і замініть новою.
- Відкиньте старий стіл.
Я ніколи не пробував сам інструмент. YMMV
RDS
Зараз я використовую MySQL через RDS Amazon . Це дійсно чудовий сервіс, який завершує та керує MySQL, дозволяючи вам додавати нові репліки для читання за допомогою однієї кнопки та прозоро модернізувати базу даних через апаратні SKU. Це дійсно зручно. Ви не отримуєте SUPER доступу до бази даних, тому ви не можете перекрутити реплікацію безпосередньо (це благо чи прокляття?). Однак ви можете використовувати Просування читання реплік, щоб внести зміни до схеми на підлеглий для читання, а потім просувати цей підлеглий, щоб стати новим господарем. Точно такий же трюк, як я описав вище, просто набагато простіше у виконанні. Вони все ще не дуже допомагають вам у вирішенні. Вам доведеться переналаштувати та перезапустити додаток.