Upgrade MySQL 8.0 na 8.4 má čtyři části a na pořadí záleží víc než na kterémkoli jednotlivém příkazu. Spusť kontrolu upgradu z MySQL Shellu proti běžícímu serveru 8.0 a oprav každou chybu, kterou nahlásí. Udělej zálohu, kterou jde obnovit do verze 8.0 - studenou kopii datového adresáře pro in-place upgrade, logický dump pro všechno ostatní. Pak buď spusť binárky 8.4 nad starým datovým adresářem (in-place), nebo načti dump do čistého serveru 8.4 (logicky). Nakonec otestuj aplikaci proti 8.4 dřív, než přijde skutečný provoz, protože cesta zpět přímo na místě neexistuje: jakmile 8.4 jednou nastartuje nad datovým adresářem, 8.0 ho odmítne otevřít.
O tom, co se mezi verzemi mění - výchozí autentizace, odstraněné příkazy, nové výchozí hodnoty InnoDB - se píše v článku MySQL 8.4 LTS: co se změnilo. Tento návod je postup: příkazy, význam výstupu kontroly, obě cesty upgradu podrobně, jak testovat a kam přesně až rollback sahá.
In-place, nebo logicky: nejdřív vyber cestu#
Obě cesty skončí s tvými daty na 8.4. Liší se výpadkem, tím, co potřebuješ mít pod kontrolou, a tím, jak vypadá rollback.
| In-place | Logicky (dump a load) | |
|---|---|---|
| Co se děje | Binárky 8.4 nastartují nad datovým adresářem 8.0 | Data se exportují jako SQL nebo soubory a načtou do nového serveru 8.4 |
| Co potřebuješ | Root na stroji, kde MySQL běží | Přihlášení na oba servery |
| Výpadek | Minuty plus upgrade datového slovníku | Doba dumpu plus doba načtení, obvykle mnohem delší |
| Rychlost u velkých dat | Rychlé - žádná data se nepřepisují | Pomalé - přebuduje se každý řádek a index |
| Starý server potom | Pryč, pokud sis nezkopíroval soubory | Nedotčený, pořád běží 8.0 |
| Bonus při úklidu | Žádný | Tabulky se přebuduje, zmizí fragmentace a staré formáty řádků |
Použij in-place, když MySQL provozuješ sám na VDS nebo na vlastním stroji a data jsou tak velká, že by znovunačtení trvalo hodiny. Použij logickou cestu, když databáze běží u poskytovatele, kde server spravuje někdo jiný, když se zároveň stěhuješ na nový stroj, nebo když jsou data tak malá - pár gigabajtů - že se načtou za pár minut. Logický upgrade má navíc nejpohodlnější rollback, protože server 8.0 pořád běží beze změny, dokud ho nevypneš.
Existuje i třetí cesta pro ty, kdo si výpadek nemohou dovolit: nový server 8.4 nastav jako repliku zdroje s 8.0, nech ho dohnat stav a pak na něj přepoj aplikaci. Replikace ze starší zdrojové verze na novější repliku je podporovaná, opačně ne, takže jakmile se zápisy objeví na 8.4, starý server 8.0 je už nemůže následovat. Tahle cesta přesahuje potřeby malé aplikace, a proto ji tu nepopisuju podrobně.
Krok 1: nejdřív zálohuj, ve formě, kterou 8.0 přečte#
Záloha před upgradem má kromě obvyklého jeden speciální úkol: musí jít obnovit do verze 8.0, protože právě k ní by ses vracel. Splňují to dva druhy.
Studená kopie datového adresáře. Čistě zastav 8.0 a zkopíruj celý adresář - na Linuxu obvykle /var/lib/mysql - jinam. Je to jediná záloha, která rychle vrátí in-place upgrade: vrátíš kopii zpět, přeinstaluješ 8.0, nastartuješ a jsi tam, kde jsi byl. Na nic jiného se nehodí, protože se otevře jen na stejné hlavní verzi, ale na tohle je ideální. Stejný účel splní snímek souborového systému (LVM, ZFS) čistě zastaveného serveru a trvá vteřiny.
$ sudo systemctl stop mysql # mysqld on RHEL-family systems$ sudo cp -a /var/lib/mysql /var/backups/mysql-80-datadir$ sudo cp -a /etc/mysql /var/backups/mysql-80-etcZkopíruj i konfiguraci. Upgrade tě přinutí ji upravit a rollback potřebuje verzi pro 8.0 zpátky.
Logický dump. To je záloha pro logickou cestu a druhá linie obrany pro in-place. mysqldump s --single-transaction --routines --events --triggers vytvoří konzistentní soubor SQL bez zastavení serveru; záloha a obnova přes mysqldump vysvětluje každý přepínač i chyby, na které narazíš. U větších databází je rychlejší dump utility z MySQL Shellu, protože zapisuje paralelně:
// in mysqlsh, JavaScript mode (\js)util.dumpInstance("/var/backups/dump-80", {threads: 4})util.dumpInstance() ve výchozím stavu zahrnuje uživatelské účty a oprávnění, což mysqldump zvládá špatně - schéma mysql vyexportuje jako tabulky a jejich načítání do jiné verze je hledání problémů. Pokud používáš mysqldump, účty ulož zvlášť: pro každý aplikační účet ti SHOW CREATE USER a SHOW GRANTS dají příkazy, které můžeš znovu přehrát.
Krok 2: spusť util.checkForServerUpgrade#
Kontrola upgradu žije v MySQL Shellu (mysqlsh), ne v serveru. Připojí se k běžícímu serveru 8.0, prozkoumá konfiguraci, účty, schémata a uložený kód a ohlásí, co by na cílové verzi selhalo nebo se chovalo jinak. Nic nemění.
Potřebuješ MySQL Shell aspoň tak nový jako cílová verze: kontrola umí testovat libovolnou verzi od 8.0.11 až po své vlastní číslo verze, dál ne. Pro cíl 8.4 funguje Shell 8.4 i vydání 9.x. Může běžet na jakémkoli stroji, který na server dosáhne, třeba na tvém notebooku, ale kontrola konfiguračního souboru potřebuje soubor na stroji, kde Shell běží, takže na samotném databázovém serveru dostaneš nejúplnější report.
$ mysqlsh -- util check-for-server-upgrade root@localhost:3306 \ --target-version=8.4.6 --config-path=/etc/mysql/my.cnfTotéž z interaktivní relace Shellu v režimu JavaScript:
util.checkForServerUpgrade("root@localhost:3306", { targetVersion: "8.4.6", configPath: "/etc/mysql/my.cnf"})Pokud vynecháš targetVersion, kontrola předpokládá verzi odpovídající samotnému Shellu - takže Shell 9.x spuštěný bez něj kontroluje pro 9.x a hlásí problémy, které zatím nemáš. Zadej konkrétní patch verze 8.4, který opravdu instaluješ. Pokud vynecháš configPath, kontroly čtoucí konfigurační soubor selžou se zprávou, že ho chtějí; na Debianu a Ubuntu je to /etc/mysql/my.cnf (který načítá mysql.conf.d/), na systémech z rodiny RHEL /etc/my.cnf.
Účet, pod kterým kontrola běží, potřebuje oprávnění PROCESS a SELECT. Na vlastním serveru je nejjednodušší root. Na hostovaném serveru, kde máš jen aplikačního uživatele, přidej, co jde, a spusť to stejně; kontroly, které nemají na co sáhnout, to ohlásí, místo aby tiše prošly.
Jak číst report
Textový výstup je číslovaný seznam kontrol, z nichž každá končí No issues found, nebo seznamem nálezů označených Error, Warning nebo Notice, a nakonec souhrnem:
Errors: 2Warnings: 5Notices: 02 errors were found. Please correct these issues before upgradingto avoid compatibility issues.Chyby (Errors) upgrade zablokují nebo způsobí, že server odmítne nastartovat - obvykle jde o odstraněnou volbu v konfiguračním souboru. Oprav je všechny na serveru 8.0 a spouštěj kontrolu znovu, dokud není počet nula. Varování (Warnings) upgrade nezastaví, ale popisují něco, co se bude chovat jinak nebo se časem rozbije; přečti si každé. Upozornění (Notices) jsou jen informativní.
Kontroly, které se na serveru 8.0 před přechodem na 8.4 spouštějí nejčastěji:
| Kontrola | Co najde |
|---|---|
sysvar | Odstraněné volby v konfiguračním souboru a nastavení, jejichž výchozí hodnota se mění |
authMethodUsage | Účty, které jsou pořád na mysql_native_password |
deprecatedDefaultAuth | Pořád nastavené default_authentication_plugin |
pluginUsage | Pluginy, které byly odstraněny nebo nahrazeny komponentami |
foreignKeyReferences | Cizí klíče mířící na neunikátní nebo částečné klíče |
reservedKeywords | Identifikátory, které se staly rezervovanými slovy |
invalidPrivileges | Oprávnění, která už neexistují nebo se změnila |
mysqlsh -- util check-for-server-upgrade --list --target-version=8.4.6 vypíše všechny kontroly s popisem a verzemi, pro které platí. Pro automatizaci dá --output-format=JSON jeden objekt s errorCount, warningCount a polem checksPerformed; krok v CI nebo skript může odmítnout pokračovat, dokud je errorCount nad nulou. Kontrola selhání neoznamuje návratovým kódem, takže čti počet a nespoléhej na to, že příkaz skončí chybou.
Dva nálezy si zaslouží poznámku k opravě. U authMethodUsage převeď každý účet na caching_sha2_password pomocí ALTER USER ... IDENTIFIED WITH caching_sha2_password BY '...' - po ověření, že ovladač aplikace tuto metodu podporuje. U sysvar uprav konfigurační soubor a odstraněná nastavení smaž nebo přejmenuj; nejčastější jsou expire_logs_days (nahraď ho binlog_expire_logs_seconds) a default_authentication_plugin. Obě opravy fungují na 8.0, takže je udělej tam, restartuj a před samotným upgradem ověř, že aplikace pořád běží. Tím oddělíš „rozbila to změna konfigurace“ od „rozbila to 8.4“, a ten rozdíl budeš chtít znát.
Krok 3a: in-place upgrade na Linuxu#
Když je kontrola čistá a studená kopie hotová, je in-place upgrade krátký. Dokumentace MySQL před in-place upgradem mezi vydávanými řadami doporučuje pomalé vypnutí, aby InnoDB dokončil purge a slučování change bufferu dřív, než se soubory předají nové verzi:
SET GLOBAL innodb_fast_shutdown = 0;Pak zastav server a vyměň balíčky. Na Debianu nebo Ubuntu s APT repozitářem od Oraclu se řada vybírá balíčkem mysql-apt-config:
$ sudo systemctl stop mysql$ sudo dpkg-reconfigure mysql-apt-config # choose the 8.4 LTS series$ sudo apt update$ sudo apt install mysql-serverNa RHEL, Rocky nebo Alma s yum repozitářem od Oraclu vypni repozitář 8.0 a zapni LTS repozitář 8.4 - přesné názvy ukáže dnf repolist all | grep mysql ve tvém release balíčku - a pak sudo dnf upgrade mysql-community-server. MySQL z balíčků distribuce se řídí vlastním harmonogramem distribuce a 8.4 nemusí nabízet vůbec; pokud apt policy mysql-server ukazuje jen kandidáty 8.0, potřebuješ repozitář od Oraclu nebo kontejner.
V Dockeru je výměna jen změna tagu. Zastav kontejner, změň image: mysql:8.0 na image: mysql:8.4 a spusť ho nad stejným svazkem. Připni 8.4 nebo konkrétní patch, nikdy latest, který se posunul za 8.4 k Innovation vydáním.
Co se stane při prvním startu
Když 8.4 nastartuje nad datovým adresářem 8.0, upgraduje datový slovník, potom systémové schéma mysql, schéma sys a tabulky nápovědy. Během toho sleduj chybový log:
$ sudo tail -f /var/log/mysql/error.logHledáš dvojici řádků Server upgrade from '80xxx' to '804xx' started a ... completed, potom ready for connections. Na serveru s pár stovkami tabulek to trvá vteřiny, s desítkami tisíc to mohou být minuty. Nezabíjej to v půlce - přerušený upgrade datového slovníku je přesně to, na co je studená kopie.
Chování řídí volba serveru --upgrade, která má výchozí hodnotu AUTO (upgraduj, co to potřebuje). --upgrade=FORCE znovu spustí upgrade systémových tabulek, i když si server myslí, že je hotový, což je oprava ve chvíli, kdy je podezření, že systémové schéma je upgradované jen napůl. mysql_upgrade už neexistuje; není co spouštět ručně.
Pokud server nenastartuje, log řekne proč v prvních několika řádcích chyb. Obvyklá příčina je volba, kterou kontrola označila a nikdo ji neodstranil - log ukáže unknown variable s jejím názvem. Odstraň ji z konfigurace a nastartuj znovu.
Krok 3b: logický upgrade#
Logická cesta potřebuje běžící server 8.4 - nový stroj, nový kontejner nebo hostovanou databázi MySQL 8.4 - a dump z kroku 1. U výstupu z mysqldump je to prostý import:
$ gunzip -c appdb-80.sql.gz | mysql -h new-host -P 3306 -u root -p appdbU dumpu z MySQL Shellu použij odpovídající loader, který načítá tabulky paralelně:
util.loadDump("/var/backups/dump-80", {threads: 4, loadUsers: true})util.loadDump() má dvě záludnosti. Data načítá přes LOAD DATA LOCAL INFILE, takže cílový server musí mít local_infile nastavené na ON; pokud je vypnuté a nemůžeš ho změnit, použij místo toho mysqldump. A loadUsers je ve výchozím stavu vypnuté, takže účty a oprávnění se přeskočí, dokud o ně nepožádáš. Na hostovaném serveru, kde nejsi plnohodnotný administrátor, je často čistší uživatele vynechat a aplikační účty si vytvořit sám - účet, který máš, nemusí mít právo vytvářet účty s libovolnými oprávněními stejně.
Smyslem logické cesty je zkouška nanečisto. Načti data do nového serveru, zatímco starý dál obsluhuje provoz, vše otestuj proti kopii, a když to projde, udělej čerstvý dump během krátkého zmrazení zápisů a načti ten. Zmrazení potřebuješ jen kvůli zápisům mezi zkušebním a finálním dumpem. Samotné přepnutí - zmrazení, finální dump, změna connection stringů, ponechání starého serveru pár dní jen pro čtení - popisuje migrace MySQL na nový host.
Definery jsou klasická příčina selhání importu. Pohled, trigger nebo rutina vytvořená účtem admin@localhost na starém serveru nese DEFINER=admin@localhost a na 8.4 vyžaduje vytvoření objektu s jiným účtem jako definerem oprávnění SET_ANY_DEFINER. Pokud se import zastaví chybou odepřeného přístupu u CREATE VIEW nebo CREATE TRIGGER, buď nejdřív vytvoř účet definera, nebo klauzule z dumpu odstraň.
Krok 4: otestuj aplikaci dřív, než přijde provoz#
Kontrola upgradu zkoumá databázi. Aplikaci nevidí a právě v aplikaci se překvapení z 8.4 objeví. Testuj proti upgradované kopii - u logické cesty proti zkušebnímu serveru, u in-place proti stagingu nebo kopii obnovené ze studené zálohy.
Co testovat, zhruba podle toho, jak často se to láme:
- Každý účet se umí přihlásit. Nejen hlavní aplikační uživatel - také účet jen pro čtení pro reporty, uživatel zálohování, ten, který používá cron. Účet, který je pořád na
mysql_native_password, selže tady a nikde jinde. - Každý klient a ovladač se připojí. Staré konektory jsou obvyklý problém: ovladač, který neumí
caching_sha2_password, hlásí, že se plugin nedá načíst. Zkontroluj ovladače pro programovací jazyky, grafické nástroje i agenty pro zálohování a monitoring. Chování TLS u tohoto pluginu popisuje vzdálená připojení k MySQL. - Testy aplikace projdou. Spusť vlastní testy aplikace proti 8.4. Zvláštní pozornost si zaslouží migrace: ORM, které vytvoří cizí klíč na neunikátním sloupci, na 8.4 selže, i když ty existující upgrade přežily.
- Plánované úlohy a skripty běží. Cokoli, co volá
SHOW SLAVE STATUS,FLUSH HOSTSneboRESET MASTER, teď končí syntaktickou chybou. Prohledej repozitáře a crontaby. - Pomalé dotazy zůstanou rychlé. Výchozí
sql_modese oproti 8.0 nezměnil, takže výsledky dotazů by měly být stejné, ale plány se mohou posunout kvůli novým výchozím hodnotám InnoDB a změnám optimalizátoru. Vezmi nejčastější dotazy zperformance_schema.events_statements_summary_by_digestna 8.0, spusť na každémEXPLAINna obou verzích a porovnej. Jak číst rozdíly, vysvětluje indexy v MySQL a EXPLAIN a slow query log zachytí, co jsi přehlédl, jakmile přijde skutečný provoz.
Na malém serveru sleduj paměť první den. Výchozí hodnota temptable_max_ram na 8.4 je 3 % paměti, ale nikdy méně než 1 GB, což na stroji s 1 nebo 2 GB může dovolit dočasným tabulkám využít mnohem víc, než je záměr. Pokud jsi ho na 8.0 nenastavoval, nastav ho teď výslovně.
Rollback: co jde vrátit a co ne#
Tohle je část, kterou se lidé učí tvrdě, takže stojí za to být přesný.
In-place downgrade z 8.4 na 8.0 není podporovaný. Jakmile 8.4 nastartuje nad datovým adresářem, datový slovník nese novou verzi. Spusť na něm 8.0 a InnoDB odmítne s hláškou Downgrade is not supported. Žádný nástroj, který by to převedl zpět, neexistuje. Jediná rychlá cesta zpět je studená kopie z kroku 1: zastav 8.4, odsuň jeho datový adresář, obnov kopii, přeinstaluj balíčky 8.0 a starou konfiguraci a nastartuj. Všechno zapsané po pořízení kopie je ztraceno, proto by okno mezi jejím pořízením a rozhodnutím, že 8.4 zůstane, mělo být krátké.
Logický dump z 8.4 do 8.0 je podporovaný, ale jen pro rollback. Manuál 8.4 uvádí dump a load (nebo replikaci) jako cestu z 8.4 zpět na 8.0 za podmínky, že se na datech nepoužila žádná nová funkcionalita 8.4. Takhle zachováš zápisy provedené po upgradu: vyexportuješ server 8.4 a načteš ho do 8.0. U velkých dat je to pomalé a funguje to jen tehdy, dokud schéma nepoužívá nic, co 8.0 nemá - nové oprávnění v grantu, GTID tag, funkci zavedenou v 8.1 až 8.4. Čím déle na 8.4 běžíš, tím pravděpodobnější je, že se tam něco připlete.
Logická cesta se vrací přepnutím connection stringu. Server 8.0 pořád běží. Pokud jsi ho při přepnutí nechal jen pro čtení, je návrat okamžitý, minus to, co se mezitím zapsalo na 8.4.
| Cesta | Cesta zpět | Zápisy po upgradu |
|---|---|---|
| In-place | Obnov studenou kopii, přeinstaluj 8.0 | Ztraceny |
| In-place | Dump z 8.4, načtení do 8.0 | Zachovány, pokud se nepoužily funkce jen z 8.4 |
| Logicky | Nasměruj aplikaci zpět na 8.0 | Ztraceny, pokud je nepřeneseš dumpem |
Bod, odkud není návratu, si stanov předem. Rozumný postup: studenou kopii nebo starý server nech týden a po tu dobu nepřebírej nic specifického pro 8.4. Potom jdi raději dopředu než zpět - problémy řeš na 8.4, protože 8.0 už nedostává bezpečnostní opravy.
Řešení potíží s upgradem#
Většina selhání spadá do pár vzorců a chybový log nebo hláška klienta je pojmenuje.
Server po výměně balíčků nenastartuje: přečti první řádky [ERROR] v logu. unknown variable znamená odstraněnou volbu v některém konfiguračním souboru - zkontroluj i includované adresáře, nejen hlavní soubor. Zpráva o tom, že datový adresář je z novější verze, znamená, že startuješ 8.0 nad upgradovaným adresářem; obnov studenou kopii.
Aplikace se nemůže přihlásit, ale mysql ano: účet je na mysql_native_password, nebo je ovladač příliš starý na caching_sha2_password. Jako provizorium mysql_native_password=ON v sekci [mysqld] starý plugin znovu zapne, ale v 9.0 už není, takže to ber jako pár dní odkladu, ne jako řešení.
Kontrola nic nehlásí, ale import selže: kontrola zkoumá zdrojový server, ne tvůj soubor s dumpem. Chyby definerů, řádky SET @@GLOBAL.GTID_PURGED a odmítnutí local_infile jsou problémy při načítání; každý z nich rozebírá návod k mysqldumpu.
Dotazy jsou po in-place upgradu pomalejší: spusť ANALYZE TABLE na nejvytíženějších tabulkách, aby byly statistiky čerstvé, a pak porovnej plány. Pokud se některá zátěž spoléhala na adaptivní hash index, innodb_adaptive_hash_index=ON vrátí chování z 8.0; měř před a po, nezapínej ho jen tak jako výchozí.
Jak to funguje na RE:NODE#
Řada MySQL na RE:NODE už běží na MySQL 8.4 LTS, takže přechod z 8.0 jinde je logická cesta: spusť kontrolu proti starému serveru, udělej dump a načti ho do nového serveru s heslem roota a aplikační databází, které se pro něj vygenerují. Binárky serveru nespravuješ, takže žádný in-place upgrade není co dělat, a zálohy v panelu - na požádání nebo plánované, obnovitelné tlačítkem a uložené mimo stroj - kryjí databázi poté, co se tam dostane. Otestuj nový server dřív, než přepneš connection string aplikace, a starý server 8.0 nech nedotčený, dokud nebudeš spokojený.
FAQ#
Můžu upgradovat z MySQL 5.7 rovnou na 8.4?
Ne in-place. 5.7 musí nejdřív na 8.0 a pak 8.0 na 8.4. Logický dump z 5.7 se obvykle načte do 8.4 přímo, s výjimkou rezervovaných slov, nulových dat ve striktním režimu a starých autentizačních pluginů, takže před zkouškou spusť kontrolu proti serveru 5.7 s cílem 8.4.
Mění kontrola upgradu něco na mém serveru?
Ne. Jen čte: konfiguraci, metadata z information_schema a ze schématu mysql a uložený kód. Otevře si vlastní relaci a aktuální relaci Shellu nechá na pokoji. Je bezpečné ji spustit proti produkci i v pracovní době.
Jak dlouho trvá in-place upgrade?
Výměna balíčků zabere minutu nebo dvě. Upgrade datového slovníku při prvním startu závisí na počtu tabulek, ne na objemu dat - vteřiny u běžné aplikace, minuty u té s desítkami tisíc tabulek. Pomalé vypnutí předtím může na vytíženém serveru s velkým množstvím čekajícího purge přidat čas.
Mám jít na 8.4, nebo rovnou na vydání 9.x?
Na 8.4 pro produkční databázi. Je to řada s dlouhodobou podporou a dostává opravy bez změn chování. Innovation vydání 9.x jsou podporovaná jen do dalšího vydání a pořád něco odstraňují, včetně úplného odstranění mysql_native_password.
Musím upgradovat ovladač MySQL v aplikaci?
Jen pokud neumí caching_sha2_password, což platí pro starý balíček mysql pro Node a pro ovladače z éry 5.7. Ovladače z posledních několika let to zvládají. Ověř to připojením k upgradované kopii přesně s tou verzí ovladače, kterou aplikace dodává.


