MySQL (Percona Server) eguneratzea 5.7tik 8.0ra

MySQL (Percona Server) eguneratzea 5.7tik 8.0ra

Aurrerapena ez da gelditzen, beraz, MySQL-ren azken bertsioetara eguneratzeko arrazoiak gero eta sinesgarriagoak dira. Duela gutxi, gure proiektuetako batean, Percona Server 5.7 kluster erosoak 8 bertsiora eguneratzeko garaia iritsi zen. Hau guztia Ubuntu Linux 16.04 plataforman gertatu zen. Nola egin eragiketa hori gutxieneko geldialdiarekin eta zein arazo aurkitu genituen eguneratzean - irakurri artikulu honetan.

Prestakuntza

Datu-basearen zerbitzariaren edozein eguneratze datu-basearen birkonfigurazioarekin lotuko da ziurrenik: sistema-baliabideen mugen eskakizunen aldaketak eta zaharkitutako zuzentarauetatik garbitu behar diren datu-baseen konfigurazioen zuzenketa.

Eguneratu aurretik, zalantzarik gabe, dokumentazio ofiziala aipatuko dugu:

Eta egin dezagun ekintza plan bat:

  1. Zuzendu konfigurazio-fitxategiak zuzentarau zaharkituak kenduz.
  2. Egiaztatu utilitateekin bateragarritasuna.
  3. Eguneratu esklaboen datu-baseak paketea instalatuz percona-server-server.
  4. Eguneratu maisua pakete berarekin.

Ikus ditzagun planaren puntu bakoitza eta ikus dezagun zer oker egon daitekeen.

GARRANTZITSUA! Galeran oinarritutako MySQL kluster bat eguneratzeko prozedurak bere Γ±abardurak ditu, artikuluan azaltzen ez direnak. Ez zenuke argibide hau erabili behar kasu honetan.

1. zatia: konfigurazioak egiaztatzea

MySQL 8. bertsioan kendu zen query_cache. Egia esan zen zaharkitutzat jo itzuli 5.7 bertsioan, baina orain guztiz ezabatu da. Horren arabera, beharrezkoa da lotutako zuzentarauak kentzea. Eta eskaerak cacheatzeko orain kanpoko tresnak erabil ditzakezu, adibidez, ProxySQL.

Era berean, konfigurazioan buruzko zuzentarau zaharkituak zeuden innodb_file_format. MySQL 5.7-n InnoDB formatua hautatzea posible bazen, 8. bertsioak dagoeneko funtzionatzen du Barracuda formatuan bakarrik.

Gure emaitza honako zuzentarau hauek kentzea da:

  • query_cache_type, query_cache_limit ΠΈ query_cache_size;
  • innodb_file_format ΠΈ innodb_file_format_max.

Egiaztatzeko, Percona Server-en Docker irudia erabiliko dugu. Zerbitzariaren konfigurazioa direktorioan jarriko dugu mysql_config_test, eta ondoan datu eta erregistroetarako direktorioak sortuko ditugu. Percona-zerbitzariaren konfigurazio probaren adibidea:

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

Beheko lerroa: Docker erregistroetan edo erregistroak dituen direktorioan - zure konfigurazioen arabera - fitxategi bat agertuko da eta bertan zuzentarau problematikoak deskribatuko dira.

Hona hemen zer genuen:

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.

Horrela, oraindik kodeketak irudikatu eta zaharkitutako direktiba ordezkatu behar genuen expire-logs-days.

2. zatia: Lan-instalazioak egiaztatzea

Eguneratze-dokumentazioak datu-basea bateragarritasuna egiaztatzeko 2 utilitate ditu. Horien erabilerak administratzaileari lehendik dagoen datu-egituraren bateragarritasuna egiaztatzen laguntzen dio.

Has gaitezen mysqlcheck utilitate klasikoarekin. Besterik gabe, exekutatu:

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

Arazorik aurkitzen ez bada, utilitatea 0 kodearekin irtengo da:

MySQL (Percona Server) eguneratzea 5.7tik 8.0ra

Horrez gain, MySQL-ren bertsio modernoetan erabilgarritasun bat dago eskuragarri mysql-shell (Perconaren kasuan hau da paketea percona-mysql-shell). Mysql bezero klasikoaren ordezkoa da eta bezero baten funtzioak, SQL kode editorea eta MySQL administrazio tresnak konbinatzen ditu. Zerbitzaria eguneratu aurretik egiaztatzeko, komando hauek exekutatu ditzakezu haren bidez:

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

Hona hemen jaso ditugun iruzkinak:

MySQL (Percona Server) eguneratzea 5.7tik 8.0ra

Oro har, ez da ezer kritikoa - kodetzeei buruzko abisuak soilik (ikus behean). Exekuzio emaitza orokorra:

MySQL (Percona Server) eguneratzea 5.7tik 8.0ra

Eguneratzea arazorik gabe joan behar zela erabaki genuen.

Goiko abisuei buruzko ohar bat kodeketekin arazoak adierazten dituena. Kontua da UTF-8 MySQL-en duela gutxi arte ez zen "egia" UTF-8, 3 byte baino ez baitzituen gordetzen 4. MySQL 8-n hau da azkenean konpontzea erabaki zuen: ezizena utf8 laster kodetzea ekarriko du utf8mb4, eta tauletako zutabe zaharrak bihurtuko dira utf8mb3. Kodeketa gehiago utf8mb3 kendu egingo da, baina ez bertsio honetan. Hori dela eta, dagoeneko martxan dagoen DBMS instalazioan dauden kodeketak zuzentzea erabaki dugu, eguneratu ondoren.

3. zatia: zerbitzariaren eguneraketak

Zer gaizki joan liteke halako plan adimenduna dagoenean?... Γ±abardurak beti gertatzen direla ondo ulertuta, lehenengo esperimentua egin genuen MySQL garatzaileen kluster batean.

Esan bezala, dokumentazio ofiziala MySQL zerbitzariak erreplikekin eguneratzearen gaia lantzen du. Beheko lerroa da lehenik eta behin erreplika guztiak (esklaboak) eguneratu behar dituzula, MySQL 8 5.7 bertsio maisu batetik errepikatu daitekeelako. Zailtasun batzuk modua erabiltzean datza maisu <-> maisu, urruneko maisua moduan dagoenean irakurtzeko soilik. Hau da, hain zuzen ere, borroka-trafikoa datu-zentro batera doa, eta bigarrena babeskopia bat da.

Topologia honen itxura du:

MySQL (Percona Server) eguneratzea 5.7tik 8.0ra

Eguneraketak erreplikekin hasi behar du mysql erreplika dc 2, mysql master dc 2 ΠΈ mysql replica dc 1, eta mysql master dc 1 zerbitzariarekin amaitu. Fidagarriagoa izateko, makina birtualak gelditu, argazkiak atera ditugu eta berehala eguneratzea komandoarekin erreplikatzea gelditu dugu. STOP SLAVE. Gainerako eguneraketak honelako itxura du:

  1. Erreplika bakoitza berrabiaraziko dugu konfigurazioei 3 aukera gehituz: skip-networking, skip-slave-start, skip-log-bin. Kontua da datu-basea eguneratzeak sistema-taulen eguneratzeekin erregistro bitarrak sortzen dituela. Zuzentarau hauek datu-basean aplikazioen datuetan aldaketarik izango ez dela bermatzen dute, eta sistema-taulak eguneratzeari buruzko informazioa ez da erregistro bitarretan sartuko. Honek arazoak saihestuko ditu erreplikazioa berriro hastean.
  2. Paketea instalatzen percona-server-server. Garrantzitsua da kontuan izan MySQL 8 bertsioan ez komandoa exekutatu behar duzu mysqlupgrade zerbitzaria eguneratu ondoren.
  3. Arrakastaz hasi ondoren, zerbitzaria berriro berrabiaraziko dugu, lehen paragrafoan gehitutako parametrorik gabe.
  4. Erreplikazioak ongi funtzionatzen duela ziurtatzen dugu: egiaztatu SHOW SLAVE STATUS eta ikusi aplikazioaren datu-baseko kontagailuak dituzten taulak eguneratuta daudela.

Guztiak nahiko erraza dirudi: garatzaileen eguneratzea arrakastatsua izan da. Ados, segurtasunez programatu dezakezu gaueko eguneraketa ekoizpenerako.

Ez zegoen tristurarik - prod eguneratu dugu

Hala ere, garapen arrakastatsuaren esperientzia ekoizpenera transferitzea ez zen sorpresarik izan.

Zorionez, eguneratze-prozesua bera erreplikekin hasten da, beraz, zailtasunak aurkitu genituenean, lana gelditu eta argazkitik erreplika berreskuratu genuen. Arazoen ikerketa hurrengo goizera arte atzeratu zuten. Erregistroek sarrera hauek zituzten:

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

Google-ko hainbat posta-zerrendaren artxiboak ikertzeak arazo hau dela eta gertatzen dela ulertu zuen MySQL akatsa. Hau erabilgarritasun akats bat izan daitekeen arren mysqlcheck ΠΈ mysqlsh.

Bihurtzen da MySQL-k eremu hamartarretarako datuak irudikatzeko modua aldatu zuela (int, tinyint, etab.), beraz, mysql-server-ek beste modu bat erabiltzen du horiek gordetzeko. Zure datu-basea bada Hasieran 5.5 edo 5.1 bertsioan zegoen eta gero 5.7ra eguneratu zenuen, baliteke egin behar izatea OPTIMIZE mahai batzuetarako. Ondoren, MySQL-k datu-fitxategiak eguneratuko ditu, uneko biltegiratze formatura transferituz.

Hau erabilgarritasunarekin ere egiaztatu dezakezu 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',
...

Bada field_type 0 berdina baduzu, mota zaharra erabiltzen da taulan - egin behar duzu OPTIMIZE. Hala ere, balioa 246 bada, dagoeneko mota berri bat duzu. Motei buruzko informazio gehiago hemen aurki daiteke kodea.

Gainera, akats hau Bigarren arrazoi posiblea aztertzen ari gara, alde batera utzi gaituena: sistemako taulan InnoDB taularik ez egotea. INNODB_SYS_TABLESPACES, horiek, taulak, 5.1 bertsioan sortu badira. Eguneratzean arazoak saihesteko, erabil dezakezu erantsitako SQL scripta.

Zergatik ez genuen horrelako arazorik izan garapenean? Datu-basea aldian-aldian kopiatzen da produkziotik - horrela, taulak birsortzen dira.

Zoritxarrez, benetan funtzionatzen duen datu-base handi batean, ezin izango duzu unibertsal bat hartu eta exekutatu OPTIMIZE. percona-toolkit-ek hemen lagunduko du: pt-online-schema-change utilitatea bikaina da lineako OPTIMIZE eragiketarako.

Eguneraturiko planak itxura hau zuen:

  1. Optimizatu taula guztiak.
  2. Eguneratu datu-baseak.

Egiaztatzeko eta, aldi berean, eguneratze-denbora jakiteko, errepliketako bat desgaitu eta hurrengo komandoa exekutatu dugu taula guztietarako:

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

Taulak blokeo luzerik gabe eguneratzen dira, erabilgarritasunak aldi baterako taula berri bat sortzen duelako eta bertan taula nagusiko datuak kopiatzen dituen. Bi mahai berdinak diren unean, jatorrizko taula blokeatu eta berriarekin ordezkatzen da. Gure kasuan, proba-exekuzio batek taula guztiak eguneratzeko egun bat inguru beharko zuela erakutsi zuen, baina datuak kopiatzeak karga gehiegi eragiten zuen diskoetan.

Hori ekiditeko, ekoizpenean argumentua gehitu diogu komandoari --sleep 10 balioarekin - parametro honek itxaronaldia doitzen du datu sorta bat taula berri batera transferitu ondoren. Horrela karga murriztu dezakezu exekutatzen ari den aplikazioak erantzun denbora eskatzen badu.

Optimizazioa egin ondoren, eguneratzea arrakastatsua izan da.

... baina ez guztiz!

Eguneratzetik ordu erdira, bezeroa arazo batekin etorri zen. Datu-baseak oso arraro funtzionatu zuen: aldian-aldian hasten ziren konexioa berrezarri. Hau da jarraipenaren itxura:

MySQL (Percona Server) eguneratzea 5.7tik 8.0ra

Pantaila-argazkiak zerra-hortz grafiko bat erakusten du, MySQL zerbitzariaren hari batzuk aldian-aldian errore batekin huts egiten zirelako. Akatsak agertu dira aplikazioan:

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

Erregistroen ikuskapen azkar batek agerian utzi zuen mysqld deabruak ezin zituela lortu sistema eragiletik beharrezko baliabideak. Akatsak konpontzean, sisteman aurkitu dugu "Umezurtz" apaindura-gidalerroen fitxategiak:

# 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

Fitxategi hauek MySQL 5.7ra eguneratzean sortu ziren duela pare bat urte eta kendutako pakete batekoak dira. Fitxategiak ezabatzeak eta apparmor zerbitzua berrabiarazteak arazoa konpondu zuen:

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

Ondorioz

Edozein eragiketarik sinpleenak ere, ustekabeko arazoak sor ditzake. Eta ondo pentsatutako plan bat edukitzeak ez du beti espero den emaitza bermatzen. Orain, gure taldeak duen edozein eguneratze planek azken ekintzen ondorioz ager zitezkeen alferrikako fitxategien derrigorrezko garbiketa ere barne hartzen dute.

Eta sormen grafiko ez oso profesional honekin, eskerrik asko esan nahi nizkioke Perconari bere produktu bikainengatik!

MySQL (Percona Server) eguneratzea 5.7tik 8.0ra

PS

Irakurri ere gure blogean:

Iturria: www.habr.com

Gehitu iruzkin berria