Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Tempo de início lento do MySQL no modo GTID? O tamanho do arquivo de log binário pode ser o problema

Você tem experimentado tempos de inicialização lentos do MySQL no modo GTID? Recentemente, encontramos esse problema em uma de nossas implantações de hospedagem MySQL e resolvemos resolvê-lo. Neste blog, detalhamos o problema que pode estar diminuindo os tempos de reinicialização do MySQL, como depurar para sua implantação e o que você pode fazer para diminuir o tempo de início e melhorar sua compreensão da replicação baseada em GTID.

Como encontramos o problema

Estávamos investigando tempos de inicialização lentos do MySQL em uma implantação baixa do MySQL 5.7.21 baseada em disco que tinha o modo GTID ativado. O sistema fazia parte de um par mestre-escravo e estava sob uma carga de gravação moderada. Ao reiniciar durante uma manutenção programada, notamos que o servidor de banco de dados levou de 5 a 10 minutos para inicializar e começar a aceitar conexões. Esse tipo de atraso não fazia sentido, então começamos a investigar.

Depurando seu tempo de início lento do MySQL

Usamos a popular ferramenta Percona pt-ioprofile para ver o que o banco de dados estava fazendo. pt-ioprofile é um utilitário muito importante no popular kit de ferramentas da Percona usado para depurar problemas do MySQL, e você pode ver a lista completa de recursos na documentação deles. O pt-ioprofile ferramenta usa strace e lsof para observar a E/S de um processo e imprimir uma tabela de arquivos e atividades de E/S.

Então, iniciamos o MySQL, esperamos pelo mysqld processo para ser gerado e iniciado pt-ioprofile para ver qual pode ser o problema:

# pt-ioprofile --profile-process mysqld --run-time 200
Tue Oct 9 15:42:24 UTC 2018
Tracing process ID 18677
total      pread       read     pwrite      write      fsync  fdatasync       open      close   getdents      lseek      fcntl filename
...
216.550641   0.000000  216.550565   0.000000   0.000000   0.000000   0.000000   0.000015   0.000040   0.000000   0.000021   0.000000 /mysql_data/binlogs/mysql-bin.000014
...

O que está retardando a reinicialização do MySQL?

Ao executar isso várias vezes, observamos o seguinte:

  • O mysqld processo estava gastando a maior parte do tempo lendo o arquivo de log binário mais recente. Esse foi o caso mesmo quando o servidor foi interrompido normalmente e não houve necessidade de uma recuperação de falhas etc.
  • O servidor também gastou uma quantidade considerável de tempo carregando os arquivos de dados do InnoDB, mas esse tempo foi muito menor comparado ao tempo gasto lendo o arquivo de log binário mais recente.
  • Se o servidor fosse reiniciado imediatamente, essa reinicialização subsequente seria muito mais rápida.
  • Como o desligamento do banco de dados libera o log binário e cria um novo na inicialização, fizemos um experimento adicional – antes de desligar o servidor, liberamos os logs binários. A inicialização subsequente do servidor foi rápida novamente.

Estas observações apontaram claramente para o fato de que o MySQL estava gastando muito tempo lendo o último arquivo de log binário. Se o arquivo for pequeno, como seria quando o arquivo de registro foi liberado antes de um desligamento, a inicialização foi rápida.

Tempo de início lento do MySQL no GTID? O tamanho do arquivo de log binário pode ser o problemaClique para Tweet

Compreendendo a recuperação do Binlog GTID

Como se vê, para preencher os valores de gtid_executed e gtid_purged, o servidor MySQL deve analisar os arquivos de log binários.

Aqui está o resumo da recomendação do método de documentação do MySQL 5.7 com base em uma leitura FALSE ou TRUE:

Quando binlog_gtid_simple_recovery =FALSO:

Para calcular gtid_executed:

  • Iterar arquivos de log binários do mais recente, parando no primeiro arquivo que tem um Previous_gtids_log_event entrada.
  • Consumir todos os GTIDs de Previous_gtids_log_event e Gtid_log_events deste arquivo de log binário e armazene esse conjunto de GTID internamente. Ele é chamado de gtids_in_binlog.
  • Valor de gtid_executed é calculado como a união de gtids_in_binlog e os GTIDs na tabela mysql.gtid_executed .

Esse processo pode ser muito demorado se houver um grande número de arquivos de registro binários sem GTIDs, por exemplo, criados quando gtid_mode =DESLIGADO.

Da mesma forma, para calcular gtid_purged:

  • Itera arquivos de log binários do mais antigo para o mais novo, parando no primeiro log binário que contém um Previous_gtids_log_event não vazio (tem pelo menos um GTID) ou que tenha pelo menos um Gtid_log_event .
  • Leia Previous_gtids_log_event deste arquivo. Calcular a variável interna gtids_in_binlog_not_purged como este conjunto de GTID subtraído de gtids_in_binlog.
  • Valor de gtid_purged está definido como gtid_executed , menos gtids_in_binlog_not_purged .

Então, isso forma a base do nosso entendimento sobre como as coisas costumavam funcionar em versões mais antigas. No entanto, algumas otimizações podem ser feitas quando binlog_gtid_simple_recovery é verdade. Este é o caso que nos interessa:

Quando binlog_gtid_simple_recovery =VERDADEIRO:

(Observe, este é o padrão no MySQL 5.7.7 e posterior)

  • Leia apenas os arquivos de log binários mais antigos e os mais recentes.
  • Cálculo gtid_purged do Previous_gtids_log_event ou Gtid_log_event encontrado no arquivo de log binário mais antigo.
  • Calcular gtid_executed do Previous_gtids_log_event ou Gtid_log_event encontrado no arquivo de log binário mais recente.
  • Assim, apenas dois arquivos de log binários são lidos durante a reinicialização do servidor ou ao limpar registros binários.

Então, para o MySQL versões 5.7.7 e superiores, os arquivos de log binários mais recentes e antigos são sempre lidos durante a inicialização do sistema para inicializar corretamente as variáveis ​​de sistema GTID. Ler o arquivo de log binário mais antigo não é tão caro, pois o evento que o MySQL está procurando, Previous_gtids_log_event, é sempre o primeiro evento em um arquivo de log binário.

No entanto, para calcular corretamente gtid_executed , o servidor deve ler todo o arquivo de log binário mais recente e coletar todos os eventos nesse arquivo. Assim, o tempo de inicialização do sistema se torna diretamente proporcional ao tamanho do arquivo de log binário mais recente .

Observe que a situação é ainda pior quando binlog_gtid_simple_recovery é FALSO . Como não é mais a opção padrão em versões recentes, não é uma grande preocupação.

Como resolver seu tempo de início lento

Tendo entendido a causa do problema que estávamos enfrentando, a solução que decidimos era bastante óbvia – reduzir o tamanho dos arquivos de log binários. O tamanho padrão dos arquivos de log binários é 1 GB. Leva tempo para analisar um arquivo desse tamanho durante a inicialização, então faz sentido diminuir o valor de max_binlog_size para um valor mais baixo.

Se diminuir o tamanho do arquivo de log binário não for uma opção, então liberar os arquivos de log binários logo antes de um desligamento de manutenção do processo mysqld pode ajudar para diminuir os tempos de recuperação do binlog GTID.