Atraso da replicação

Nesta página, descrevemos como resolver problemas e corrigir atrasos de replicação para réplicas de leitura do Cloud SQL.

Visão geral

As réplicas de leitura do Cloud SQL usam a replicação baseada em linha do MySQL usando identificadores globais de transação (GTIDs, na sigla em inglês). As alterações são gravadas no registro binário da instância principal e enviadas à réplica, onde são recebidas e aplicadas ao banco de dados.

O atraso da replicação pode acontecer em alguns cenários, como:

  • A instância principal não pode enviar as alterações com rapidez suficiente para a réplica.
  • A réplica não recebe as alterações com rapidez suficiente.
  • A réplica não pode aplicar as alterações com rapidez suficiente.
Use a métrica network_lag para monitorar os dois primeiros cenários em que a instância principal não pode enviar alterações com rapidez suficiente ou a réplica não pode receber alterações rápido o suficiente.

O atraso total é observado com a métrica replica_lag. A diferença entre replica_lag e network_lag pode indicar o terceiro motivo quando a réplica não pode aplicar as alterações de replicação com rapidez suficiente. Essas métricas são descritas na seção Monitorar atraso da replicação abaixo.

Configuração de réplica mais rápida

Há duas maneiras de fazer uma réplica do MySQL aplicar alterações com mais rapidez. Os usuários podem configurar as réplicas com as seguintes opções:

  • Replicação paralela
  • Limpeza de alto desempenho

Replicação paralela

A replicação paralela pode ajudar o atraso de replicação configurando a réplica para usar várias linhas de execução em paralelo para aplicar alterações na réplica. Para mais informações sobre como usar a replicação paralela, consulte Como configurar a replicação paralela.

Ao ativar a replicação paralela definindo a flag replica_parallel_workers (ou slave_parallel_workers), considere o seguinte:

  • Recomendamos definir o valor da flag replica_parallel_workers como um número que corresponda à contagem de vCPUs da instância de réplica. Definir um valor muito alto pode causar esperas de bloqueio, tempos limite de espera de bloqueio e impasses. Se você observar picos de espera de bloqueio alinhados com o atraso de replicação, considere reduzir o paralelismo.
  • Se a versão do MySQL for compatível com a flag binlog_transaction_dependency_tracking, defina-a como WRITESET para a instância principal. Esse é o comportamento padrão para a versão 8.4 e mais recentes.

Limpeza de alto desempenho

Por padrão, o Cloud SQL para MySQL limpa os registros de refazer no disco após cada transação para garantir a durabilidade. A limpeza de alto desempenho reduz a frequência com que os registros de refazer são apagados para o disco uma vez por segundo. Isso pode ajudar a melhorar o desempenho de gravação na réplica, reduzindo a E/S do disco.

Defina a sinalização innodb_flush_log_at_trx_commit na réplica de leitura como 2. Se o registro binário estiver ativado para a réplica, para ajudar a tornar a flag innodb_flush_log_at_trx_commit eficaz, recomendamos definir a flag sync_binlog com um valor alto, por exemplo, 10.000.

Para mais informações sobre esta sinalização, consulte Dicas para trabalhar com sinalizações.

Quando a sinalização innodb_flush_log_at_trx_commit é definida na réplica de leitura e o Cloud SQL detecta que pode ter ocorrido uma falha, o Cloud SQL recria automaticamente a réplica.

Verificar se a réplica está provisionada adequadamente

Uma instância de réplica menor que a instância principal (por exemplo, com menos vCPUs e memória) pode ter um atraso na replicação. Uma réplica menor também pode ter flags de configuração padrão diferentes em comparação com uma instância principal maior. Recomendamos que a instância de réplica seja pelo menos tão grande quanto a instância principal para ter recursos suficientes para lidar com a carga de replicação.

A alta utilização da CPU na réplica também pode causar atraso na replicação. Se a utilização da CPU da réplica estiver alta (por exemplo, acima de 90%), considere aumentar a capacidade da CPU da réplica.

Use o comando SHOW VARIABLES para conferir a configuração da réplica e da instância principal e compará-las para identificar diferenças. Por exemplo, uma réplica menor não pode configurar o innodb_buffer_pool_size para ter o mesmo valor da principal, o que pode afetar o desempenho da réplica.

Otimizar consultas e esquema

Nesta seção, sugerimos algumas otimizações comuns de consulta e esquema que podem ser feitas para melhorar o desempenho da replicação.

Nível de isolamento da consulta na réplica de leitura

Os níveis de isolamento de transação REPEATABLE READ e SERIALIZABLE adquirem bloqueios que possam bloquear as mudanças de replicação. Considere reduzir o nível de isolamento das consultas na réplica. O nível de isolamento da transação READ COMMITTED pode ter um desempenho melhor.

Transações de longa duração no banco de dados principal

Transações de longa duração na instância principal podem causar atraso na replicação. O registro binário não é enviado para a réplica até que a transação seja confirmada.

Se um grande número de linhas for atualizado em uma única transação, isso poderá causar um pico repentino no número de alterações que precisam ser aplicadas à instância principal e enviadas para a réplica. Isso se aplica a atualizações ou exclusões de instruções únicas que afetam muitas linhas de uma vez. As alterações são enviadas à réplica depois de serem confirmadas. Aplicar um pico repentino de alterações na réplica pode aumentar a possibilidade de contenção de bloqueio na réplica se a carga de consulta na réplica também for alta, levando a atraso na replicação.

Considere dividir transações grandes em várias transações menores. Para monitorar transações de longa duração, verifique a métrica cloudsql.googleapis.com/database/mysql/innodb/active_trx_longest_time no servidor principal.

Chaves primárias ausentes

As réplicas de leitura do Cloud SQL usam a replicação baseada em linha, que tem um desempenho insatisfatório se as tabelas MySQL replicadas não têm chaves primárias. Recomendamos que todas as tabelas replicadas tenham chaves primárias.

Para o MySQL 8 ou versões posteriores, recomendamos que você defina a sinalização sql_require_primary_key como ON para exigir que as tabelas no seu banco de dados tenham chaves primárias.

Transações de longa duração na réplica de leitura

Transações de longa duração na réplica, como instruções SELECT, podem bloquear ou diminuir a velocidade da replicação. A verificação de tabela é um problema comum. Investigue consultas de longa duração e considere otimizá-las. Essas consultas podem aumentar o tamanho da lista do histórico de InnoDB.

Tamanho excessivo do histórico de InnoDB

Uma lista de histórico InnoDB muito grande pode causar problemas de desempenho e diminuir a velocidade da replicação. É possível monitorar o tamanho da lista de histórico usando a métrica cloudsql.googleapis.com/database/mysql/innodb/history_list_length. Essa métrica também pode ser alta no primário e já estar causando problemas de desempenho. Se, após a inicialização, a réplica mostrar sinais de alto atraso de replicação, esse pode ser o motivo.

Uma lista de histórico grande pode ser causada pelo seguinte:

  • Transações de longa duração. Transações de longa duração ou inativas impedem a limpeza de entradas antigas de registros "undo".
  • Desempenho lento do disco. A exclusão permanente é uma operação com uso intensivo de E/S.
  • Nível de isolamento REPEATABLE READ. Isso pode contribuir para o crescimento da lista de histórico.
  • Configuração de limpeza insuficiente.O parâmetro innodb_purge_threads, que controla o número de linhas de execução dedicadas à limpeza, pode estar definido como muito baixo para a carga de trabalho.

Para resolver isso, tente o seguinte:

  • Divida transações grandes em menores. Permite a limpeza mais rápida de registros antigos.
  • Use uma instância maior. Instâncias maiores têm mais CPU e memória.
  • Ajuste as configurações de exclusão. Aumente innodb_purge_threads, innodb_io_capacity e innodb_io_capacity_max.
  • Use o nível de isolamento READ COMMITTED.
  • Verifique se as tabelas têm chaves primárias. Tabelas sem chaves primárias podem causar verificações de tabela, o que pode diminuir a velocidade da replicação e contribuir para o crescimento da lista de histórico.

Grande quantidade de espera de bloqueio

Um grande número de espera de bloqueios na réplica pode diminuir a velocidade da replicação, principalmente com a replicação paralela ativada. É possível monitorar esperas de bloqueio e deadlocks usando as seguintes métricas:

  • cloudsql.googleapis.com/database/mysql/innodb/row_lock_waits_count
  • cloudsql.googleapis.com/database/mysql/innodb/row_lock_time
  • cloudsql.googleapis.com/database/mysql/innodb/lock_timeout_count
  • cloudsql.googleapis.com/database/mysql/innodb/deadlocks_count

Se essas métricas de bloqueio estiverem muito altas e parecerem correlacionadas com o atraso de replicação, considere reduzir o valor da flag replica_parallel_workers. O nível de isolamento também pode afetar os bloqueios.

Bloqueios exclusivos devido a DDL

Os comandos da linguagem de definição de dados (DDL), como ALTER TABLE e CREATE INDEX, podem causar atraso de replicação na réplica devido a bloqueios exclusivos. Para evitar a contenção de bloqueio, programe a execução do DDL quando a carga da consulta for menor nas réplicas.

Considere usar o recurso DDL on-line do MySQL 8.0.

Réplica sobrecarregada

Se uma réplica de leitura estiver recebendo muitas consultas, a replicação poderá ser bloqueada. Divida as leituras entre várias réplicas para reduzir a carga em cada uma.

Para evitar picos de consulta, limite as consultas de leitura de réplica na lógica do aplicativo ou em uma camada de proxy, se usar uma.

Se houver picos de atividade na instância principal, considere distribuir as atualizações.

Banco de dados primário monolítico

Considere fragmentar o banco de dados primário verticalmente (ou horizontalmente) para impedir que uma ou mais tabelas atrasadas retenham todas as outras tabelas.

Monitorar atraso de replicação

Use as métricas replica_lag e network_lag para monitorar a atraso da replicação e identificar se a causa do atraso está no banco de dados principal, na rede ou na réplica.

MétricaDescrição
Atraso da replicação
(cloudsql.googleapis.com/database/replication/replica_lag)

O número de segundos em que o estado da réplica está atrasado em relação ao estado da instância principal. Essa é a diferença entre o horário atual e o carimbo de data/hora original em que o banco de dados primário confirmou a transação que está sendo aplicada na réplica. Em particular, as gravações podem ser contadas com atraso, mesmo que tenham sido recebidas pela réplica, se a réplica ainda não tiver aplicado a gravação ao banco de dados.

Essa métrica informa o valor de Seconds_Behind_Master quando SHOW SLAVE STATUS é executado na réplica. Para mais informações, consulte Como verificar o status da replicação no Manual de referência do MySQL.

Número do último erro da linha de execução de E/S
(cloudsql.googleapis.com/database/mysql/replication/last_io_errno)

Indica o último erro que causou a falha da linha de execução de E/S. Se ele for diferente de zero, a replicação estará corrompida. Isso é raro, mas pode acontecer. Verifique a documentação do MySQL para entender o que o código do erro indica. Por exemplo, os arquivos binlog na instância principal podem ter sido excluídos antes de serem recebidos pela réplica. O Cloud SQL geralmente recria automaticamente a réplica se a replicação estiver corrompida. Esta métrica last_io_errno pode explicar o motivo.

Número do último erro de linha de execução SQL
(cloudsql.googleapis.com/database/mysql/replication/last_sql_errno)

Indica o último erro que causou a falha da linha de execução SQL. Se ele for diferente de zero, a replicação estará corrompida. Isso é raro, mas pode acontecer. Verifique a documentação do MySQL para entender o que o código do erro indica. Normalmente, o Cloud SQL recriará automaticamente a réplica se a replicação estiver corrompida. Esta métrica last_sql_errno pode explicar o motivo.

Atraso da rede
(cloudsql.googleapis.com/database/replication/network_lag)

O tempo, em segundos, desde a gravação do binlog no banco de dados primário até a linha de execução de E/S na réplica.

Se a network_lag for zero ou insignificante, mas a replica_lag for alta, isso indica que a linha de execução SQL não pode aplicar mudanças de replicação com rapidez suficiente.

Verificar a replicação

Para verificar se a replicação está funcionando, execute a seguinte instrução na réplica:

mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
               Slave_IO_State: Queueing master event to the relay log
                  Master_Host: xx.xxx.xxx.xxx
                  Master_User: cloudsqlreplica
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.199927
          Read_Master_Log_Pos: 83711956
               Relay_Log_File: relay-log.000025
                Relay_Log_Pos: 24214376
        Relay_Master_Log_File: mysql-bin.199898
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 24214163
              Relay_Log_Space: 3128686571
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: Yes
           Master_SSL_CA_File: master_server_ca.pem
           Master_SSL_CA_Path: /mysql/datadir
              Master_SSL_Cert: replica_cert.pem
            Master_SSL_Cipher:
               Master_SSL_Key: replica_pkey.pem
        Seconds_Behind_Master: 2627
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 321071839
                  Master_UUID: 437d04e9-8456-11e8-b13d-42010a80027b
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: System lock
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set: 437d04e9-8456-11e8-b13d-42010a80027b:52111095710-52120776390
            Executed_Gtid_Set: 437d04e9-8456-11e8-b13d-42010a80027b:1-52113039508
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

Se a replicação estiver acontecendo, a primeira coluna, Slave_IO_State, vai mostrar Waiting for master to send event ou uma mensagem semelhante. Além disso, o campo Last_IO_Error está vazio.

Se a replicação não estiver acontecendo, a coluna Slave_IO_State mostrará o status Connecting to master e a coluna Last_IO_Error mostrará o status error connecting to master cloudsqlreplica@x.x.x.x:3306.

De acordo com a documentação do MySQL (em inglês), alguns outros campos interessantes relacionados ao atraso de replicação incluem:

CampoDescrição
Master_Log_File
O nome do arquivo de registros binários de origem que a linha de execução de E/S está lendo no momento.
Read_Master_Log_Pos
A posição no arquivo de registros binário de origem atual que a linha de execução de E/S leu.
Relay_Log_File
O nome do arquivo de registros de redirecionamento que a linha de execução SQL lê e executa no momento.
Relay_Log_Pos
A posição no arquivo de registros de redirecionamento atual que a linha de execução SQL lê e executa até o momento.
Relay_Master_Log_File
O nome do arquivo de registros binários de origem que contém o evento mais recente executado pela linha de execução SQL.

No exemplo anterior, Relay_Master_Log_File tem o valor mysql-bin.199898. Master_Log_File tem o valor mysql-bin.199927. O sufixo numérico 199898 é menor que 199927. Isso significa que, mesmo que a réplica tenha recebido um arquivo de registro mysql-bin.199927 mais recente, ela ainda está aplicando a mysql-bin.199898 mais antiga.

Nesse caso, a linha de execução do SQL está atrasada na réplica.

Você também pode se conectar ao banco de dados primário e executar:

  SHOW MASTER STATUS;

Este comando mostra qual arquivo binlog está sendo gravado no banco de dados principal.

Se o arquivo de registros binários do banco de dados principal for mais recente que o Master_Log_File na réplica, isso significa que a linha de execução de E/S está atrasada. A réplica ainda está lendo um arquivo de registro binário mais antigo do banco de dados principal.

Quando a linha de execução de E/S estiver atrasada, a métrica network_lag também será alta. Quando a linha de execução do SQL estiver atrasada, mas a linha de execução de E/S não, a métrica network_lag não será tão alta, mas a replica_lag será alta.

Os comandos anteriores permitem observar os detalhes do atraso enquanto o atraso está acontecendo, mas as métricas network_lag e replica_lag fornecem uma maneira de analisar as ocorrências anteriores do atraso.

Recriar réplica atrasada

Recrie uma réplica atrasada quando a replicação ficar abaixo de um período aceitável.

Com o Cloud SQL, é possível configurar a réplica de leitura para se recriar se a replicação ficar atrasada (ou for adiada) por um período de tempo inaceitável e se esse atraso persistir por pelo menos cinco minutos.

Se você definir um atraso de replicação aceitável como sendo inferior a 360 segundos (seis minutos) e um atraso de replicação de pelo menos 361 segundos persistir por mais de cinco minutos, após cinco minutos, a instância principal vai criar um novo snapshot dela mesma, e a réplica de leitura será recriada usando esse snapshot.

Recriar uma réplica de leitura atrasada oferece os seguintes benefícios:

  • Você controla o que é considerado um intervalo aceitável para o atraso de replicação.
  • É possível reduzir o tempo gasto na solução de problemas de atraso de replicação em horas ou até dias.

Outros detalhes do recurso:

  • Compatível com as seguintes versões:
    • MySQL 5.7
    • MySQL 8.0
    • MySQL 8.4
  • Um intervalo aceitável para atraso ou demora na replicação precisa ser definido em segundos.
  • O valor mínimo aceitável é de 300 segundos ou cinco minutos.
  • O valor máximo aceitável é de 31.536.000 segundos ou um ano.
    • Se você ativar a recriação de réplica atrasada para uma instância, mas não definir o atraso máximo aceitável de replicação, o Cloud SQL usará o valor padrão de um ano.
  • Tipos de instâncias compatíveis:
    • Réplica de leitura
    • Réplica de leitura entre regiões
    • Réplica em cascata
  • O valor definido para o campo replicationLagMaxSeconds é específico de cada instância de réplica. Se uma instância principal tiver várias instâncias de réplica, você poderá definir cada uma com um valor diferente.
  • Quando uma réplica é recriada, os usuários podem esperar um tempo de inatividade enquanto as seguintes operações são concluídas:
    • A replicação é interrompida.
    • A réplica é excluída.
    • Um snapshot da instância principal é criado.
    • A réplica é recriada com base nesse snapshot mais recente. A nova réplica usa o mesmo nome e endereço IP da anterior. Como resultado, o MySQL precisa ser interrompido e reiniciado.
    • A nova réplica começa a replicar dados.
  • O replicationLagMaxSeconds é um campo no nível da instância. Cada instância tem um valor próprio.
  • Se você tiver várias réplicas de leitura para a mesma instância principal, poderá definir um valor exclusivo para o campo replicationLagMaxSeconds em cada réplica.

    Definir diferentes limites de tempo para diferentes réplicas pode ajudar a evitar um cenário em que todas as réplicas fiquem inativas ao mesmo tempo.

Ativar a recriação de réplica atrasada

O recurso de recriação de réplica atrasada fica desativado por padrão. Para ativar esse recurso ao criar uma instância, use um dos seguintes métodos:

gcloud

Use o comando gcloud sql instances create para criar uma nova instância de réplica de leitura com a flag
--replication-lag-max-seconds-for-recreate:

gcloud beta sql instances create REPLICA_INSTANCE_NAME \
  --master-instance-name=PRIMARY_INSTANCE_NAME \
  --database-version=DATABASE_VERSION \
  --tier=TIER \
  --edition=EDITION \
  --region=REGION \
  --root-password=PASSWORD \
  --replication-lag-max-seconds-for-recreate=REPLICATION_LAG_MAX_SECONDS

Em que:

  • REPLICA_INSTANCE_NAME é o nome da instância de réplica.
  • PRIMARY_INSTANCE_NAME é o nome da instância principal.
  • DATABASE_VERSION é a versão do banco de dados da instância. Por exemplo, MYSQL_8_0_31.
  • TIER é o tipo de máquina que você quer usar para a instância de réplica. Por exemplo, db-perf-optimized-N-4. Para mais informações, consulte Configurações de instância personalizadas.
  • EDITION é a edição que você quer usar para a instância de réplica. Por exemplo, ENTERPRISE_PLUS. Para mais informações, consulte Criar uma instância.
  • REGION é a região que você quer usar para a instância de réplica. Por exemplo, us-central1.
  • PASSWORD é a senha de root da instância.
  • REPLICATION_LAG_MAX_SECONDS é o atraso ou a defasagem máxima aceitável da replicação em segundos. Por exemplo, 600. O valor mínimo aceitável é de 300 segundos ou cinco minutos. O valor máximo aceitável é de 31.536.000 segundos ou um ano.

API REST

O campo replicationLagMaxSeconds está localizado no recurso DatabaseInstance. Adicione este campo ao corpo da solicitação:

{
  "settings": {
  "replicationLagMaxSeconds" :REPLICATION_LAG_MAX_SECONDS,
  }
  ...
}

Em que:

  • REPLICATION_LAG_MAX_SECONDS é o atraso ou a defasagem máxima aceitável de replicação em segundos. Por exemplo, 600.

Atualizar o período de recriação do atraso de replicação

Para conferir as configurações de uma instância, use qualquer um dos métodos descritos em Ver informações resumidas da instância.

Com essas informações, você pode escolher se quer ou não atualizar o período de atraso de replicação especificado como aceitável antes da recriação da réplica.

gcloud

Use o comando gcloud sql instances patch para atualizar o período de recriação da instância com base no atraso de replicação:

gcloud beta sql instances patch INSTANCE_NAME \
  --replication-lag-max-seconds-for-recreate=REPLICATION_LAG_MAX_SECONDS

Em que:

  • INSTANCE_NAME é o nome da instância;
  • REPLICATION_LAG_MAX_SECONDS é o atraso ou a defasagem máxima aceitável da replicação em segundos. Por exemplo, 700. Se você quiser reverter para o valor padrão de um ano, insira 31536000. O valor mínimo aceitável é de 300 segundos ou cinco minutos. O valor máximo aceitável é de 31.536.000 segundos ou um ano.

API REST

A política pode ser atualizada usando instances.patch e instance.insert.

Para ver um exemplo de como atualizar a configuração usando a API REST, consulte Editar uma instância.

Limitações

As seguintes limitações se aplicam à recriação de réplicas atrasadas:

  • Os valores de replicationLagMaxSeconds só podem ser definidos em segundos.
  • Os índices criados na réplica de leitura antes de uma operação de recriação não são mantidos. Se um índice existir, crie um índice secundário depois que a réplica for recriada.
  • Para evitar tempos de inatividade frequentes nas réplicas de leitura, as recriações são limitadas a uma por dia por instância.
  • Réplicas de servidores externos não são compatíveis com esse recurso.
  • Se você ativar a recriação de réplicas atrasadas em uma réplica em cascata, o Cloud SQL vai recriar primeiro as réplicas de folha para manter a consistência da replicação.
  • A recriação de uma réplica entre regiões gera um custo adicional.
  • Não é possível ativar a recriação de réplicas atrasadas no console Google Cloud .

Qual é a próxima etapa?