Experiência prática atualizando o MySQL 5.7 para a versão 8.0

imagem

Recentemente, atualizamos nossos servidores do MySQL 5.7 para 8.0.

Vamos deixar de fora o escopo deste artigo, por que e quais novos pães apareceram no MySQL 8.0, mas, em vez disso, falaremos sobre as dificuldades que encontramos durante o processo de atualização.

Em primeiro lugar, antes de atualizar, vale a pena examinar a lista de alterações e corrigir o seu arquivo de configuração.

No mínimo, as seguintes opções foram excluídas:
innodb_file_format, innodb_file_format_check, innodb_file_format_max, innodb_large_prefix
query_cache_limit, query_cache_min_res_unit, query_cache_size, query_cache_type, query_cache_wlock_invalidate.

No parâmetro sql_mode, em particular, NO_AUTO_CREATE_USER foi excluído - o que é especialmente importante, porque no MySQL 5.7, estava ativado por padrão.

A Percona possui instruções para atualização no local. E, no caso geral, você pode segui-lo, no entanto, conseguimos atualizar apenas um cluster dessa maneira; de resto, uma tentativa de atualizar isso falhou com um erro semelhante:

2019-06-22T05:04:18.510888Z 1 [ERROR] [MY-011014] [Server] Found partially upgraded DD. Aborting upgrade and deleting all DD tables. Start the upgrade process again. 2019-06-22T05:04:23.115018Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed. 2019-06-22T05:04:23.115655Z 0 [ERROR] [MY-010119] [Server] Aborting 

Portanto, atualizamos os clusters restantes, criando uma nova instância vazia e restaurando o dump do banco de dados da versão anterior.

Para fazer isso, primeiro, você precisa de um despejo de banco de dados. E aqui o perigo # 1 aguarda - um despejo feito da maneira padrão:

 mysqldump -u root -p --hex-blob --default-character-set=utf8mb4 --all-databases --triggers --routines --events > dump.sql 

não se recupera dando um erro:

 ERROR 3554 (HY000) at line 15915: Access to system table 'mysql.innodb_index_stats' is rejected. 

A descrição está no rastreador de erros do MySQL (com o status Not a bug :), também há conselhos sobre como despejá-lo para que possa ser restaurado:

 mysqldump -u root -p --hex-blob --default-character-set=utf8mb4 --all-databases --triggers --routines --events --ignore-table=mysql.innodb_index_stats --ignore-table=mysql.innodb_table_stats > dump.sql 

Mas, ao tentar usar esse despejo, se houvesse gatilhos (e nós os tínhamos), o perigo número 2 poderia ser esperado, na forma de um erro:

 ERROR 1231 (42000) at line 54: Variable 'sql_mode' can't be set to the value of 'NO_AUTO_CREATE_USER' 

A razão para isso é porque o MySQL usa sql_mode para acionadores, a saber: O MySQL salva o valor sql_mode para o acionador no momento em que é criado e, em seguida, sempre o executa com esse valor. E, consequentemente, salva esse valor em um despejo.

Descrição da ajuda para isso:
dev.mysql.com/doc/refman/8.0/en/create-trigger.html
O MySQL armazena a configuração da variável de sistema sql_mode em vigor quando um gatilho é criado e sempre executa o corpo do gatilho com essa configuração em vigor, independentemente do modo SQL do servidor atual quando o gatilho começa a ser executado.

O que fazemos? Acabamos de cortar NO_AUTO_CREATE_USER do despejo finalizado. Comando semelhante:

 sed "s/50003 SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER/50003 SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO/g" dump.sql > dump2.sql 

Depois disso, o dump é restaurado com sucesso, mas o perigo nº 3 nos espera (a verdade esperada) - as tabelas do sistema foram restauradas para o estado a partir da versão 5.7 e temos os seguintes erros nos logs:

 [ERROR] [MY-013143] [Server] Column count of mysql.user is wrong. Expected 51, found 45. The table is probably corrupted 

Da experiência com versões anteriores, isso é tratado executando mysql_upgrade - mas desde a versão 8.0.16 - isso não funciona, porque mysql_upgrade é declarado obsoleto e não faz nada.

Agora, para fazer com que as tabelas do sistema sejam atualizadas, você deve iniciar o MySQL com a opção upgrade = FORCE .

No ubuntu novo, isso pode ser feito da seguinte maneira:

 systemctl set-environment MYSQLD_OPTS="--upgrade=FORCE" 

Então reinicie o MySQL. Bem, após uma atualização bem-sucedida, exclua-a:

 systemctl unset-environment MYSQLD_OPTS 

Source: https://habr.com/ru/post/pt476852/


All Articles