Mysql
 sql >> база данни >  >> RDS >> Mysql

Създайте индекс на огромна таблица за производство на MySQL без заключване на таблицата

[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
  • Введете 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. Наистина е удобно. Не получавате СУПЕР достъп до базата данни, така че не можете да прецакате с репликацията директно (това благословия ли е или проклятие?). Можете обаче да използвате Прочетете промоцията на реплика за да направите промени в схемата си на подчинен само за четене, след това повишете този подчинен да стане ваш нов господар. Точно същият трик, както описах по-горе, просто много по-лесен за изпълнение. Те все още не правят много, за да ви помогнат с прекъсването. Трябва да преконфигурирате и рестартирате приложението си.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как работи функцията RTRIM() в MySQL

  2. Грешка при преименуването на колона в MySQL

  3. mysql - създаване на механизъм, подобен на последователностите на Oracle

  4. Как да изтрия всички дублиращи се записи в MySQL таблица без временни таблици

  5. MySQL Премахване на дублиращи се записи