A MySQL (Percona Server) frissítése 5.7-ről 8.0-ra

A MySQL (Percona Server) frissítése 5.7-ről 8.0-ra

A haladás nem áll meg, így a MySQL legújabb verzióira való frissítés iránti okok egyre meggyőzőbbek. Nem sokkal ezelőtt egyik projektünkben eljött az ideje, hogy frissítsük a hangulatos Percona Server 5.7 fürtöket a 8-as verzióra. Mindez az Ubuntu Linux 16.04 platformon történt. Hogyan hajtsunk végre egy ilyen műveletet minimális állásidővel, és milyen problémákkal találkoztunk a frissítés során - olvassa el ebben a cikkben.

Edzés

Az adatbázis-kiszolgáló minden frissítése valószínűleg az adatbázis-újrakonfigurációhoz kapcsolódik: a rendszererőforrás-korlátozási követelmények megváltozása és az adatbázis-konfigurációk javítása, amelyeket meg kell tisztítani az elavult direktíváktól.

Frissítés előtt feltétlenül hivatkozunk a hivatalos dokumentációra:

És készítsünk cselekvési tervet:

  1. Javítsa ki a konfigurációs fájlokat az elavult direktívák eltávolításával.
  2. Ellenőrizze a kompatibilitást a segédprogramokkal.
  3. Frissítse a szolga adatbázisokat a csomag telepítésével percona-server-server.
  4. Frissítse a mestert ugyanazzal a csomaggal.

Nézzük meg a terv minden pontját, és nézzük meg, mi hibázhat.

FONTOS! A Galera alapú MySQL-fürt frissítési eljárásának megvannak a maga finomságai, amelyeket a cikk nem ismertet. Ebben az esetben ne használja ezt az utasítást.

1. rész: Konfigurációk ellenőrzése

A MySQL-t eltávolították a 8-as verzióban query_cache. Valójában ő volt elavulttá nyilvánították még az 5.7-es verzióban, de most teljesen törölve. Ennek megfelelően el kell távolítani a kapcsolódó irányelveket. A kérések gyorsítótárazásához most már külső eszközöket is használhat – például ProxySQL.

A konfigban is voltak elavult direktívák kb innodb_file_format. Ha a MySQL 5.7-ben az InnoDB formátumot lehetett választani, akkor a 8. verzió már működik csak Barracuda formátummal.

Eredményünk a következő direktívák eltávolítása:

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

Az ellenőrzéshez a Percona Server Docker-képet használjuk. A szerver konfigurációját a könyvtárba helyezzük mysql_config_test, mellette pedig könyvtárakat hozunk létre az adatok és naplók számára. Példa a Percona-szerver konfigurációs tesztjéhez:

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

A lényeg: vagy a Docker naplókban, vagy a naplókat tartalmazó könyvtárban - a konfigurációktól függően - megjelenik egy fájl, amelyben a problémás direktívák leírása lesz.

Íme, mi volt nálunk:

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.

Így még mindig ki kellett találnunk a kódolásokat, és ki kellett cserélnünk az elavult direktívát expire-logs-days.

2. rész: Működő berendezések ellenőrzése

A frissítési dokumentáció 2 segédprogramot tartalmaz az adatbázis kompatibilitási ellenőrzésére. Használatuk segít az adminisztrátornak ellenőrizni a meglévő adatstruktúra kompatibilitását.

Kezdjük a klasszikus mysqlcheck segédprogrammal. Egyszerűen fuss:

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

Ha nem talál problémát, a segédprogram 0 kóddal lép ki:

A MySQL (Percona Server) frissítése 5.7-ről 8.0-ra

Ezenkívül a MySQL modern verzióiban egy segédprogram is elérhető mysql-shell (Percona esetében ez a csomag percona-mysql-shell). A klasszikus mysql klienst helyettesíti, és egyesíti a kliens, az SQL kódszerkesztő és a MySQL adminisztrációs eszközök funkcióit. A kiszolgáló frissítés előtti ellenőrzéséhez futtassa a következő parancsokat rajta:

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

Íme a hozzánk érkezett észrevételek:

A MySQL (Percona Server) frissítése 5.7-ről 8.0-ra

Általában semmi kritikus - csak figyelmeztetések a kódolással kapcsolatban (lásd lejjebb). A teljes végrehajtás eredménye:

A MySQL (Percona Server) frissítése 5.7-ről 8.0-ra

Úgy döntöttünk, hogy a frissítésnek problémamentesnek kell lennie.

Megjegyzés a fenti figyelmeztetésekről, amelyek kódolási problémákat jeleznek. Az a tény, hogy az UTF-8 a MySQL-ben egészen a közelmúltig nem volt "igaz" UTF-8, mivel 3 helyett csak 4 bájtot tárolt. A MySQL 8-ban ez végre úgy döntött, megjavítja: alias utf8 hamarosan kódoláshoz vezet utf8mb4, és a táblázatok régi oszlopai lesznek utf8mb3. További kódolás utf8mb3 eltávolításra kerül, de ebben a kiadásban nem. Ezért úgy döntöttünk, hogy a már futó DBMS-telepítésen, annak frissítése után kijavítjuk a kódolásokat.

3. rész: Szerverfrissítések

Mi történhet rosszul, ha van egy ilyen okos terv?... Jól megértve, hogy árnyalatok mindig történnek, elvégeztük az első kísérletet egy MySQL fejlesztői fürtön.

Mint már említettem, hivatalos dokumentáció lefedi a MySQL-kiszolgálók replikákkal való frissítésének kérdését. A lényeg az, hogy először frissítenie kell az összes replikát (slave), mivel a MySQL 8 képes replikálni az 5.7-es főverzióról. Némi nehézség abban rejlik, hogy a módot használjuk mester <-> mester, amikor a távoli mester módban van csak olvasható. Ez azt jelenti, hogy a harci forgalom az egyik adatközpontba megy, a második pedig egy tartalék.

A topológia így néz ki:

A MySQL (Percona Server) frissítése 5.7-ről 8.0-ra

A frissítésnek replikákkal kell kezdődnie mysql replika dc 2, mysql master dc 2 и mysql replica dc 1, és a végén a mysql master dc 1 szerverrel. A megbízhatóbbak érdekében leállítottuk a virtuális gépeket, pillanatfelvételeket készítettünk róluk, és közvetlenül a frissítés előtt leállítottuk a replikációt a paranccsal STOP SLAVE. A frissítés többi része így néz ki:

  1. Minden replikát újraindítunk úgy, hogy 3 lehetőséget adunk a konfigurációkhoz: skip-networking, skip-slave-start, skip-log-bin. Az a tény, hogy az adatbázis frissítése bináris naplókat generál a rendszertáblázatok frissítésével. Ezek az irányelvek garantálják, hogy az adatbázisban lévő alkalmazásadatok nem változnak, és a rendszertáblázatok frissítésére vonatkozó információk nem fognak szerepelni a bináris naplókban. Ezzel elkerülheti a replikáció folytatásakor felmerülő problémákat.
  2. A csomag telepítése percona-server-server. Fontos megjegyezni, hogy a MySQL 8-as verziójában nincs le kell futtatnia a parancsot mysqlupgrade szerver frissítés után.
  3. Sikeres indítás után újraindítjuk a szervert – az első bekezdésben megadott paraméterek nélkül.
  4. Biztosítjuk a replikáció sikeres működését: ellenőrizze SHOW SLAVE STATUS és ellenőrizze, hogy az alkalmazás-adatbázis számlálóit tartalmazó táblák frissülnek-e.

Minden nagyon egyszerűnek tűnik: a fejlesztői frissítés sikeres volt. Rendben, nyugodtan ütemezhet egy éjszakai frissítést a gyártáshoz.

Nem volt szomorúság – frissítettük a prod-ot

A sikeres fejlesztői tapasztalatok termelésbe való átadása azonban nem volt mentes meglepetésektől.

Szerencsére maga a frissítési folyamat a replikákkal kezdődik, így amikor nehézségekbe ütköztünk, leállítottuk a munkát, és visszaállítottuk a replikát a pillanatképből. A problémák kivizsgálását másnap reggelig halasztották. A naplók a következő bejegyzéseket tartalmazták:

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

A különböző levelezőlisták archívumainak kutatása a Google-on arra a felismerésre vezetett, hogy ez a probléma oka MySQL bug. Bár ez inkább egy segédprogram hiba mysqlcheck и mysqlsh.

Kiderült, hogy a MySQL megváltoztatta a decimális mezők (int, tinyint stb.) adatmegjelenítési módját, így a mysql-server más módon tárolja azokat. Ha az adatbázisod alapvetően 5.5-ös vagy 5.1-es verzióban volt, majd frissített 5.7-re, akkor lehet, hogy OPTIMIZE néhány asztalhoz. Ezután a MySQL frissíti az adatfájlokat, és átviszi őket az aktuális tárolási formátumba.

Ezt a segédprogrammal is ellenőrizheti 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',
...

Ha field_type Ha 0-val egyenlő, akkor a táblázatban a régi típust használjuk - végre kell hajtani OPTIMIZE. Ha azonban az érték 246, akkor már van egy új típusa. A típusokról bővebb információ itt található kód.

Sőt, ben ezt a hibát A második lehetséges okot fontolgatjuk, amely megkerült minket: az InnoDB táblák hiányát a rendszertáblában INNODB_SYS_TABLESPACES, ha azok, táblák, az 5.1-es verzióban jöttek létre. A frissítési problémák elkerülése érdekében használhatja csatolt SQL szkriptet.

Miért nem voltak ilyen problémáink a fejlesztőnél? Az adatbázist időszakonként másolják oda a termelésből – így a táblázatok újra létrejönnek.

Sajnos egy igazán működő, nagy adatbázison nem lehet csak úgy elvenni és végrehajtani egy univerzálisat OPTIMIZE. A percona-toolkit segít itt: a pt-online-schema-change segédprogram kiválóan alkalmas az online OPTIMIZE műveletre.

A frissített terv így nézett ki:

  1. Optimalizálja az összes táblát.
  2. Frissítse az adatbázisokat.

Ennek ellenőrzéséhez és egyidejűleg a frissítés időpontjának megállapításához letiltottuk az egyik replikát, és a következő parancsot futtattuk az összes táblára:

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

A táblák frissítése hosszadalmas zárolás nélkül történik, mivel a segédprogram új ideiglenes táblát hoz létre, amelybe a fő tábla adatait másolja. Abban a pillanatban, amikor mindkét asztal azonos, az eredeti asztal zárolásra kerül, és az új asztalra kerül. Esetünkben egy próbaüzem azt mutatta, hogy az összes tábla frissítése körülbelül egy napot vesz igénybe, de az adatok másolása túl sok terhelést okozott a lemezeken.

Ennek elkerülése érdekében a termelésben hozzáadtuk az argumentumot a parancshoz --sleep 10-es értékkel - ez a paraméter beállítja a várakozási időt egy adatköteg új táblába átvitele után. Így csökkentheti a terhelést, ha a ténylegesen futó alkalmazás válaszidőt igényel.

Az optimalizálás elvégzése után a frissítés sikeres volt.

... de nem teljesen!

A frissítés után fél órán belül probléma lépett fel a klienssel. Az adatbázis nagyon furcsán működött: időszakosan elindultak kapcsolat alaphelyzetbe áll. Így nézett ki a megfigyelés során:

A MySQL (Percona Server) frissítése 5.7-ről 8.0-ra

A képernyőképen egy fűrészfog grafikon látható, mivel a MySQL szerver szálai közül néhány időnként összeomlott egy hiba miatt. Hibák jelentek meg az alkalmazásban:

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

A naplók gyors vizsgálata során kiderült, hogy a mysqld démon nem tudja megszerezni a szükséges erőforrásokat az operációs rendszertől. A hibák kijavítása során felfedeztük a rendszerben „árva” apparmor házirend-fájlok:

# 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

Ezek a fájlok a MySQL 5.7-re való frissítéskor jöttek létre néhány évvel ezelőtt, és egy eltávolított csomaghoz tartoznak. A fájlok törlése és az apparmor szolgáltatás újraindítása megoldotta a problémát:

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

Összefoglalva

Bármilyen, még a legegyszerűbb művelet is váratlan problémákhoz vezethet. És még egy jól átgondolt terv sem mindig garantálja a várt eredményt. Mostantól csapatunk minden frissítési tervébe beletartozik a szükségtelen fájlok kötelező megtisztítása is, amelyek a közelmúltban végrehajtott műveletek eredményeként jelenhettek meg.

Ezzel a nem túl professzionális grafikai kreativitással pedig hatalmas köszönetet szeretnék mondani a Perconának a kiváló termékeikért!

A MySQL (Percona Server) frissítése 5.7-ről 8.0-ra

PS

Olvassa el blogunkon is:

Forrás: will.com

Hozzászólás