Zaznamenali jste pomalé spouštění MySQL v režimu GTID? Nedávno jsme narazili na tento problém v jednom z našich hostingových nasazení MySQL a rozhodli jsme se problém vyřešit. V tomto blogu rozebereme problém, který by mohl zpomalovat časy restartování MySQL, jak ladit pro vaši implementaci a co můžete udělat, abyste zkrátili čas zahájení a zlepšili své porozumění replikaci založené na GTID.
Jak jsme problém našli
Zkoumali jsme pomalé spouštění MySQL na diskovém nasazení MySQL 5.7.21 nižší třídy, které mělo povolený režim GTID. Systém byl součástí dvojice master-slave a byl pod mírným zápisem. Při restartování během plánované údržby jsme si všimli, že databázovému serveru trvalo 5–10 minut, než se spustil a začal přijímat připojení. Takové zpoždění nedávalo smysl, a tak jsme se to vydali prozkoumat.
Ladění pomalého startovacího času MySQL
Použili jsme populární nástroj Percona pt-ioprofile, abychom viděli, co databáze dělá. pt-ioprofile je velmi důležitý nástroj v oblíbené sadě nástrojů Percona, který se používá k ladění problémů s MySQL, a úplný seznam funkcí můžete vidět v jejich dokumentaci. pt-ioprofile nástroj používá strace a lsof ke sledování I/O procesu a vytištění tabulky souborů a I/O aktivity.
Takže jsme spustili MySQL a čekali na mysqld proces, aby se vytvořil, a začal pt-ioprofile abyste zjistili, v čem může být problém:
Co zpomaluje restart vašeho MySQL?
Při opakovaném spuštění jsme zaznamenali následující:
- mysqld proces trávil většinu času čtením nejnovějšího binárního souboru protokolu. Bylo tomu tak i v případě, kdy byl server řádně zastaven a nebylo nutné obnovení po havárii atd.
- Server také strávil značné množství času načítáním datových souborů InnoDB, ale tato doba byla mnohem kratší ve srovnání s dobou strávenou čtením nejnovějšího binárního souboru protokolu.
- Pokud by byl server okamžitě znovu restartován, bylo by toto následné restartování mnohem rychlejší.
- Protože vypnutí databáze vyprázdní binární protokol a vytvoří nový při spuštění, provedli jsme další experiment – před vypnutím serveru jsme binární protokoly vyprázdnili. Následný start serveru byl opět rychlý.
Tato pozorování jasně poukázala na skutečnost, že MySQL trávilo spoustu času čtením nejnovějšího binárního souboru protokolu. Pokud byl soubor malý, jako když byl soubor protokolu vyprázdněn před vypnutím, spouštění bylo rychlé.
Pomalý start MySQL v GTID? Problémem může být velikost vašeho binárního souboru protokolu Kliknutím na tweet
Pochopení obnovení GTID Binlog
Jak se ukázalo, k naplnění hodnot gtid_executed a gtid_purged musí server MySQL analyzovat binární soubory protokolu.
Zde je shrnutí doporučení metod dokumentace MySQL 5.7 na základě NEPRAVDIVÉHO nebo PRAVDIVÉHO čtení:
Když binlog_gtid_simple_recovery =FALSE:
Výpočet gtid_executed:
- Iterujte binární soubory protokolu od nejnovějších a zastavte se u prvního souboru, který má Previous_gtids_log_event vstup.
- Použijte všechna GTID z Previous_gtids_log_event a Gtid_log_events z tohoto binárního souboru protokolu a interně uložit tuto sadu GTID. Označuje se jako gtids_in_binlog.
- Hodnota gtid_executed se vypočítá jako spojení gtids_in_binlog a GTID v tabulce mysql.gtid_executed .
Tento proces může být velmi časově náročný, pokud existuje velké množství binárních souborů protokolu bez GTID, například vytvořených při gtid_mode =VYPNUTO.
Podobně pro výpočet gtid_purged:
- Iterujte binární soubory protokolu od nejstaršího po nejnovější a zastavte se u prvního binárního protokolu, který obsahuje buď neprázdnou událost Previous_gtids_log_event (má alespoň jedno GTID) nebo má alespoň jednu Gtid_log_event .
- Přečíst Previous_gtids_log_event z tohoto souboru. Vypočítejte interní proměnnou gtids_in_binlog_not_purged jak tato sada GTID odečtena od gtids_in_binlog.
- Hodnota gtid_purged je nastaven na gtid_executed , mínus gtids_in_binlog_not_purged .
Toto tvoří základ našeho chápání toho, jak věci fungovaly ve starších verzích. Určité optimalizace však lze provést, když binlog_gtid_simple_recovery je pravda. Toto je případ, který nás zajímá:
Když binlog_gtid_simple_recovery =TRUE:
(Poznámka, toto je výchozí nastavení v MySQL 5.7.7 a novějších)
- Přečtěte si pouze nejstarší a nejnovější binární soubory protokolu.
- Vypočítejte gtid_purged z Previous_gtids_log_event nebo Gtid_log_event nalezen v nejstarším binárním souboru protokolu.
- Vypočítat gtid_executed z Previous_gtids_log_event nebo Gtid_log_event nalezen v nejnovějším binárním souboru protokolu.
- Takže pouze dva binární soubory protokolu jsou čteny během restartování serveru nebo při čištění binárních protokolů.
Takže pro MySQL verze 5.7.7 a vyšší se vždy při spouštění systému načtou nejnovější a staré binární soubory protokolu, aby se správně inicializovaly systémové proměnné GTID. Čtení nejstaršího binárního souboru protokolu není tak drahé, protože událost, kterou MySQL hledá, Previous_gtids_log_event, je vždy první událostí v binárním souboru protokolu.
Aby však bylo možné správně vypočítat gtid_executed , musí server přečíst celý nejnovější binární soubor protokolu a shromáždit všechny události v tomto souboru. Doba spuštění systému se tak stane přímo úměrnou velikosti nejnovějšího binárního souboru protokolu .
Všimněte si, že situace je ještě horší, když binlog_gtid_simple_recovery je NEPRAVDA . Vzhledem k tomu, že již není výchozí možností v posledních verzích, není to příliš znepokojující.
Jak vyřešit svůj pomalý začátek
Když jsme pochopili příčinu problému, na který jsme narazili, řešení, pro které jsme se rozhodli, bylo celkem zřejmé – zmenšete velikost souborů binárních protokolů. Výchozí velikost souborů binárního protokolu je 1 GB. Analýza souboru této velikosti během spouštění nějakou dobu trvá, takže má smysl snížit hodnotu max_binlog_size na nižší hodnotu.
Pokud zmenšení velikosti souboru binárního protokolu není možné, může vám pomoci vyprázdnění souborů binárního protokolu těsně před ukončením údržby procesu mysqld ke zkrácení doby obnovy GTID z binlogu.