Actualizando MySQL (Servidor Percona) de 5.7 a 8.0

Actualizando MySQL (Servidor Percona) de 5.7 a 8.0

O progreso non se detén, polo que os motivos para actualizar ás últimas versións de MySQL son cada vez máis convincentes. Non hai moito, nun dos nosos proxectos, era hora de actualizar os acolledores clústeres de Percona Server 5.7 á versión 8. Todo isto ocorreu na plataforma Ubuntu Linux 16.04. Como realizar tal operación cun tempo de inactividade mínimo e que problemas atopamos durante a actualización - lea neste artigo.

Adestramento

Calquera actualización do servidor de base de datos está asociada moi probablemente coa reconfiguración da base de datos: cambios nos requisitos para os límites de recursos do sistema e corrección das configuracións da base de datos que deben borrarse das directivas obsoletas.

Antes de actualizar, definitivamente remitirémonos á documentación oficial:

E imos elaborar un plan de acción:

  1. Corrixa os ficheiros de configuración eliminando directivas obsoletas.
  2. Comprobe a compatibilidade coas utilidades.
  3. Actualiza as bases de datos de escravos instalando o paquete percona-server-server.
  4. Actualiza o mestre co mesmo paquete.

Vexamos cada punto do plan e vexamos que pode saír mal.

IMPORTANTE! O procedemento para actualizar un clúster de MySQL baseado en Galera ten as súas propias sutilezas que non se describen no artigo. Non debe usar esta instrución neste caso.

Parte 1: Comprobación da configuración

MySQL foi eliminado na versión 8 query_cache. En realidade era declarado obsoleto de volta na versión 5.7, pero agora completamente eliminado. En consecuencia, é necesario eliminar as directivas asociadas. E para almacenar as solicitudes na caché agora podes usar ferramentas externas, por exemplo, ProxySQL.

Tamén na configuración había directivas obsoletas sobre innodb_file_format. Se en MySQL 5.7 era posible seleccionar o formato InnoDB, entón xa funciona a 8ª versión só con formato Barracuda.

O noso resultado é a eliminación das seguintes directivas:

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

Para comprobalo, utilizaremos a imaxe Docker de Percona Server. Colocaremos a configuración do servidor no directorio mysql_config_test, e xunto a el crearemos directorios para datos e rexistros. Exemplo de proba de configuración do 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ón: ben nos rexistros de Docker ou no directorio cos rexistros -en función das súas configuracións- aparecerá un ficheiro no que se describirán as directivas problemáticas.

Aquí está o que tiñamos:

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.

Así, aínda necesitabamos descubrir as codificacións e substituír a directiva obsoleta expire-logs-days.

Parte 2: Comprobación das instalacións de traballo

A documentación de actualización contén 2 utilidades para comprobar a compatibilidade da base de datos. O seu uso axuda ao administrador a comprobar a compatibilidade da estrutura de datos existente.

Comecemos coa clásica utilidade mysqlcheck. Simplemente executa:

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

Se non se atopan problemas, a utilidade pechará co código 0:

Actualizando MySQL (Servidor Percona) de 5.7 a 8.0

Ademais, hai unha utilidade dispoñible nas versións modernas de MySQL mysql-shell (no caso de Percona este é o paquete percona-mysql-shell). É un substituto do clásico cliente mysql e combina as funcións dun cliente, un editor de código SQL e ferramentas de administración de MySQL. Para comprobar o servidor antes de actualizar, pode executar os seguintes comandos a través del:

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

Estes son os comentarios que recibimos:

Actualizando MySQL (Servidor Percona) de 5.7 a 8.0

En xeral, nada crítico - só avisos sobre codificacións (Ver abaixo). Resultado xeral da execución:

Actualizando MySQL (Servidor Percona) de 5.7 a 8.0

Decidimos que a actualización debería ir sen problemas.

Unha nota sobre as advertencias anteriores que indica problemas coas codificacións. O caso é que UTF-8 en MySQL ata hai pouco non era "verdadero" UTF-8, xa que só almacenaba 3 bytes en lugar de 4. En MySQL 8 isto é finalmente posible decidiu solucionalo: alias utf8 pronto levará á codificación utf8mb4, e as columnas antigas das táboas pasarán a ser utf8mb3. Codificación adicional utf8mb3 eliminarase, pero non nesta versión. Polo tanto, decidimos corrixir as codificacións xa na instalación do DBMS en execución, despois de actualizalo.

Parte 3: Actualizacións do servidor

Que podería saír mal cando hai un plan tan intelixente?... Entendendo ben que os matices sempre ocorren, realizamos o primeiro experimento nun clúster de desenvolvemento de MySQL.

Como xa se mencionou, documentación oficial trata o tema da actualización dos servidores MySQL con réplicas. A conclusión é que primeiro debes actualizar todas as réplicas (escravos), xa que MySQL 8 pode replicarse desde unha versión mestra 5.7. Algunha dificultade reside no feito de que utilizamos o modo mestre mestre, cando o mestre remoto está en modo só lectura. É dicir, de feito, o tráfico de combate vai a un centro de datos e o segundo é un backup.

A topoloxía ten o seguinte aspecto:

Actualizando MySQL (Servidor Percona) de 5.7 a 8.0

A actualización debe comezar con réplicas réplica mysql dc 2, mysql master dc 2 и mysql replica dc 1, e rematamos co servidor mysql master dc 1. Para ser máis fiables, paramos as máquinas virtuais, tomamos instantáneas delas e inmediatamente antes da actualización paramos a replicación co comando STOP SLAVE. O resto da actualización ten o seguinte aspecto:

  1. Reiniciamos cada réplica engadindo 3 opcións ás configuracións: skip-networking, skip-slave-start, skip-log-bin. O feito é que a actualización da base de datos xera rexistros binarios con actualizacións das táboas do sistema. Estas directivas garanten que non haberá cambios nos datos da aplicación na base de datos e que a información sobre a actualización das táboas do sistema non se incluirá nos rexistros binarios. Isto evitará problemas ao retomar a replicación.
  2. Instalando o paquete percona-server-server. É importante ter en conta que en MySQL versión 8 non cómpre executar o comando mysqlupgrade despois da actualización do servidor.
  3. Despois dun inicio exitoso, reiniciamos o servidor de novo, sen os parámetros que se engadiron no primeiro parágrafo.
  4. Asegurámonos de que a replicación funciona correctamente: comproba SHOW SLAVE STATUS e ver que as táboas con contadores na base de datos da aplicación están actualizadas.

Todo parece bastante sinxelo: a actualización do dev foi exitosa. Ok, podes programar con seguridade unha actualización nocturna para a produción.

Non había tristeza - actualizamos o produto

Non obstante, a transferencia da experiencia de desenvolvemento exitosa á produción non estivo exenta de sorpresas.

Afortunadamente, o proceso de actualización en si comeza coas réplicas, polo que cando atopamos dificultades, paramos o traballo e restauramos a réplica desde a instantánea. A investigación dos problemas aprazouse ata a mañá seguinte. Os rexistros contiñan as seguintes entradas:

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 investigación dos arquivos de varias listas de correo en Google levou a entender que este problema ocorre debido a Error de MySQL. Aínda que isto é máis probable que sexa un erro de utilidade mysqlcheck и mysqlsh.

Resulta que MySQL cambiou a forma en que representan os datos para os campos decimais (int, tinyint, etc.), polo que mysql-server usa un xeito diferente de almacenalos. Se a súa base de datos inicialmente estaba na versión 5.5 ou 5.1, e despois actualizou a 5.7, entón é posible que teñas que facer OPTIMIZE para algunhas táboas. A continuación, MySQL actualizará os ficheiros de datos, transfiríndoos ao formato de almacenamento actual.

Tamén pode comprobar isto coa utilidade 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',
...

Se field_type Se o ten igual a 0, na táboa utilízase o tipo antigo - cómpre realizar OPTIMIZE. Non obstante, se o valor é 246, xa tes un novo tipo. Pódese atopar máis información sobre os tipos en código.

Ademais, en este erro Estamos considerando a segunda razón posible, que nos pasou por alto: a ausencia de táboas InnoDB na táboa do sistema INNODB_SYS_TABLESPACES, se elas, táboas, foron creadas na versión 5.1. Para evitar problemas ao actualizar, pode usar script SQL anexo.

Por que non tivemos tales problemas no desenvolvemento? A base de datos cópiase alí periodicamente desde a produción; así, recréanse táboas.

Desafortunadamente, nunha base de datos grande que funciona, non poderás simplemente tomar e executar un universal OPTIMIZE. percona-toolkit axudará aquí: a utilidade pt-online-schema-change é excelente para a operación OPTIMIZE en liña.

O plan actualizado quedou así:

  1. Optimizar todas as táboas.
  2. Actualizar as bases de datos.

Para comprobalo e ao mesmo tempo coñecer a hora de actualización, desactivamos unha das réplicas e executamos o seguinte comando para todas as táboas:

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

As táboas actualízanse sen bloqueos longos debido ao feito de que a utilidade crea unha nova táboa temporal na que copia os datos da táboa principal. No momento en que ambas táboas son idénticas, a táboa orixinal está bloqueada e substitúese pola nova. No noso caso, unha execución de proba mostrou que levaría aproximadamente un día actualizar todas as táboas, pero copiar datos provocou demasiada carga nos discos.

Para evitar isto, en produción engadimos o argumento ao comando --sleep cun valor de 10: este parámetro axusta a duración de espera despois de transferir un lote de datos a unha nova táboa. Deste xeito, pode reducir a carga se a aplicación en execución real esixe o tempo de resposta.

Despois de realizar a optimización, a actualización foi exitosa.

... pero non completamente!

Dentro de media hora despois da actualización, o cliente veu cun problema. A base de datos funcionaba de forma moi estraña: comezaban periodicamente restablece a conexión. Este é o que parecía no seguimento:

Actualizando MySQL (Servidor Percona) de 5.7 a 8.0

A captura de pantalla mostra un gráfico de dente de serra debido ao feito de que algúns dos fíos do servidor MySQL fallaban periódicamente cun erro. Apareceron erros na aplicación:

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

Unha inspección rápida dos rexistros revelou que o daemon mysqld non puido obter os recursos necesarios do sistema operativo. Ao resolver os erros, descubrimos no sistema Ficheiros de políticas de aparellos "orfos".:

# 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

Estes ficheiros creáronse ao actualizar a MySQL 5.7 hai un par de anos e pertencen a un paquete eliminado. Eliminar os ficheiros e reiniciar o servizo de apparmor resolveu o 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ón

Calquera operación, incluso a operación máis sinxela, pode levar a problemas inesperados. E mesmo ter un plan ben pensado non sempre garante o resultado esperado. Agora, calquera plan de actualización que teña o noso equipo tamén inclúe a limpeza obrigatoria de ficheiros innecesarios que puideran aparecer como resultado de accións recentes.

E con esta creatividade gráfica pouco profesional, gustaríame darlle as grazas a Percona polos seus excelentes produtos!

Actualizando MySQL (Servidor Percona) de 5.7 a 8.0

PS

Lea tamén no noso blog:

Fonte: www.habr.com

Engadir un comentario