Нека си представим следната ситуация: имаме голям проект с таблица 'actions' която има над 50 000 000 редове. В нея постоянно влизат средно по 3-5 реда в секунда. Налагани се да добавим нова колонка в нея. Ако го направим по класическия начин като изпълним ALTER TABLE заявка, таблицата ще бъде заключена докато не се изпълни (а тя няма да се изпълни бързо). За да избегнем този "downtime" ще трябва да използваме tool за online schema migration.
Сега ще ви покажа как да използвате един от най-известните pt-online-schema-change. Инсталира се на linux. В моя случай ползвам Debian 10. Линк за теглене: https://www.percona.com/downloads/percona-toolkit/LATEST/
Ще опиша най-общо какво прави при редакция на таблица:
- Създава подобна таблица със име "_actions_new";
- Изпълнява ALTER заявката на новата таблица;
- Създава TRIGGERS на оригиналната таблица (actions), които при промяна на данните в оригиналта таблица ги прилага в новата (_actions_new);
- Копира данните от оригиналта таблица (actions) в новата (_actions_new);
- Разменя новата таблица (_actions_new) със старата (actions);
- Изтрива създадените TRIGGERS.
Това е примерна команда за добаваня на нова колонка с foreign key:
pt-online-schema-change D=mydatabasename,t=actions,h=localhost,u=root --alter="ADD COLUMN \`managerID\` INT NULL AFTER \`email\`, ADD FOREIGN KEY (\`managerID\`) REFERENCES \`mydatabasename\`.\`managers\` (\`ID\`) ON UPDATE CASCADE ON DELETE CASCADE;" --alter-foreign-keys-method=drop_swap --ask-pass --execute
Сега ще обясня накрадко коя команда за какво е:
- D=mydatabasename,t=actions,h=localhost,u=root - тук посочваме DSN (Data source name). По-просто казано "връзката с базата" и посочваме коя таблица ще редактираме;
- --alter - тук е самата заявка която модифицира таблицата. Всичко след "ALTER TABLE". Този символ "`" трябва да бъде escape-нат "\`". Важно е да се отбележи, че има лимитации, какви заявки могад да бъдат изпълнени. Задължително трябва да ги погледнете ТУК;
- --alter-foreign-keys-method - тази опция има следните стойности auto, rebuild_constraints, drop_swap, none.
- "auto" - ако е възможно се използва "rebuild_constraints", в противен случай се ползва "drop_swap".
- "rebuild_constraints" - тази опция използва "ALTER TABLE" за да изтрие и добави всички "foreign keys" на всички таблици които имат връзка към редактираната таблица (actions). Това е препоръчителния метод за редакция, когато таблиците които имат връзка към редактираната таблица (actions) не са прекалено големи. Ако са прекалено големи ще отнеме дълго време да се изтрият и създадат "foreign keys" и ще има "downtime".
- "drop_swap" - тази опция деактивира "foreign key checks" (FOREIGN_KEY_CHECKS=0), след което изтрива оригиналта таблица и преименова новата таблица на мястото на старата. Този метод е много бърз, но име два проблема. Първия е, че по време на преименуването на новата таблица, за кратко време заявките които търсят таблицата ще върнат грешка от рода "Table 'actions' doesn't exist". Втория проблем е, че ако се провали преименуването на новата таблица, операцията е необратима, защото старата таблица вече е изтрита.
- "none" - тази опция е същата като "drop_swap", без преименуването на новата таблица и изтриването на старата.
- --ask-pass - подканва ви да въведете парола за достъп до базата.
- --execute - тази опция позволява да се изпълни редакцията на таблицата. Без тази опция само ще се направят някои проверки (като --dry-run). Препоръчвам ви първо да изпълните командата без --execute. Ако всички проверки минат успешно, тогава я изпълните със.
Това са основните опции които трябва да за направите редакция. Препоръчвам да погледнете и останалите опции, преди да правите редакция на live база.