Než se pokusíte provést jakékoli změny schématu v produkčních databázích, měli byste se ujistit, že máte pevný plán vrácení zpět; a že váš postup změny byl úspěšně otestován a ověřen v samostatném prostředí. Zároveň je vaší odpovědností zajistit, aby změna neměla žádný nebo nejmenší možný dopad přijatelný pro firmu. Rozhodně to není snadný úkol.
V tomto článku se podíváme na to, jak kontrolovaně provádět změny databáze na MySQL a MariaDB. Budeme mluvit o některých dobrých návycích ve vaší každodenní práci DBA. Zaměříme se na předběžné požadavky a úkoly během skutečných operací a problémů, se kterými se můžete potýkat, když řešíte změny schématu databáze. Budeme také mluvit o open source nástrojích, které vám mohou pomoci v tomto procesu.
Scénáře testování a vrácení
Záloha
Existuje mnoho způsobů, jak ztratit svá data. Selhání upgradu schématu je jedním z nich. Na rozdíl od kódu aplikace nemůžete vypustit svazek souborů a prohlásit, že nová verze byla úspěšně nasazena. Pro vrácení změn také nemůžete jen vrátit starší sadu souborů. Samozřejmě můžete spustit jiný SQL skript a databázi znovu změnit, ale existují případy, kdy jediným přesným způsobem, jak vrátit změny zpět, je obnovení celé databáze ze zálohy.
Co když si však nemůžete dovolit vrátit databázi na nejnovější zálohu nebo vaše okno údržby není dostatečně velké (s ohledem na výkon systému), takže před změnou nemůžete provést úplnou zálohu databáze?
Člověk může mít sofistikované, redundantní prostředí, ale pokud se data upravují jak v primárních, tak v pohotovostních umístěních, není s tím moc co dělat. Mnoho skriptů lze spustit pouze jednou nebo změny nelze vrátit zpět. Většina kódu změny SQL spadá do dvou skupin:
- Spustit jednou – nelze přidat stejný sloupec do tabulky dvakrát.
- Nelze vrátit zpět – jakmile sloupec vypustíte, zmizí. Svou databázi byste nepochybně mohli obnovit, ale není to právě návrat zpět.
Tento problém můžete řešit alespoň dvěma možnými způsoby. Jedním by bylo povolit binární protokol a vytvořit zálohu, která je kompatibilní s PITR. Taková záloha musí být úplná, úplná a konzistentní. Pro xtrabackup, pokud obsahuje úplnou datovou sadu, bude kompatibilní s PITR. Pro mysqldump existuje možnost, aby byl kompatibilní s PITR. Pro menší změny by varianta zálohování mysqldump spočívala v tom, že by bylo potřeba změnit pouze podmnožinu dat. To lze provést pomocí volby --where. Záloha by měla být součástí plánované údržby.
mysqldump -u -p --lock-all-tables --where="WHERE employee_id=100" mydb employees> backup_table_tmp_change_07132018.sql
Další možností je použít CREATE TABLE AS SELECT.
Můžete ukládat data nebo jednoduché změny struktury ve formě pevné dočasné tabulky. S tímto přístupem získáte zdroj, pokud potřebujete vrátit zpět své změny. Může to být docela užitečné, pokud neměníte mnoho dat. Návrat lze provést odebráním dat z něj. Pokud při kopírování dat do tabulky dojde k jakémukoli selhání, tabulka se automaticky zruší a nevytvoří, takže se ujistěte, že váš příkaz vytváří kopii, kterou potřebujete.
Samozřejmě existují i určitá omezení.
Protože pořadí řádků v podkladových příkazech SELECT nelze vždy určit, jsou CREATE TABLE ... IGNORE SELECT a CREATE TABLE ... REPLACE SELECT označeny jako nebezpečné pro replikaci založenou na příkazech. Takové příkazy vytvářejí varování v protokolu chyb při použití režimu založeného na příkazech a zapisují se do binárního protokolu pomocí formátu založeného na řádcích, když používáte režim MIXED.
Velmi jednoduchý příklad takové metody může být:
CREATE TABLE tmp_employees_change_07132018 AS SELECT * FROM employees where employee_id=100;
UPDATE employees SET salary=120000 WHERE employee_id=100;
COMMMIT;
Další zajímavou možností může být MariaDB flashback databáze. Když dojde k nesprávné aktualizaci nebo smazání a vy byste se chtěli v určitém okamžiku vrátit do stavu databáze (nebo jen tabulky), můžete použít funkci flashback.
Vrácení k určitému bodu v čase umožňuje správcům databází obnovit data rychleji vrácením transakcí do předchozího bodu v čase namísto provádění obnovy ze zálohy. Na základě událostí DML založených na ROW může flashback transformovat binární protokol a reverzní účely. To znamená, že může pomoci rychle vrátit dané změny řádků. Například může změnit události DELETE na INSERTs a naopak a zaměnit části událostí UPDATE WHERE a SET. Tento jednoduchý nápad může výrazně urychlit zotavení z určitých typů chyb nebo katastrof. Pro ty, kteří znají databázi Oracle, je to dobře známá funkce. Omezením MariaDB flashback je nedostatek podpory DDL.
Vytvořte zpožděnou replikaci Slave
Od verze 5.6 MySQL podporuje zpožděnou replikaci. Podřízený server může za hlavním serverem zaostávat alespoň o určitou dobu. Výchozí zpoždění je 0 sekund. Pomocí možnosti MASTER_DELAY pro CHANGE MASTER TO nastavte zpoždění na N sekund:
CHANGE MASTER TO MASTER_DELAY = N;
Byla by to dobrá volba, pokud jste neměli čas připravit si správný scénář obnovy. Musíte mít dostatečné zpoždění, abyste si všimli problematické změny. Výhodou tohoto přístupu je, že nemusíte obnovovat databázi, abyste z ní odebrali data potřebná k opravě změny. Pohotovostní databáze je v provozu a připravena na sběr dat, což minimalizuje potřebný čas.
Vytvořte asynchronní slave zařízení, které není součástí clusteru
Pokud jde o cluster Galera, testování změn není snadné. Všechny uzly provozují stejná data a velké zatížení může narušit řízení toku. Musíte tedy nejen zkontrolovat, zda byly změny úspěšně aplikovány, ale také jaký byl dopad na stav clusteru. Chcete-li, aby se vaše testovací procedura co nejvíce přiblížila produkční zátěži, možná budete chtít přidat asynchronní slave do vašeho clusteru a spustit test tam. Test neovlivní synchronizaci mezi uzly clusteru, protože technicky není součástí clusteru, ale budete mít možnost to zkontrolovat se skutečnými daty. Takový slave lze snadno přidat z ClusterControl.
ClusterControl přidat asynchronní slaveJak je znázorněno na výše uvedeném snímku obrazovky, ClusterControl může automatizovat proces přidávání asynchronního slave zařízení několika způsoby. Můžete přidat uzel do clusteru, zpozdit slave. Chcete-li snížit dopad na hlavní jednotku, můžete při sestavování podřízené jednotky jako zdroj dat použít namísto hlavní zálohy existující zálohu.
Klonování databáze a měření času
Dobrý test by měl být co nejblíže změně výroby. Nejlepší způsob, jak toho dosáhnout, je naklonovat stávající prostředí.
ClusterControl Clone Cluster pro testProvádět změny prostřednictvím replikace
Chcete-li mít nad svými změnami lepší kontrolu, můžete je předem použít na podřízeném serveru a poté provést přepnutí. U replikace založené na příkazech to funguje dobře, ale u replikace založené na řádcích to může do určité míry fungovat. Replikace založená na řádcích umožňuje, aby na konci tabulky existovaly další sloupce, takže pokud umí zapisovat první sloupce, bude to v pořádku. Nejprve aplikujte toto nastavení na všechny podřízené jednotky, potom přepnutí při selhání na jednoho z podřízených a poté implementujte změnu na nadřízenou jednotku a připojte ji jako podřízenou. Pokud vaše úprava zahrnuje vložení nebo odebrání sloupce uprostřed tabulky, bude fungovat s replikací založenou na řádcích.
Provoz
Během období údržby nechceme mít aplikační provoz na databázi. Někdy je těžké vypnout všechny aplikace v celé společnosti. Případně chceme povolit vzdálený přístup k MySQL pouze některým konkrétním hostitelům (například monitorovací systém nebo záložní server). K tomuto účelu můžeme využít linuxové filtrování paketů. Chcete-li zjistit, jaká pravidla filtrování paketů jsou k dispozici, můžeme spustit následující příkaz:
iptables -L INPUT -v
Chcete-li uzavřít port MySQL na všech rozhraních, která používáme:
iptables -A INPUT -p tcp --dport mysql -j DROP
a znovu otevřít port MySQL po okně údržby:
iptables -D INPUT -p tcp --dport mysql -j DROP
Pro uživatele bez přístupu root můžete změnit max_connection na 1 nebo 'přeskočit síť'.
Protokolování
Chcete-li zahájit proces protokolování, použijte příkaz tee v příkazovém řádku klienta MySQL, například takto:
mysql> tee /tmp/my.out;
Tento příkaz říká MySQL, aby zaprotokolovala vstup i výstup vaší aktuální relace přihlášení k MySQL do souboru s názvem /tmp/my.out. Poté spusťte soubor skriptu se zdrojovým příkazem.
Chcete-li získat lepší představu o době provádění, můžete jej zkombinovat s funkcí profilování. Spusťte profilovač pomocí
SET profiling = 1;
Poté spusťte dotaz pomocí
SHOW PROFILES;
zobrazí se seznam dotazů, pro které má profiler statistiky. Nakonec si tedy vyberete, který dotaz se má zkoumat
SHOW PROFILE FOR QUERY 1;
Nástroje pro migraci schémat
Mnohokrát není přímý ALTER na masteru možný - ve většině případů způsobuje zpoždění na slave, a to nemusí být přijatelné pro aplikace. Co však lze udělat, je provést změnu v rolovacím režimu. Můžete začít s otroky, a jakmile je změna aplikována na slave, migrovat jednoho z slave jako nového master, degradovat starého mastera na slave a provést na něm změnu.
Nástroj, který může pomoci s takovým úkolem, je Percona pt-online-schema-change. Pt-online-schema-change je přímočará - vytvoří dočasnou tabulku s požadovaným novým schématem (například pokud jsme přidali index nebo odstranili sloupec z tabulky). Poté vytvoří spouštěče na staré tabulce. Tyto spouštěče jsou zde proto, aby zrcadlily změny, ke kterým došlo v původní tabulce, do nové tabulky. Změny se zrcadlí během procesu změny schématu. Pokud se do původní tabulky přidá řádek, přidá se také do nové. Napodobuje způsob, jakým MySQL interně upravuje tabulky, ale funguje na kopii tabulky, kterou chcete změnit. Znamená to, že původní tabulka není uzamčena a klienti v ní mohou nadále číst a měnit data.
Podobně, pokud je upraven nebo odstraněn řádek ve staré tabulce, použije se také v nové tabulce. Poté začne proces kopírování dat na pozadí (pomocí LOW_PRIORITY INSERT) mezi starou a novou tabulkou. Po zkopírování dat se provede RENAME TABLE.
Dalším zajímavým nástrojem je gh-ost. Gh-ost vytvoří dočasnou tabulku se změněným schématem, stejně jako pt-online-schema-change. Provádí dotazy INSERT, které používají následující vzor ke kopírování dat ze staré do nové tabulky. Přesto nepoužívá spouštěče. Bohužel spouštěče mohou být zdrojem mnoha omezení. gh-ost používá binární protokol k zachycení změn v tabulce a asynchronně je aplikuje na tabulku duchů. Jakmile ověříme, že gh-ost dokáže správně provést naši změnu schématu, je čas ji skutečně provést. Mějte na paměti, že možná budete muset ručně odstranit staré tabulky, které vytvořil gh-ost během procesu testování migrace. Můžete také použít příznaky --initily-drop-ghost-table a --initily-drop-old-table a požádat gh-ost, aby to udělal za vás. Poslední příkaz k provedení je přesně stejný, jaký jsme použili k testování naší změny, jen jsme k němu přidali --execute.
pt-online-schema-change a gh-ost jsou mezi uživateli Galery velmi oblíbené. Nicméně Galera má některé další možnosti. Dvě metody Total Order Isolation (TOI) a Rolling Schema Upgrade (RSU) mají své klady i zápory.
TOI – Toto je výchozí metoda replikace DDL. Uzel, který vytváří sadu zápisů, detekuje DDL v době analýzy a odešle událost replikace pro příkaz SQL ještě před zahájením zpracování DDL. Upgrady schématu se spouštějí na všech uzlech clusteru ve stejné celkové pořadí pořadí, což zabraňuje potvrzení dalších transakcí po dobu trvání operace. Tato metoda je dobrá, když chcete, aby se vaše online upgrady schématu replikovaly prostřednictvím clusteru, a nevadí vám zamknout celou tabulku (podobně jako ke změnám výchozího schématu došlo v MySQL).
SET GLOBAL wsrep_OSU_method='TOI';
RSU - provádějte aktualizace schématu lokálně. V této metodě vaše zápisy ovlivňují pouze uzel, na kterém jsou spuštěny. Změny se nereplikují do zbytku klastru. Tato metoda je vhodná pro nekonfliktní operace a klastr nezpomalí.
SET GLOBAL wsrep_OSU_method='RSU';
Zatímco uzel zpracovává upgrade schématu, desynchronizuje se s clusterem. Když dokončí zpracování upgradu schématu, použije události zpožděné replikace a synchronizuje se s clusterem. To by mohla být dobrá volba pro spouštění náročných vytváření indexů.
Závěr
Představili jsme zde několik různých metod, které vám mohou pomoci s plánováním změn schématu. Vše samozřejmě závisí na vaší aplikaci a obchodních požadavcích. Můžete navrhnout svůj plán změn, provést potřebné testy, ale stále existuje malá šance, že se něco pokazí. Podle Murphyho zákona – „věci se pokazí v jakékoli dané situaci, pokud jim dáte šanci“. Ujistěte se tedy, že vyzkoušíte různé způsoby provádění těchto změn a vyberte si ten, který vám bude nejvíce vyhovovat.