[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, когда база данных находится в сети. Так что не волнуйтесь, вы выиграли"• прервать использование производственной системы. "
Это **** ЛОЖЬ **** (по крайней мере для таблиц MyISAM / InnoDB, что составляет 99,999%люди используют там. Clustered Edition отличается.)
Выполнение операций UPDATE над таблицей будет BLOCK во время создания индекса.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 и не допускать сбоя доступности.Круговые мастера:
- Мастер A использует вашу базу данных MySQL, работающую на нем
- Приведите в действие Master B и заставьте его реплицировать записи с Master A (B является подчиненным A)
- Выполните обновление схемы на Master B. Оно будет отставать во время обновления
- Пусть Master B наверстает упущенное.Инвариант: ваше изменение схемы ДОЛЖНО быть способным обрабатывать команды, реплицированные из схемы обратного преобразования.Изменения индексации соответствуют требованиям.Простые добавления столбцов обычно квалифицируются.Удаление столбца?возможно нет.
- АТОМНО поменять местами всех клиентов с Master A на Master B. Если вы хотите быть в безопасности (поверьте мне, вы делаете это), вы должны убедиться, что последняя запись в A реплицирована в B ДО B берет свою первую запись.Если вы разрешаете одновременную запись для 2+ мастеров, ... вы лучше понимаете репликацию MySQL на уровне DEEP, или вам грозит мир боли.Сильная боль.Мол, у вас есть колонка, которая AUTOINCREMENT ???вы облажались (если вы не используете четные числа на одном хозяине и шансы на другом).НЕ доверяйте репликации MySQL, чтобы «делать правильные вещи».Это НЕ умный и не спасет вас.Это немного менее безопасно, чем копировать двоичные журналы транзакций из командной строки и воспроизводить их вручную.Тем не менее, отключение всех клиентов от старого мастера и переключение их на новый мастер может быть сделано за считанные секунды, значительно быстрее, чем ожидание многочасового обновления схемы.
- Теперь Мастер B - ваш новый мастер,У вас есть новая схема.Жизнь хороша.Есть пиво;худшее позади.
- Повторите процесс с Мастером А, обновив его схему так, чтобы он стал вашим новым вторичным мастером, готовым вступить во владение в случае, если ваш основной мастер (мастер Б сейчас) теряет власть или простои умирает от вас.
Простой способ обновить схему это не так.Работоспособен в серьезных производственных условиях;Да, это.Пожалуйста, пожалуйста, пожалуйста, если есть более простой способ добавить индекс в таблицу MySQL без блокировки записей, дайте мне знать.
Поиск в Google приводит меня к этой статье , которая описывает аналогичныйтехника.Более того, они советуют пить в тот же момент в процессе (обратите внимание, что я написал свой ответ, прежде чем читать статью)!
Percona's pt-online-schema-change
В статье , которую я привел выше, говорится об инструменте pt-online-schema-change , который работает какследует:
- Создать новую таблицу с такой же структурой, что и исходная.
- Обновить схему для новой таблицы.
- Добавить триггер в исходную таблицу, чтобы сохранить изменениясинхронно с копией
- Копирование строк в пакетах из исходной таблицы.
- Перемещение исходной таблицы в сторону и ее замена новой таблицей.
- Удаление старой таблицы.
Сам никогда не пробовал этот инструмент.YMMV
RDS
В настоящее время я использую MySQL через Amazon RDS .Это действительно изящный сервис, который объединяет и управляет MySQL, позволяя вам добавлять новые реплики чтения с помощью одной кнопки и прозрачно обновлять базу данных с помощью аппаратных SKU.Это действительно удобно.У вас нет СУПЕР-доступа к базе данных, поэтому вы не можете напрямую связываться с репликацией (это благословение или проклятие?).Однако вы можете использовать Read Replica Promotion , чтобы внести изменения в схему на ведомом устройстве, доступном только для чтения, а затем повысить статус этого ведомого, чтобы он стал вашим новым хозяином.Точно такой же трюк, как я описал выше, просто гораздо проще выполнить.Они до сих пор не делают много, чтобы помочь вам с сокращением.Вам нужно перенастроить и перезапустить приложение.