
Napredek ne miruje, zato postajajo razlogi za nadgradnjo na najnovejše različice MySQL vse pomembnejši. Pred kratkim je pri enem od naših projektov prišel čas za nadgradnjo udobnih klasterjev Percona Server 5.7 na 8. različico. Vse to se je dogajalo na platformi Ubuntu Linux 16.04. Kako izvesti to operacijo z minimalnimi ustavitvami in s katerimi težavami smo se srečali pri nadgradnji — preberite v tem članku.
Priprava
Vsaka nadgradnja strežnika baz podatkov bo verjetno povezana s ponovno nastavitvijo baze: spremembami zahtev po omejitvah sistemskih virov in popravkom konfiguracijskih datotek baze, ki jih je treba očistiti od zastarelih direktiv.
Pred nadgradnjo se bomo nujno sklicevali na uradno dokumentacijo:
- ;
- ;
- ;
- .
In pripravili bomo načrt ukrepov:
- Popraviti je treba konfiguracijske datoteke, tako da odstranimo zastarele direktive.
- Preveriti združljivost s pripomočki.
- Nadgraditi slave baze z namestitvijo paketa
percona-server-server. - Nadgraditi glavni strežnik in namestiti isti paket.
Razčlenili bomo vsak korak načrta in se prepričali, kaj bi lahko šlo narobe.
Pomembno! Postopek nadgradnje MySQL klasterja na osnovi Galere ima svoje posebnosti, ki niso opisane v tem članku. Te instrukcije ne uporabljajte v tem primeru.
Del 1: Preverjanje konfiguracij
V 8. različici MySQL so odstranili query_cache. V resnici je bil že v različici 5.7, zdaj pa je . Zato je potrebno odstraniti povezane direktive. Za predpomnjenje poizvedb pa lahko zdaj uporabite zunanja orodja — na primer, .
Prav tako so v konfiguraciji našli zastarele direktive o innodb_file_format. Če je bila v MySQL 5.7 možnost izbire formata InnoDB, 8. različica pa deluje .
Naš zaključek — odstranitev naslednjih direktiv:
-
query_cache_type,query_cache_limitinquery_cache_size; -
innodb_file_formatininnodb_file_format_max.
Za preverjanje bomo uporabili Docker sliko Percona Server. Konfiguracijo strežnika bomo postavili v imenik mysql_config_test, ob njem pa bomo ustvarili imenike za podatke in dnevniške datoteke. Primer testa konfiguracije percona-server:
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-centosNa koncu se bo v dnevnikih Dockerja ali v imeniku z dnevniki, odvisno od vaših nastavitev, pojavil datoteka, v kateri bodo opisane problematične direktive.
Tukaj je, kar smo imeli:
2020-04-03T12:44:19.670831Z 0 [Opozorilo] [MY-011068] [Strežnik] Sintaksa 'expire-logs-days' je zastarela in bo odstranjena v prihodnjem izdanju. Prosimo, da namesto tega uporabite binlog_expire_logs_seconds.
2020-04-03T12:44:19.671678Z 0 [Opozorilo] [MY-013242] [Strežnik] --character-set-server: 'utf8' je trenutno alias za niz znakov UTF8MB3, bo pa v prihodnjem izdanju alias za UTF8MB4. Razmislite o uporabi UTF8MB4, da ne bo zmede.
2020-04-03T12:44:19.671682Z 0 [Opozorilo] [MY-013244] [Strežnik] --collation-server: 'utf8_general_ci' je kolacija zastarelega niza znakov UTF8MB3. Razmislite o uporabi UTF8MB4 z ustrezno kolacijo namesto tega. Tako smo se morali dodatno ukvarjati s kodiranjem in zamenjati zastarelo direktivo expire-logs-days.
Del 2: Preverjanje delujočih namestitev
V dokumentaciji za nadgradnjo so na voljo 2 orodji za preverjanje baze na skladnost. Njihova uporaba pomaga administratorju, da preveri skladnost obstoječe strukture podatkov.
Začnimo s klasičnim orodjem mysqlcheck. Preprosto ga je treba zagnati:
mysqlcheck -u root -p --all-databases --check-upgradeČe težave niso odkrite, se orodje zaključi s kodo 0:

Poleg tega v sodobnih različicah MySQL obstaja orodje (v primeru Percone je to paket percona-mysql-shell). To je zamenjava klasičnega odjemalca mysql in združuje funkcije odjemalca, urejevalnika SQL kode in orodij za upravljanje MySQL. Za preverjanje strežnika pred nadgradnjo lahko preko nje izvedete naslednji ukaz:
mysqlsh -- util check-for-server-upgrade { --user=root --host=1.1.1.1 --port=3306 } --config-path=\/etc\/mysql\/my.cnfIn tukaj so ugotovitve, ki smo jih prejeli:

Na splošno ni nič kritičnega — le opozorila o kodiranju. (см. ниже)Skupni rezultat izvajanja:

Odločili smo se, da bi morala nadgradnja potekati brez težav.
Opomba o opozorilih zgoraj, ki kažejo na težave s kodiranjem. Dejstvo je, da UTF-8 v MySQL do nedavnega saj je hranila le 3 bajte namesto 4. V MySQL 8 so to končno alias utf8 bo kmalu vodil na kodiranje utf8mb4, stari stolpci v tabelah pa bodo postali utf8mb3.V prihodnje bo to kodiranje odstranjeno, vendar ne v tem izdanju. Zato smo se odločili, da popravimo kodiranja že na delujoči namestitvi SGBD, po njeni nadgradnji. utf8mb3. Del 3: Nadgradnja strežnikov
Часть 3: Обновление серверов
Kaj se lahko zgodi, ko imamo tako vrhunski načrt?.. Zavedajoč se, da se vedno pojavijo podrobnosti, smo prvi poskus izpeljali na dev-klasterju MySQL.
Kot smo že omenili, obravnava vprašanje nadgradnje MySQL strežnikov z replikami. Osnovna ideja je, da bi najprej morali nadgraditi vse replikate (slave), saj MySQL 8 lahko replicira z glavnim strežnikom različice 5.7. Nekaj zapletenosti nastane, ker uporabljamo način master master, kjer je oddaljeni glavni strežnik v načinu read-only. To pomeni, da dejanski promet poteka v en datacenter, drugi pa je rezervni.
Topologija je videti takole:

Nadgradnja se mora začeti z replikami mysql replica dc 2, mysql master dc 2 in mysql replica dc 1, končati pa mora na strežniku mysql master dc 1. Za večjo zanesljivost smo ustavili virtualne stroje, naredili njihove posnetke, in tik pred nadgradnjo ustavili replikacijo z ukazom STOP SLAVE. Ostalo pa izgledam takole:
- Vsako repliko znova zaženemo z dodatkom 3 možnosti v konfiguracijo:
skip-networking,skip-slave-start,skip-log-bin. Gre za to, da nadgradnja baze generira binarne dnevniške datoteke z obnovitvijo sistemskih tabel. Te direktive zagotavljajo, da v bazi ne bo sprememb podatkov aplikacije ter da v binarne dnevnike ne bo vstopila informacija o obnovitvi sistemskih tabel. To bo preprečilo težave pri ponovnem zagonu replikacije. - Nnamestimo paket
percona-server-server. Pomembno je omeniti, da v različici MySQL 8 ne je potrebno zagnati ukazmysqlupgradepo nadgradnji strežnika. - Po uspešnem zagonu še enkrat znova zaženemo strežnik — že brez parametrov, ki so bili dodani v prvem koraku.
- Preverimo, ali replikacija deluje uspešno: preverimo
SHOW SLAVE STATUSin si ogledamo, da se tabele s števcem v bazi aplikacije posodabljajo.
Vse to izgleda dovolj preprosto: nadgradnja dev je uspela. Okej, zdaj lahko brez skrbi načrtujemo nočno nadgradnjo za produkcijo.
Nobene skrbi — produkcijo smo nadgradili
Vendar prenos uspešne izkušnje dev na produkcijo ni šel brez presenečenj.
Na srečo se sam postopek nadgradnje začne z replikami, zato smo se ob težavah ustavili in obnovili repliko iz posnetka. Raziskovanje težav smo prestavili na naslednje jutro. V dnevnikih so se pojavili naslednji zapisi:
2020-01-14T21:43:21.500563Z 2 [ERROR] [MY-012069] [InnoDB] таблица: t1 имеет 19 колонок, но в словаре InnoDB 20 колонок
2020-01-14T21:43:21.500722Z 2 [ERROR] [MY-010767] [Сервер] Ошибка при исправлении данных SE для db1.t1
2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Сервер] Не удалось заполнить таблицы DD.
2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Сервер] Прерывание Исследование архивов различных почтовых рассылок в Google привело к пониманию, что такая проблема возникает из-за . Хотя скорее это даже баг утилит mysqlcheck in mysqlsh.
Оказывается, в MySQL сменили способ представления данных для десятичных полей (int, tinyint и т.п.), поэтому внутри mysql-server используется другой способ их хранения. Если ваша база данных изначально была в версии 5.5 или 5.1, а затем вы обновлялись до 5.7, то, возможно, требуется произвести OPTIMIZE для некоторых таблиц. Тогда MySQL обновит файлы с данными, переведя их на актуальный формат хранения.
Также это можно проверить утилитой 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',
... Если field_type у вас равен 0, то в таблице используется старый тип — надо проводить OPTIMIZE. Однако, если стоит значение 246 — у вас уже новый тип. Подробнее с типами можно ознакомиться в .
Более того, в рассматривается вторая возможная причина, которая обошла нас стороной, — это отсутствие InnoDB-таблиц в системной таблице INNODB_SYS_TABLESPACES, если они, таблицы, создавались в версии 5.1. Чтобы избежать проблем при обновлении, можно воспользоваться .
Почему же у нас не возникло таких проблем на dev? База туда периодически копируется с production — таким образом, таблицы пересоздаются.
К сожалению, на реально работающей большой БД не получится просто взять и выполнить повсеместный OPTIMIZE. Здесь поможет percona-toolkit: для операции online OPTIMIZE отлично подходит утилита pt-online-schema-change.
Обновленный план стал получился таким:
- Провести оптимизацию всех таблиц.
- Провести обновление баз данных.
Чтобы проверить его и заодно выяснить время обновления, мы отключили одну из реплик, а для всех таблиц запустили следующую команду:
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=t1Posodobitev tabel se izvaja brez dolgotrajnih zaklenitev, saj orodje ustvari novo začasno tabelo, v katero prenese podatke iz glavne tabele. Ko sta obe tabeli enaki, se izvirna tabela zaklene in nadomesti z novo. V našem primeru je testni zagon pokazal, da bo za posodobitev vseh tabel potrebnih približno 24 ur, vendar je prenos podatkov povzročal preveliko obremenitev na diskih.
Da bi to preprečili, smo na produkciji dodali ekipi argument --sleep z vrednostjo 10 — ta parameter ureja dolžino čakanja po prenosu serije podatkov v novo tabelo. S tem se lahko zmanjša obremenitev, če je dejansko delujoča aplikacija zahtevna glede časa odgovora.
Po optimizaciji je bila posodobitev uspešna.
… ampak ne povsem!
Že pol ure po posodobitvi se je stranka obrnila s težavo. Baza podatkov je delovala zelo nenavadno: občasno so se začela ponovna povezovanja. Tako je to izgledalo v monitoringu:

Na posnetku zaslona je vidna zobata krivulja, povezano s tem, da so delci strežnika MySQL občasno padali z napako. V aplikaciji so se pojavile napake:
[PDOException] SQLSTATE[HY000] [2002] Povezava zavrnjenaHitri pregled dnevnikov je pokazal, da daemons mysqld ni mogel pridobiti zahtevanih virov od operacijskega sistema. Ko smo raziskovali napake, smo odkrili v sistemu »brezskrben« datoteke politik 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 amd64Ti datoteke so nastale pri nadgradnji na MySQL 5.7 pred nekaj leti in pripadajo odstranjeni zbirki. Odstranitev datotek in ponovni zagon storitve apparmor je rešila problem:
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 apparmorNa záver
Kakršna koli, celo najpreprostejša operacija, lahko povzroči nepričakovane težave. In celo skrbno načrtovanje ne zagotavlja vedno želenega rezultata. Zdaj vsak načrt posodobitve vključuje tudi obvezno čiščenje odvečnih datotek, ki so lahko nastale kot rezultat prejšnjih dejanj.
In s tem ne prav profesionalnim grafičnim delom bi se rad zahvalil podjetju Percona za njihove odlične proizvode!

P.S.
Preberite tudi na našem blogu:
- «»;
- «»;
- «»;
- «»;
- «».
Izvor: habr.com
