[2017] Актуализация:MySQL 5.6 има поддръжка за онлайн актуализации на индекси
В 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
- Введете Master B в експлоатация и го накарайте да копира записите от Master A (B е подчинен на A)
- Извършете актуализацията на схемата на Master B. Тя ще изостане по време на надстройката
- Нека Master B навакса. Инвариантно:Вашата промяна на схемата ТРЯБВА да може да обработва команди, репликирани от схема за понижаване. Промените в индексирането отговарят на условията. Обикновено се квалифицират прости добавяния на колони. Премахване на колона? вероятно не.
- АТОМИЧНО разменете всички клиенти от Master A към Master B. Ако искате да сте в безопасност (повярвайте ми, го правите), трябва да се уверите, че последното записване към A е репликирано на B ПРЕДИ B прави първото си записване. Ако разрешите едновременни записи на 2+ глави, ... вие разбирате по-добре репликацията на MySQL на ниво DEEP или се насочвате към свят на болка. Екстремна болка. Като, имате ли колона, която е АВТОМАТИЧНО ИНКРЕМЕНТ??? прецакани сте (освен ако не използвате четни числа на единия мастер и коефициенти на другия). НЕ се доверявайте на MySQL репликацията да "прави правилното нещо". НЕ е умно и няма да ви спаси. Просто е малко по-малко безопасно от копирането на регистрационни файлове на двоични транзакции от командния ред и възпроизвеждането им на ръка. И все пак, прекъсването на връзката на всички клиенти от стария главен код и преобръщането им към новия главен код може да стане за броени секунди, значително по-бързо, отколкото да се чака многочасова надстройка на схемата.
- Сега Master B е вашият нов господар. Имате новата схема. Животът е добър. Пийте бира; най-лошото свърши.
- Повторете процеса с Master A, надграждайки неговата схема, така че той да стане вашият нов вторичен главен, готов да поеме управлението в случай, че основният ви господар (майстор B сега) загуби мощност или просто се издигне и умре върху вас.
Това не е лесен начин за актуализиране на схемата. Работещи в сериозна производствена среда; да, така е. Моля, моля, моля, ако има по-лесен начин за добавяне на индекс към MySQL таблица без блокиране на запис, уведомете ме.
Търсенето в Google ме доведе до тази статия който описва подобна техника. Още по-добре, те съветват да се пие в същия момент от процедурата (Обърнете внимание, че написах отговора си, преди да прочета статията)!
Промяната на pt-online-schema-change на Percona
статията Свързах по-горе разговори за инструмент, pt -online-schema-change , който работи по следния начин:
- Създайте нова таблица със същата структура като оригиналната.
- Актуализиране на схемата на нова таблица.
- Добавете тригер към оригиналната таблица, така че промените да се поддържат в синхрон с копието
- Копиране на редове в пакети от оригиналната таблица.
- Преместете оригиналната таблица настрани и я заменете с нова таблица.
- Изхвърлете старата маса.
Самият аз никога не съм опитвал инструмента. YMMV
RDS
В момента използвам MySQL чрез RDS на Amazon . Това е наистина страхотна услуга, която обгръща и управлява MySQL, като ви позволява да добавяте нови реплики за четене с един бутон и прозрачно да надграждате базата данни в хардуерни SKU. Наистина е удобно. Не получавате СУПЕР достъп до базата данни, така че не можете да прецакате с репликацията директно (това благословия ли е или проклятие?). Можете обаче да използвате Прочетете промоцията на реплика за да направите промени в схемата си на подчинен само за четене, след това повишете този подчинен да стане ваш нов господар. Точно същият трик, както описах по-горе, просто много по-лесен за изпълнение. Те все още не правят много, за да ви помогнат с прекъсването. Трябва да преконфигурирате и рестартирате приложението си.