Ответ 1
[2017] Обновление: MySQL 5.6 поддерживает индексы онлайн-индексов
https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html
В MySQL 5.6 и выше таблица остается доступной для операций чтения и записи во время создания или удаления индекса. Операция CREATE INDEX или DROP INDEX завершается только после завершения всех транзакций, которые обращаются к таблице, так что начальное состояние индекса отражает самое последнее содержимое таблицы. Ранее изменение таблицы при создании или удалении индекса обычно приводило к тупиковой ситуации, которая отменила оператор INSERT, UPDATE или DELETE в таблице.
[2015] Таблица обновлений указывает на блокирование записей в MySQL 5.5
Из вышеприведенного ответа:
"Если вы используете версию с индексом более 5,1, когда база данных находится в сети, то не беспокойтесь, вы не будете прерывать использование системы производства."
Это **** FALSE **** (по крайней мере, для таблиц MyISAM/InnoDB, что составляет 99,999% людей, которых там используют. Clustered Edition отличается.)
Выполнение операций UPDATE в таблице будет BLOCK во время создания индекса. MySQL действительно, действительно глупо об этом (и еще несколько вещей).
Тест Script:
(
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
Операции чтения Vs, которые не блокируют (заменяйте комментарий строки в script):
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 и не испытывать сбоя доступности. Круговые мастера:
- У мастера A есть ваша база данных MySQL, работающая на нем
- Принесите Мастер B в действие и попросите его выполнить репликацию из Master A (B является подчиненным A)
- Выполните обновление схемы для мастера B. Это будет отставать во время обновления.
- Пусть Мастер Б догонит. Invariant: Ваше изменение схемы ДОЛЖНО быть способным обрабатывать команды, реплицированные из схемы понижающего преобразования. Изменения индексации квалифицируются. Обычно добавляются простые столбцы. Удаление столбца? возможно нет.
- ATOMICALLY свопите всех клиентов с Master A на Master B. Если вы хотите быть в безопасности (верьте мне, вы это делаете), вы должны убедиться, что последняя запись в реплицируется в B BEFORE B берет свою первую запись. Если вы разрешаете одновременную запись 2+ мастерам,... вы лучше понимаете репликацию MySQL на уровне DEEP или вы направляетесь в мир боли. Крайняя боль. Например, у вас есть столбец, который является AUTOINCREMENT??? вы завинчены (если вы не используете четные цифры на одном хозяине, а шансы - на другом). НЕ доверяйте репликации MySQL, чтобы "делать правильные вещи". Он НЕ умный и не спасет вас. Это немного менее безопасно, чем копирование двоичных журналов транзакций из командной строки и их воспроизведение вручную. Тем не менее, отключить всех клиентов от старого мастера и перевернуть их на новый мастер можно в считанные секунды, намного быстрее, чем ждать многочасового обновления схемы.
- Теперь мастер B - ваш новый мастер. У вас новая схема. Жизнь хороша. Выпейте пиво; худшее закончилось.
- Повторите процесс с мастером A, обновив свою схему, чтобы он стал вашим новым вторичным мастером, готовым принять участие в том случае, если ваш основной мастер (мастер B теперь) теряет силу или просто встанет и умрет на вас.
Простым способом обновления схемы это не так. Работает в серьезной производственной среде; да. Пожалуйста, пожалуйста, пожалуйста, если есть более простой способ добавить индекс в таблицу MySQL, не блокируя записи, сообщите мне.
Googling приведет меня к этой статье, в которой описывается подобная методика. Еще лучше, они советуют пить в одном и том же месте в процессе (обратите внимание, что я написал свой ответ, прежде чем читать статью)!
Percona pt-online-schema-change
статья Я связал выше разговоры о инструменте, pt-online-schema-change, который работает следующим образом:
- Создайте новую таблицу с той же структурой, что и оригинал.
- Обновить схему в новой таблице.
- Добавьте триггер в исходную таблицу, чтобы изменения сохранялись в синхронизации с копией
- Копирование строк в партиях из исходной таблицы.
- Отмените исходную таблицу и замените ее на новую таблицу.
- Удалить старую таблицу.
Я никогда не пробовал инструмент самостоятельно. YMMV
RDS
В настоящее время я использую MySQL через Amazon RDS. Это действительно отличный сервис, который объединяет и управляет MySQL, позволяя вам добавлять новые реплики для чтения с помощью одной кнопки и прозрачно обновлять базу данных через аппаратные SKU. Это очень удобно. Вы не получаете SUPER доступ к базе данных, поэтому вы не можете напрямую вставлять репликацию (это благословение или проклятие?). Тем не менее, вы можете использовать Read Replica Promotion, чтобы внести изменения в схему на ведомом только для чтения, а затем продвинуть этот ведомый, чтобы стать вашим новым мастером. Точно такой же трюк, как я описал выше, просто намного проще выполнить. Они все еще не делают много, чтобы помочь вам с сокращением. Вам необходимо перенастроить и перезапустить приложение.