Aktualizace MySQL (Percona Server) z 5.7 na 8.0

Aktualizace MySQL (Percona Server) z 5.7 na 8.0

Pokrok se nezastaví, takže důvody pro upgrade na nejnovější verze MySQL jsou stále přesvědčivější. Nedávno byl v jednom z našich projektů čas aktualizovat útulné clustery Percona Server 5.7 na verzi 8. To vše se odehrálo na platformě Ubuntu Linux 16.04. Jak provést takovou operaci s minimálními prostoji a s jakými problémy jsme se během aktualizace setkali - přečtěte si tento článek.

Trénink

Jakákoli aktualizace databázového serveru je s největší pravděpodobností spojena s rekonfigurací databáze: změny v požadavcích na omezení systémových prostředků a oprava databázových konfigurací, které je třeba vyčistit od zastaralých direktiv.

Před aktualizací se určitě odkážeme na oficiální dokumentaci:

A pojďme sestavit akční plán:

  1. Opravte konfigurační soubory odstraněním zastaralých direktiv.
  2. Zkontrolujte kompatibilitu s nástroji.
  3. Aktualizujte podřízené databáze instalací balíčku percona-server-server.
  4. Aktualizujte master se stejným balíčkem.

Podívejme se na každý bod plánu a uvidíme, co by se mohlo pokazit.

POZOR! Postup aktualizace clusteru MySQL založeného na Galeře má své vlastní jemnosti, které nejsou popsány v článku. V tomto případě byste tento návod neměli používat.

Část 1: Kontrola konfigurací

MySQL byl odstraněn ve verzi 8 query_cache. Ve skutečnosti byl prohlášeno za zastaralé zpět ve verzi 5.7, ale nyní zcela smazáno. V souladu s tím je nutné odstranit související směrnice. A k ukládání požadavků do mezipaměti můžete nyní používat externí nástroje – např. ProxySQL.

Také v konfiguraci byly zastaralé směrnice o innodb_file_format. Pokud v MySQL 5.7 bylo možné vybrat formát InnoDB, pak již funguje 8. verze pouze s formátem Barracuda.

Naším výsledkem je odstranění následujících směrnic:

  • query_cache_type, query_cache_limit и query_cache_size;
  • innodb_file_format и innodb_file_format_max.

Pro kontrolu použijeme Docker image Percona Serveru. Do adresáře umístíme konfiguraci serveru mysql_config_test, a vedle něj vytvoříme adresáře pro data a logy. Příklad testu konfigurace serveru Percona:

mkdir -p {mysql_config_test,mysql_data,mysql_logs}
cp -r /etc/mysql/conf.d/* mysql_config_test/
docker run  --name some-percona -v $(pwd)/mysql_config_test:/etc/my.cnf.d/  -v $(pwd)/mysql_data/:/var/lib/mysql/ -v $(pwd)/mysql_logs/:/var/log/mysql/ -e MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD} -d percona:8-centos

Sečteno a podtrženo: buď v protokolech Dockeru nebo v adresáři s protokoly – v závislosti na vašich konfiguracích – se objeví soubor, ve kterém budou popsány problematické direktivy.

Zde je to, co jsme měli:

2020-04-03T12:44:19.670831Z 0 [Warning] [MY-011068] [Server] The syntax 'expire-logs-days' is deprecated and will be removed in a future release. Please use binlog_expire_logs_seconds instead.
2020-04-03T12:44:19.671678Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.
2020-04-03T12:44:19.671682Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8_general_ci' is a collation of the deprecated character set UTF8MB3. Please consider using UTF8MB4 with an appropriate collation instead.

Stále jsme tedy potřebovali zjistit kódování a nahradit zastaralou směrnici expire-logs-days.

Část 2: Kontrola pracovních instalací

Dokumentace k aktualizaci obsahuje 2 nástroje pro kontrolu kompatibility databáze. Jejich použití pomáhá správci kontrolovat kompatibilitu stávající datové struktury.

Začněme klasickou utilitou mysqlcheck. Stačí spustit:

mysqlcheck -u root -p --all-databases --check-upgrade

Pokud nebudou nalezeny žádné problémy, nástroj se ukončí s kódem 0:

Aktualizace MySQL (Percona Server) z 5.7 na 8.0

Kromě toho je v moderních verzích MySQL k dispozici utilita mysql-shell (v případě Percona se jedná o balíček percona-mysql-shell). Jedná se o náhradu klasického mysql klienta a kombinuje funkce klienta, editoru SQL kódu a nástrojů pro správu MySQL. Chcete-li zkontrolovat server před aktualizací, můžete přes něj spustit následující příkazy:

mysqlsh -- util check-for-server-upgrade { --user=root --host=1.1.1.1 --port=3306 } --config-path=/etc/mysql/my.cnf

Zde jsou komentáře, které jsme obdrželi:

Aktualizace MySQL (Percona Server) z 5.7 na 8.0

Obecně nic kritického - pouze upozornění na kódování (viz. níže). Celkový výsledek provedení:

Aktualizace MySQL (Percona Server) z 5.7 na 8.0

Rozhodli jsme se, že aktualizace by měla proběhnout bez problémů.

Poznámka k výše uvedeným varováním indikujícím problémy s kódováním. Faktem je, že UTF-8 v MySQL donedávna nebylo "pravé" UTF-8, protože uložil pouze 3 bajty místo 4. V MySQL 8 je to konečně možné rozhodl to napravit: alias utf8 brzy povede ke kódování utf8mb4, a staré sloupce v tabulkách se stanou utf8mb3. Další kódování utf8mb3 bude odstraněn, ale ne v tomto vydání. Proto jsme se rozhodli opravit kódování již na běžící instalaci DBMS, po její aktualizaci.

Část 3: Aktualizace serveru

Co by se mohlo pokazit, když existuje takový chytrý plán?... Dobře jsme pochopili, že k nuancím dochází vždy, provedli jsme první experiment na vývojovém clusteru MySQL.

Jak již bylo zmíněno, oficiální dokumentace pokrývá problém aktualizace serverů MySQL pomocí replik. Pointa je, že byste měli nejprve aktualizovat všechny repliky (slave), protože MySQL 8 se může replikovat z hlavní verze 5.7. Určitá potíž spočívá v tom, že používáme režim mistr <-> mistr, když je vzdálený master v režimu pouze pro čtení. To znamená, že bojový provoz jde do jednoho datového centra a to druhé je záložní.

Topologie vypadá takto:

Aktualizace MySQL (Percona Server) z 5.7 na 8.0

Aktualizace musí začínat replikami replika mysql dc 2, mysql master dc 2 и mysql replica dc 1a končíme serverem mysql master dc 1. Abychom byli spolehlivější, zastavili jsme virtuální stroje, pořídili jejich snímky a bezprostředně před aktualizací zastavili replikaci příkazem STOP SLAVE. Zbytek aktualizace vypadá takto:

  1. Každou repliku restartujeme přidáním 3 možností do konfigurací: skip-networking, skip-slave-start, skip-log-bin. Faktem je, že aktualizace databáze generuje binární protokoly s aktualizacemi systémových tabulek. Tyto direktivy zaručují, že nedojde k žádným změnám aplikačních dat v databázi a informace o aktualizaci systémových tabulek nebudou zahrnuty do binárních protokolů. Vyhnete se tak problémům při obnovení replikace.
  2. Instalace balíčku percona-server-server. Je důležité si uvědomit, že v MySQL verze 8 ne musíte spustit příkaz mysqlupgrade po aktualizaci serveru.
  3. Po úspěšném startu restartujeme server znovu - bez parametrů, které byly přidány v prvním odstavci.
  4. Zajistíme, aby replikace fungovala úspěšně: zkontrolujte SHOW SLAVE STATUS a uvidíte, že jsou aktualizovány tabulky s čítači v databázi aplikace.

Všechno to vypadá docela jednoduše: aktualizace pro vývojáře byla úspěšná. Dobře, můžete si bezpečně naplánovat noční aktualizaci pro produkci.

Nebyl žádný smutek - aktualizovali jsme prod

Přenos úspěšných vývojářských zkušeností do výroby se však neobešel bez překvapení.

Naštěstí samotný proces aktualizace začíná replikami, takže když jsme narazili na potíže, zastavili jsme práci a obnovili repliku ze snímku. Vyšetřování problémů bylo odloženo na druhý den ráno. Protokoly obsahovaly následující záznamy:

2020-01-14T21:43:21.500563Z 2 [ERROR] [MY-012069] [InnoDB] table: t1 has 19 columns but InnoDB dictionary has 20 columns
2020-01-14T21:43:21.500722Z 2 [ERROR] [MY-010767] [Server] Error in fixing SE data for db1.t1
2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Server] Failed to Populate DD tables.
2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Server] Aborting

Prozkoumání archivů různých e-mailových konferencí na Google vedlo k pochopení, že k tomuto problému dochází kvůli Chyba MySQL. I když je to pravděpodobnější chyba nástroje mysqlcheck и mysqlsh.

Ukázalo se, že MySQL změnil způsob, jakým představují data pro desetinná pole (int, tinyint atd.), takže mysql-server používá jiný způsob jejich ukládání. Pokud vaše databáze zpočátku byl ve verzi 5.5 nebo 5.1 a poté jste aktualizovali na 5.7, možná budete muset provést OPTIMIZE pro některé stoly. Poté MySQL aktualizuje datové soubory a přenese je do aktuálního formátu úložiště.

Můžete to také zkontrolovat pomocí nástroje mysqlfrm:

mysqlfrm --diagnostic -vv /var/lib/mysql/db/table.frm
...
 'field_length': 8,
  'field_type': 246, # формат поля
  'field_type_name': 'decimal',
  'flags': 3,
  'flags_extra': 67,
  'interval_nr': 0,
 'name': 'you_deciaml_column',
...

Jestliže field_type Pokud ji máte rovnou 0, pak je v tabulce použit starý typ - musíte provést OPTIMIZE. Pokud je však hodnota 246, máte již nový typ. Více informací o typech naleznete v kód.

Navíc v tato chyba Zvažujeme druhý možný důvod, který nás obešel: absence tabulek InnoDB v systémové tabulce INNODB_SYS_TABLESPACES, pokud byly tabulky vytvořeny ve verzi 5.1. Chcete-li se vyhnout problémům při aktualizaci, můžete použít připojený SQL skript.

Proč jsme neměli takové problémy na vývoji? Databáze se tam periodicky kopíruje z výroby – tedy tabulky jsou znovu vytvořeny.

Bohužel na skutečně fungující velké databázi nebudete moci jen tak vzít a spustit univerzální OPTIMIZE. Zde pomůže percona-toolkit: utilita pt-online-schema-change je vynikající pro online operaci OPTIMIZE.

Aktualizovaný plán vypadal takto:

  1. Optimalizujte všechny tabulky.
  2. Aktualizujte databáze.

Abychom to zkontrolovali a zároveň zjistili čas aktualizace, zakázali jsme jednu z replik a pro všechny tabulky spustili následující příkaz:

pt-online-schema-change --critical-load Threads_running=150 --alter "ENGINE=InnoDB" --execute --chunk-size 100 --quiet --alter-foreign-keys-method auto h=127.0.0.1,u=root,p=${MYSQL_PASSWORD},D=db1,t=t1

Tabulky se aktualizují bez zdlouhavého zamykání díky tomu, že obslužný program vytvoří novou dočasnou tabulku, do které zkopíruje data z hlavní tabulky. V okamžiku, kdy jsou oba stoly totožné, je původní stůl uzamčen a nahrazen novým. V našem případě zkušební provoz ukázal, že aktualizace všech tabulek bude trvat asi den, ale kopírování dat způsobilo příliš velké zatížení disků.

Abychom tomu zabránili, ve výrobě jsme do příkazu přidali argument --sleep s hodnotou 10 - tento parametr upravuje délku čekání po přenesení dávky dat do nové tabulky. Tímto způsobem můžete snížit zatížení, pokud je aktuální spuštěná aplikace náročná na dobu odezvy.

Po provedení optimalizace byla aktualizace úspěšná.

... ale ne úplně!

Do půl hodiny po aktualizaci přišel klient s problémem. Databáze fungovala velmi zvláštně: periodicky se spouštěly připojení se resetuje. Takto to vypadalo v monitoringu:

Aktualizace MySQL (Percona Server) z 5.7 na 8.0

Snímek obrazovky ukazuje pilovitý graf kvůli skutečnosti, že některá vlákna serveru MySQL pravidelně padala s chybou. V aplikaci se objevily chyby:

[PDOException] SQLSTATE[HY000] [2002] Connection refused

Rychlá kontrola protokolů odhalila, že démon mysqld nemůže získat požadované prostředky z operačního systému. Při třídění chyb jsme objevili v systému "osiřelé" soubory zásad apparmor:

# dpkg -S /etc/apparmor.d/cache/usr.sbin.mysqld
dpkg-query: no path found matching pattern /etc/apparmor.d/cache/usr.sbin.mysqld
# dpkg -S /etc/apparmor.d/local/usr.sbin.mysqld
dpkg-query: no path found matching pattern /etc/apparmor.d/local/usr.sbin.mysqld
# dpkg -S /etc/apparmor.d/usr.sbin.mysqld
mysql-server-5.7: /etc/apparmor.d/usr.sbin.mysqld
# dpkg -l mysql-server-5.7
rc  mysql-server-5.7 5.7.23-0ubuntu0.16.04.1      amd64

Tyto soubory byly vytvořeny při upgradu na MySQL 5.7 před několika lety a patří do odstraněného balíčku. Smazání souborů a restartování služby apparmor problém vyřešilo:

systemctl stop apparmor
rm /etc/apparmor.d/cache/usr.sbin.mysqld
rm /etc/apparmor.d/local/usr.sbin.mysqld
rm /etc/apparmor.d/usr.sbin.mysqld
systemctl start apparmor

Konečně,

Jakákoli, i ta nejjednodušší operace, může vést k neočekávaným problémům. A ani dobře promyšlený plán nemusí vždy zaručit očekávaný výsledek. Nyní všechny plány aktualizací náš tým zahrnují také povinné čištění nepotřebných souborů, které se mohly objevit v důsledku nedávných akcí.

A touto nepříliš profesionální grafickou kreativitou bych chtěl poděkovat společnosti Percona za skvělé produkty!

Aktualizace MySQL (Percona Server) z 5.7 na 8.0

PS

Přečtěte si také na našem blogu:

Zdroj: www.habr.com

Přidat komentář