Nastavení replikace v MySQL je snadné, ale její správa v produkci nikdy nebyla snadným úkolem. I s novějším automatickým určováním polohy GTID se to stále může pokazit, pokud nevíte, co děláte. Po nastavení replikace se může pokazit celá řada věcí. Chyby lze snadno udělat a mohou mít pro vaše data katastrofální konec.
Tento příspěvek upozorní na některé z nejčastějších chyb při replikaci MySQL a na to, jak jim můžete předejít.
Nastavení replikace
Při nastavování replikace MySQL je třeba připravit podřízené uzly datovou sadou z hlavního serveru. S řešeními, jako je cluster Galera, je to automaticky řešeno za vás metodou podle vašeho výběru. Pro replikaci MySQL to musíte udělat sami, takže si přirozeně vezmete svůj standardní zálohovací nástroj.
Pro MySQL je k dispozici široká škála nástrojů pro zálohování, ale nejběžněji používaným je mysqldump. Mysqldump vytváří logickou zálohu datové sady vašeho hlavního serveru. To znamená, že kopie dat nebude binární kopií, ale velkým souborem obsahujícím dotazy k opětovnému vytvoření vaší datové sady. Ve většině případů by vám to mělo poskytnout (téměř) identickou kopii vašich dat, ale existují případy, kdy se tak nestane – kvůli výpisu stavu paměti pro jednotlivé objekty. To znamená, že ještě předtím, než začnete replikovat data, vaše datová sada není stejná jako ta na hlavní.
Existuje několik vylepšení, která můžete udělat, aby byl mysqldump spolehlivější jako výpis jako jediná transakce, a také nezapomeňte zahrnout rutiny a spouštěče:
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > dumpfile.sql
Osvědčeným postupem je zkontrolovat, zda je váš podřízený uzel 100% stejný, pomocí pt-table-checksum po nastavení replikace:
pt-table-checksum --replicate=test.checksums --ignore-databases mysql h=localhost,u=user,p=pass
Tento nástroj vypočítá kontrolní součet pro každou tabulku na masteru, replikuje příkaz na slave a pak slave uzel provede stejnou operaci kontrolního součtu. Pokud některá z tabulek není stejná, mělo by to být jasně viditelné v tabulce kontrolního součtu.
Použití nesprávné metody replikace
Výchozí replikační metodou MySQL byla tzv. replikace založená na příkazech. Tato metoda je přesně tím, čím je:replikační proud každého příkazu spuštěného na hlavním uzlu, který bude přehrán na podřízeném uzlu. Protože samotná MySQL je vícevláknová, ale její (tradiční) replikace nikoli, pořadí příkazů v replikačním proudu nemusí být 100% stejné. Také přehrání příkazu může poskytnout jiné výsledky, pokud není provedeno přesně ve stejnou dobu.
To může mít za následek rozdílné datové sady mezi master a slave v důsledku datového driftu. To nebyl problém po mnoho let, protože málokdo provozoval MySQL s mnoha simultánními vlákny, ale s moderní architekturou s více CPU se to ve skutečnosti stalo vysoce pravděpodobné při běžné každodenní zátěži.
Odpověď z MySQL byla takzvaná replikace založená na řádcích. Řádková replikace bude replikovat data, kdykoli je to možné, ale v některých výjimečných případech stále používá příkazy. Dobrým příkladem by byla změna knihovny DLL tabulky, kde by replikace musela zkopírovat každý řádek v tabulce prostřednictvím replikace. Protože je to neefektivní, bude takové prohlášení replikováno tradičním způsobem. Když řádková replikace detekuje posun dat, zastaví podřízené vlákno, aby se situace nezhoršila.
Pak existuje metoda mezi těmito dvěma:replikace ve smíšeném režimu. Tento typ replikace bude vždy replikovat příkazy, kromě případů, kdy dotaz obsahuje funkci UUID(), spouštěče, uložené procedury, UDF a několik dalších výjimek. Smíšený režim nevyřeší problém posunu dat a spolu s replikací založenou na příkazech je třeba se mu vyhnout.
Kruhová replikace
Spuštění replikace MySQL s multimasterem je často nezbytné, pokud máte prostředí s více datovými centry. Protože aplikace nemůže čekat, až hlavní server v jiném datovém centru potvrdí váš zápis, dává se přednost místnímu hlavnímu serveru. Normálně se offset automatického přírůstku používá, aby se zabránilo kolizím dat mezi mastery. To, že dva mastery provádějí zápisy do sebe tímto způsobem, je široce přijímané řešení.
MySQL Master-Master replikacePokud však potřebujete zapisovat do více datových center do stejné databáze, skončíte s několika mastery, kteří si musí svá data zapsat jeden do druhého. Před MySQL 5.7.6 neexistovala žádná metoda pro provedení replikace typu mesh, takže alternativou by bylo použít místo toho kruhovou replikaci.
Topologie kruhové replikace MySQLReplikace ringu v MySQL je problematická z následujících důvodů:latence, vysoká dostupnost a posun dat. Zapsání některých dat na server A by trvalo tři přeskoky, než by skončilo na serveru D (přes server B a C). Protože (tradiční) replikace MySQL je jednovláknová, jakýkoli dlouho běžící dotaz v replikaci může zastavit celý kruh. Pokud by některý ze serverů selhal, kruh by se porouchal a v současné době neexistuje žádný software pro převzetí služeb při selhání, který by dokázal opravit kruhové struktury. Pak může dojít k posunu dat, když jsou data zapsána na server A a zároveň jsou změněna na serveru C nebo D.
Replikace přerušeného kruhuObecně se kruhová replikace nehodí k MySQL a je třeba se jí za každou cenu vyhnout. Galera by byla dobrou alternativou pro zápisy ve více datacentrech, protože byla navržena s ohledem na to.
Zastavení replikace pomocí velkých aktualizací
Různé dávkové úlohy údržby často provedou různé úkoly, od čištění starých dat až po výpočet průměrů „lajků“ získaných z jiného zdroje. To znamená, že v nastavených intervalech bude úloha vytvářet velké množství databázových aktivit a s největší pravděpodobností zapíše do databáze mnoho dat. Přirozeně to znamená, že aktivita v rámci replikačního proudu se stejně zvýší.
Replikace založená na příkazech bude replikovat přesné dotazy používané v dávkových úlohách, takže pokud zpracování dotazu na hlavním serveru trvalo půl hodiny, podřízené vlákno bude zastaveno alespoň na stejnou dobu. To znamená, že žádná další data se nemohou replikovat a podřízené uzly začnou zaostávat za masterem. Pokud to překročí práh vašeho nástroje pro přepnutí při selhání nebo proxy, může tyto podřízené uzly vyřadit z dostupných uzlů v klastru. Používáte-li replikaci založenou na příkazech, můžete tomu zabránit tím, že budete data pro vaši úlohu zpracovávat v menších dávkách.
Nyní si můžete myslet, že replikace založená na řádcích není tímto ovlivněna, protože replikuje informace o řádcích namísto dotazu. To je částečně pravda, protože u změn DDL se replikace vrátí zpět do formátu založeného na příkazech. Také velký počet operací CRUD ovlivní tok replikace:ve většině případů se stále jedná o operaci s jedním vláknem, a proto každá transakce bude čekat na přehrání předchozí prostřednictvím replikace. To znamená, že pokud máte vysokou souběžnost na masteru, slave se může zastavit kvůli přetížení transakcí během replikace.
Abychom to obešli, nabízí MariaDB i MySQL paralelní replikaci. Implementace se může lišit podle dodavatele a verze. MySQL 5.6 nabízí paralelní replikaci, pokud jsou dotazy odděleny schématem. MariaDB 10.0 a MySQL 5.7 zvládnou paralelní replikaci napříč schématy, ale mají jiné hranice. Provádění dotazů prostřednictvím paralelních podřízených vláken může urychlit váš replikační proud, pokud máte náročný zápis. Pokud však nejste, bylo by nejlepší držet se tradiční replikace s jedním vláknem.
Změny schématu
Provádění změn schématu na běžícím produkčním nastavení je vždy utrpení. Souvisí to se skutečností, že změna DDL většinu času uzamkne tabulku a uvolní tento zámek až po použití změny DDL. Ještě se to zhorší, jakmile začnete tyto změny DDL replikovat prostřednictvím replikace MySQL, kde to navíc zastaví replikační stream.
Často používaným řešením je nejprve použít změnu schématu na podřízené uzly. Pro replikaci založenou na příkazech to funguje dobře, ale pro replikaci založenou 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 je schopna zapsat první sloupce, bude to v pořádku. Nejprve aplikujte změnu na všechny podřízené jednotky, poté přepnutí při selhání na jednoho z podřízených a poté aplikujte změnu na nadřízenou jednotku a připojte ji jako podřízenou. Pokud vaše změna zahrnuje vložení sloupce doprostřed nebo odstranění sloupce, bude to fungovat s replikací založenou na řádcích.
V okolí jsou nástroje, které dokážou provádět změny online schémat spolehlivěji. Percona Online Schema Change (známá jako pt-osc) vytvoří stínovou tabulku s novou strukturou tabulky, vloží nová data pomocí spouštěčů a vyplní data na pozadí. Jakmile vytvoříte novou tabulku, jednoduše vymění starou tabulku za novou v rámci transakce. Toto nefunguje ve všech případech, zvláště pokud vaše stávající tabulka již spouštěcí prvky má.
Alternativou je nový nástroj Gh-ost od Github. Tento online nástroj pro změnu schématu nejprve vytvoří kopii vašeho stávajícího rozvržení tabulky, upraví tabulku na nové rozvržení a poté zapojí proces jako repliku MySQL. Využije replikační proud k vyhledání nových řádků, které byly vloženy do původní tabulky a zároveň tabulku zaplní. Po dokončení zásypu se původní a nové tabulky prohodí. Přirozeně všechny operace do nové tabulky skončí také v replikačním proudu, takže u každé repliky proběhne migrace současně.
Tabulky paměti a replikace
Když už jsme u DDL, častým problémem je vytváření paměťových tabulek. Paměťové tabulky jsou neperzistentní tabulky, jejich struktura tabulek zůstává, ale po restartu MySQL ztrácejí svá data. Při vytváření nové paměťové tabulky na masteru i slave budou mít oba prázdnou tabulku a to bude fungovat naprosto v pořádku. Jakmile se kterýkoli z nich restartuje, tabulka se vyprázdní a dojde k chybám replikace.
Replikace založená na řádcích se přeruší, jakmile data v podřízeném uzlu vrátí jiné výsledky, a replikace založená na příkazech se přeruší, jakmile se pokusí vložit data, která již existují. U paměťových tabulek je to častý nástroj pro přerušení replikace. Oprava je snadná:jednoduše vytvořte novou kopii dat, změňte engine na InnoDB a nyní by měla být replikace bezpečná.
Nastavení proměnné pouze pro čtení na hodnotu True
Jak jsme popsali dříve, nemít stejná data v podřízených uzlech může přerušit replikaci. Často to bylo způsobeno tím, že něco (nebo někdo) změnilo data na podřízeném uzlu, ale ne na hlavním uzlu. Jakmile se data hlavního uzlu změní, budou replikována do podřízeného, kde nemůže změnu použít, což způsobí přerušení replikace.
Existuje jednoduchá prevence:nastavení proměnné read_only na hodnotu true. To znemožní komukoli provádět změny v datech, kromě uživatelů replikace a root. Většina správců převzetí služeb při selhání nastavuje tento příznak automaticky, aby zabránili uživatelům zapisovat do použitého hlavního serveru během převzetí služeb při selhání. Některé z nich si to zachovají i po převzetí služeb při selhání.
To stále nechává uživatele root provést chybný dotaz CRUD na podřízeném uzlu. Aby se tomu zabránilo, od MySQL 5.7.8 existuje proměnná super_read_only, která dokonce zablokuje uživatele root v aktualizaci dat.
Povolení GTID
Při replikaci MySQL je nezbytné spustit slave ze správné pozice v binárních protokolech. Získání této pozice lze provést při vytváření zálohy (podporuje to xtrabackup a mysqldump) nebo když jste přestali slavit na uzlu, ze kterého vytváříte kopii. Spuštění replikace pomocí příkazu CHANGE MASTER TO by vypadalo takto:
mysql> CHANGE MASTER TO MASTER_HOST='x.x.x.x',MASTER_USER='replication_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='master-bin.0001', MASTER_LOG_POS= 04;
Spuštění replikace na nesprávném místě může mít katastrofální následky:data mohou být zapsána dvakrát nebo nebudou aktualizována. To způsobí posun dat mezi nadřízeným a podřízeným uzlem.
Také při selhání z masteru na slave je třeba najít správnou pozici a změnit master na vhodného hostitele. MySQL neuchovává binární protokoly a pozice ze svého hlavního serveru, ale spíše vytváří své vlastní binární protokoly a pozice. Při opětovném zarovnání podřízeného uzlu k novému masteru se to může stát vážným problémem:na novém masteru musí být nalezena přesná pozice masteru při převzetí služeb při selhání a poté mohou být všechny slave zařízení znovu zarovnány.
Aby se tento problém vyřešil, společnost Oracle i MariaDB implementovala Global Transaction Identifier (GTID). GTID umožňují automatické zarovnání otroků a v MySQL i MariaDB server sám zjistí, jaká je správná pozice. Oba však implementovali GTID jiným způsobem, a proto jsou nekompatibilní. Pokud potřebujete nastavit replikaci z jednoho do druhého, měla by být replikace nastavena pomocí tradičního umístění binárního protokolu. Také váš software pro převzetí služeb při selhání by měl být upozorněn, aby nepoužíval GTID.
Závěr
Doufáme, že jsme vám poskytli dostatek tipů, jak se vyhnout problémům. To vše jsou běžné postupy odborníků na MySQL. Museli se to naučit tvrdě a s těmito tipy zajistíme, že vy to nebudete muset.
Máme pro vás několik dalších bílých knih, které mohou být užitečné, pokud si chcete přečíst více o replikaci MySQL.
Související whitepapers MySQL Replication Blueprint Whitepaper MySQL Replication Blueprint zahrnuje všechny aspekty topologie replikace s výhodami a nevýhodami nasazení, nastavení replikace, monitorování, upgrady, provádění zálohování a správa vysoké dostupnosti pomocí serverů proxy.Stáhněte si Replikaci MySQL pro vysokou dostupnostTento výukový program obsahuje informace o replikaci MySQL s informacemi o nejnovějších funkcích představených ve verzích 5.6 a 5.7. K dispozici je také praktická a praktická část o tom, jak rychle nasadit a spravovat nastavení replikace pomocí ClusterControl.Download