Actualització de MySQL (Servidor Percona) de la 5.7 a la 8.0

Actualització de MySQL (Servidor Percona) de la 5.7 a la 8.0

El progrés no s'atura, de manera que les raons per actualitzar a les últimes versions de MySQL són cada cop més convincents. No fa molt, en un dels nostres projectes, era hora d'actualitzar els acollidors clústers de Percona Server 5.7 a la versió 8. Tot això va passar a la plataforma Ubuntu Linux 16.04. Com realitzar aquesta operació amb un temps d'inactivitat mínim i quins problemes hem trobat durant l'actualització: llegiu en aquest article.

Entrenament

Qualsevol actualització del servidor de bases de dades s'associa molt probablement amb la reconfiguració de la base de dades: canvis en els requisits dels límits dels recursos del sistema i correcció de les configuracions de la base de dades que s'han d'esborrar de directives obsoletes.

Abans d'actualitzar, definitivament ens referirem a la documentació oficial:

I elaborem un pla d'acció:

  1. Corregiu els fitxers de configuració eliminant les directives obsoletes.
  2. Comproveu la compatibilitat amb les utilitats.
  3. Actualitzeu les bases de dades esclaus instal·lant el paquet percona-server-server.
  4. Actualitzeu el mestre amb el mateix paquet.

Mirem cada punt del pla i veiem què podria sortir malament.

IMPORTANT! El procediment per actualitzar un clúster MySQL basat en Galera té les seves pròpies subtileses que no es descriuen a l'article. No hauríeu d'utilitzar aquesta instrucció en aquest cas.

Part 1: Comprovació de les configuracions

MySQL es va eliminar a la versió 8 query_cache. En realitat ho era declarat obsolet tornar a la versió 5.7, però ara esborrat completament. En conseqüència, cal eliminar les directives associades. I per emmagatzemar les sol·licituds a la memòria cau ara podeu utilitzar eines externes, per exemple, ProxySQL.

També a la configuració hi havia directives obsoletes sobre innodb_file_format. Si a MySQL 5.7 era possible seleccionar el format InnoDB, la 8a versió ja funciona només amb format Barracuda.

El nostre resultat és l'eliminació de les següents directives:

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

Per comprovar-ho, utilitzarem la imatge Docker de Percona Server. Col·locarem la configuració del servidor al directori mysql_config_test, i al costat crearem directoris per a dades i registres. Exemple de prova de configuració del servidor 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

Conclusió: ja sigui als registres de Docker o al directori amb els registres, segons les vostres configuracions, apareixerà un fitxer en el qual es descriuran les directrius problemàtiques.

Això és el que teníem:

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.

Per tant, encara calia esbrinar les codificacions i substituir la directiva obsoleta expire-logs-days.

Part 2: Comprovació de les instal·lacions de treball

La documentació d'actualització conté 2 utilitats per comprovar la compatibilitat de la base de dades. El seu ús ajuda l'administrador a comprovar la compatibilitat de l'estructura de dades existent.

Comencem amb la clàssica utilitat mysqlcheck. Simplement executeu:

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

Si no es troben problemes, la utilitat sortirà amb el codi 0:

Actualització de MySQL (Servidor Percona) de la 5.7 a la 8.0

A més, hi ha una utilitat disponible en les versions modernes de MySQL mysql-shell (en el cas de Percona aquest és el paquet percona-mysql-shell). És un reemplaçament del client mysql clàssic i combina les funcions d'un client, un editor de codi SQL i eines d'administració de MySQL. Per comprovar el servidor abans d'actualitzar-lo, podeu executar-hi les ordres següents:

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

Aquests són els comentaris que hem rebut:

Actualització de MySQL (Servidor Percona) de la 5.7 a la 8.0

En general, res crític: només advertències sobre codificacions (mirar abaix). Resultat global de l'execució:

Actualització de MySQL (Servidor Percona) de la 5.7 a la 8.0

Vam decidir que l'actualització hauria de fer-se sense problemes.

Una nota sobre les advertències anteriors que indica problemes amb les codificacions. El fet és que UTF-8 a MySQL fins fa poc no era "vertader" UTF-8, ja que només emmagatzemava 3 bytes en lloc de 4. A MySQL 8 això és finalment va decidir arreglar-ho: àlies utf8 aviat portarà a la codificació utf8mb4, i les columnes antigues de les taules es convertiran en utf8mb3. Més codificació utf8mb3 s'eliminarà, però no en aquesta versió. Per tant, vam decidir corregir les codificacions que ja hi havia a la instal·lació del SGBD en execució, després d'actualitzar-la.

Part 3: Actualitzacions del servidor

Què podria sortir malament quan hi ha un pla tan intel·ligent?... Entenent perfectament que els matisos sempre passen, vam realitzar el primer experiment en un clúster de desenvolupament de MySQL.

Com ja s’ha esmentat, documentació oficial tracta el problema de l'actualització dels servidors MySQL amb rèpliques. La conclusió és que primer hauríeu d'actualitzar totes les rèpliques (esclaus), ja que MySQL 8 es pot replicar des d'una versió mestra 5.7. Alguna dificultat rau en el fet que fem servir el mode mestre <-> mestre, quan el mestre remot està en mode Llegeix només. És a dir, de fet, el trànsit de combat va a un centre de dades i el segon és un de còpia de seguretat.

La topologia té aquest aspecte:

Actualització de MySQL (Servidor Percona) de la 5.7 a la 8.0

L'actualització ha de començar amb rèpliques rèplica mysql dc 2, mysql master dc 2 и mysql replica dc 1, i acabem amb el servidor mysql master dc 1. Per ser més fiables, vam aturar les màquines virtuals, vam fer-ne instantànies i immediatament abans de l'actualització vam aturar la replicació amb l'ordre STOP SLAVE. La resta de l'actualització té aquest aspecte:

  1. Reiniciem cada rèplica afegint 3 opcions a les configuracions: skip-networking, skip-slave-start, skip-log-bin. El fet és que l'actualització de la base de dades genera registres binaris amb actualitzacions de les taules del sistema. Aquestes directives garanteixen que no hi haurà canvis a les dades de l'aplicació a la base de dades i que la informació sobre l'actualització de les taules del sistema no s'inclourà als registres binaris. Això evitarà problemes en reprendre la rèplica.
  2. Instal·lació del paquet percona-server-server. És important tenir en compte que a MySQL versió 8 no heu d'executar l'ordre mysqlupgrade després de l'actualització del servidor.
  3. Després d'un inici correcte, reiniciem el servidor de nou, sense els paràmetres que es van afegir al primer paràgraf.
  4. Assegureu-vos que la rèplica funciona correctament: comproveu SHOW SLAVE STATUS i comproveu que s'actualitzen les taules amb comptadors de la base de dades de l'aplicació.

Tot sembla bastant senzill: l'actualització del desenvolupador va tenir èxit. D'acord, podeu programar amb seguretat una actualització nocturna per a la producció.

No hi havia tristesa: vam actualitzar el producte

No obstant això, la transferència de l'experiència de desenvolupament d'èxit a la producció no va estar exempta de sorpreses.

Afortunadament, el procés d'actualització en si comença amb rèpliques, de manera que quan vam trobar dificultats, vam aturar el treball i vam restaurar la rèplica des de la instantània. La investigació dels problemes es va ajornar fins al matí següent. Els registres contenien les entrades següents:

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

La recerca dels arxius de diverses llistes de correu a Google va portar a la comprensió que aquest problema es produeix a causa de Error de MySQL. Tot i que això és més probable que sigui un error d'utilitat mysqlcheck и mysqlsh.

Resulta que MySQL va canviar la forma en què representen les dades dels camps decimals (int, tinyint, etc.), de manera que mysql-server utilitza una manera diferent d'emmagatzemar-los. Si la vostra base de dades inicialment era a la versió 5.5 o 5.1, i després l'heu actualitzat a la 5.7, llavors potser haureu de fer OPTIMIZE per a algunes taules. Aleshores, MySQL actualitzarà els fitxers de dades, transferint-los al format d'emmagatzematge actual.

També podeu comprovar-ho amb la utilitat 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',
...

Si field_type Si el teniu igual a 0, a la taula s'utilitza el tipus antic; heu de dur a terme OPTIMIZE. Tanmateix, si el valor és 246, ja teniu un tipus nou. Podeu trobar més informació sobre els tipus a codi.

A més, a aquest error Estem considerant la segona raó possible, que ens va passar per alt: l'absència de taules InnoDB a la taula del sistema INNODB_SYS_TABLESPACES, si aquestes, taules, es van crear a la versió 5.1. Per evitar problemes durant l'actualització, podeu utilitzar script SQL adjunt.

Per què no vam tenir aquests problemes al desenvolupament? La base de dades es copia periòdicament des de la producció; així, es recreen taules.

Malauradament, en una base de dades gran que funciona, no podreu prendre i executar un universal OPTIMIZE. percona-toolkit ajudarà aquí: la utilitat pt-online-schema-change és excel·lent per a l'operació en línia OPTIMIZE.

El pla actualitzat tenia aquest aspecte:

  1. Optimitzar totes les taules.
  2. Actualitzar les bases de dades.

Per comprovar-ho i al mateix temps esbrinar l'hora d'actualització, vam desactivar una de les rèpliques i vam executar l'ordre següent per a totes les taules:

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

Les taules s'actualitzen sense bloquejos llargs a causa del fet que la utilitat crea una nova taula temporal a la qual copia les dades de la taula principal. En el moment en què les dues taules són idèntiques, la taula original es bloqueja i es substitueix per la nova. En el nostre cas, una prova va demostrar que es trigaria aproximadament un dia a actualitzar totes les taules, però la còpia de dades va provocar massa càrrega als discs.

Per evitar-ho, en producció hem afegit l'argument a l'ordre --sleep amb un valor de 10: aquest paràmetre ajusta la durada d'espera després de transferir un lot de dades a una taula nova. D'aquesta manera podeu reduir la càrrega si l'aplicació real en execució exigeix ​​el temps de resposta.

Després de realitzar l'optimització, l'actualització va tenir èxit.

... però no del tot!

En mitja hora després de l'actualització, el client va presentar un problema. La base de dades funcionava de manera molt estranya: començaven periòdicament restableix la connexió. Aquest és el que semblava en el seguiment:

Actualització de MySQL (Servidor Percona) de la 5.7 a la 8.0

La captura de pantalla mostra un gràfic de dent de serra a causa del fet que alguns dels fils del servidor MySQL s'estavellaven periòdicament amb un error. S'han produït errors a l'aplicació:

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

Una inspecció ràpida dels registres va revelar que el dimoni mysqld no podia obtenir els recursos necessaris del sistema operatiu. Mentre resolem errors, vam descobrir al sistema fitxers de polítiques d'aparcar "orfes".:

# 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

Aquests fitxers es van crear quan es va actualitzar a MySQL 5.7 fa un parell d'anys i pertanyen a un paquet eliminat. L'eliminació dels fitxers i la reinici del servei d'apparmor van resoldre el problema:

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

en conclusió

Qualsevol operació, fins i tot la més senzilla, pot provocar problemes inesperats. I fins i tot tenir un pla ben pensat no sempre garanteix el resultat esperat. Ara, tots els plans d'actualització que tingui el nostre equip també inclouen la neteja obligatòria d'arxius innecessaris que podrien haver aparegut com a conseqüència d'accions recents.

I amb aquesta creativitat gràfica poc professional, m'agradaria donar les gràcies a Percona pels seus excel·lents productes!

Actualització de MySQL (Servidor Percona) de la 5.7 a la 8.0

PS

Llegeix també al nostre blog:

Font: www.habr.com

Afegeix comentari