Configurar a replicação no MySQL é fácil, mas gerenciá-la em produção nunca foi uma tarefa fácil. Mesmo com o posicionamento automático GTID mais recente, ainda pode dar errado se você não souber o que está fazendo. Depois de configurar a replicação, todos os tipos de coisas podem dar errado. Erros podem ser cometidos facilmente e podem ter um final desastroso para seus dados.
Este post destacará alguns dos erros mais comuns cometidos com a replicação do MySQL e como você pode evitá-los.
Configurando a replicação
Ao configurar a replicação do MySQL, você precisa preparar os nós escravos com o conjunto de dados do mestre. Com soluções como o cluster Galera, isso é tratado automaticamente para você com o método de sua escolha. Para a replicação do MySQL, você precisa fazer isso sozinho, então, naturalmente, você pega sua ferramenta de backup padrão.
Para MySQL existe uma enorme variedade de ferramentas de backup disponíveis, mas a mais usada é o mysqldump. O Mysqldump gera um backup lógico do conjunto de dados do seu mestre. Isso significa que a cópia dos dados não será uma cópia binária, mas um arquivo grande contendo consultas para recriar seu conjunto de dados. Na maioria dos casos, isso deve fornecer uma cópia (quase) idêntica de seus dados, mas há casos em que isso não ocorre - devido ao despejo ser feito por objeto. Isso significa que, mesmo antes de você começar a replicar os dados, seu conjunto de dados não é igual ao do mestre.
Existem alguns ajustes que você pode fazer para tornar o mysqldump mais confiável, como dump como uma única transação, e também não se esqueça de incluir rotinas e gatilhos:
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > dumpfile.sql
Uma boa prática é verificar se o seu nó slave está 100% igual, é usando pt-table-checksum após configurar a replicação:
pt-table-checksum --replicate=test.checksums --ignore-databases mysql h=localhost,u=user,p=pass
Esta ferramenta irá calcular um checksum para cada tabela no mestre, replicar o comando para o escravo e então o nó escravo realizará a mesma operação de checksum. Se alguma das tabelas não for a mesma, isso deve ser claramente visível na tabela de soma de verificação.
Usando o método de replicação errado
O método de replicação padrão do MySQL era a chamada replicação baseada em instruções. Esse método é exatamente o que é:um fluxo de replicação de cada instrução executada no mestre que será reproduzido no nó escravo. Como o MySQL em si é multi-thread, mas sua replicação (tradicional) não é, a ordem das instruções no fluxo de replicação pode não ser 100% a mesma. Além disso, a repetição de uma instrução pode fornecer resultados diferentes quando não executada exatamente ao mesmo tempo.
Isso pode resultar em diferentes conjuntos de dados entre o mestre e o escravo, devido ao desvio de dados. Isso não foi um problema por muitos anos, já que muitos não executavam o MySQL com muitos threads simultâneos, mas com arquiteturas modernas de várias CPUs, isso realmente se tornou altamente provável em uma carga de trabalho normal do dia-a-dia.
A resposta do MySQL foi a chamada replicação baseada em linha. A replicação baseada em linha replicará os dados sempre que possível, mas em alguns casos excepcionais ainda usará instruções. Um bom exemplo seria a alteração da DLL de uma tabela, onde a replicação teria que copiar todas as linhas da tabela por meio da replicação. Como isso é ineficiente, tal afirmação será replicada da maneira tradicional. Quando a replicação baseada em linha detecta o desvio de dados, ela interrompe o encadeamento escravo para evitar que as coisas piorem.
Depois, há um método entre esses dois:replicação de modo misto. Esse tipo de replicação sempre replicará instruções, exceto quando a consulta contém a função UUID(), gatilhos, procedimentos armazenados, UDFs e algumas outras exceções são usadas. O modo misto não resolverá o problema de desvio de dados e, juntamente com a replicação baseada em instruções, deve ser evitado.
Replicação Circular
A execução da replicação do MySQL com vários mestres geralmente é necessária se você tiver um ambiente de vários datacenters. Como o aplicativo não pode esperar que o mestre no outro datacenter reconheça sua gravação, é preferível um mestre local. Normalmente, o deslocamento de incremento automático é usado para evitar conflitos de dados entre os mestres. Fazer com que dois mestres executem gravações entre si dessa maneira é uma solução amplamente aceita.
Replicação MySQL mestre-mestre
No entanto, se você precisar gravar em vários datacenters no mesmo banco de dados, terá vários mestres que precisam gravar seus dados entre si. Antes do MySQL 5.7.6 não havia nenhum método para fazer uma replicação do tipo mesh, então a alternativa seria usar uma replicação em anel circular.
Topologia de replicação em anel MySQL
A replicação de anel no MySQL é problemática pelos seguintes motivos:latência, alta disponibilidade e desvio de dados. Escrevendo alguns dados no servidor A, seriam necessários três saltos para terminar no servidor D (via servidor B e C). Como a replicação (tradicional) do MySQL é de encadeamento único, qualquer consulta de longa execução na replicação pode travar todo o anel. Além disso, se algum dos servidores cair, o anel será quebrado e, atualmente, não há software de failover que possa reparar as estruturas do anel. Então, o desvio de dados pode ocorrer quando os dados são gravados no servidor A e são alterados ao mesmo tempo no servidor C ou D.
Replicação de anel quebrado
Em geral, a replicação circular não é adequada ao MySQL e deve ser evitada a todo custo. O Galera seria uma boa alternativa para gravações em vários datacenters, pois foi projetado com isso em mente.
Parando sua replicação com grandes atualizações
Muitas vezes, vários trabalhos em lote de limpeza executam várias tarefas, desde a limpeza de dados antigos até o cálculo de médias de 'curtidas' obtidas de outra fonte. Isso significa que, em intervalos definidos, um trabalho criará muita atividade no banco de dados e, provavelmente, gravará muitos dados de volta no banco de dados. Naturalmente, isso significa que a atividade no fluxo de replicação aumentará igualmente.
A replicação baseada em instrução replicará as consultas exatas usadas nos trabalhos em lote, portanto, se a consulta levar meia hora para ser processada no mestre, o encadeamento escravo ficará parado pelo menos o mesmo período de tempo. Isso significa que nenhum outro dado pode ser replicado e os nós escravos começarão a ficar atrás do mestre. Se isso exceder o limite de sua ferramenta de failover ou proxy, ele poderá descartar esses nós escravos dos nós disponíveis no cluster. Se você estiver usando a replicação baseada em instrução, poderá evitar isso processando os dados do seu trabalho em lotes menores.
Agora você pode pensar que a replicação baseada em linha não é afetada por isso, pois replicará as informações da linha em vez da consulta. Isso é parcialmente verdade, pois para alterações de DDL, a replicação é revertida para o formato baseado em instrução. Além disso, um grande número de operações CRUD afetará o fluxo de replicação:na maioria dos casos, essa ainda é uma operação de encadeamento único e, portanto, cada transação aguardará que a anterior seja reproduzida via replicação. Isso significa que, se você tiver alta simultaneidade no mestre, o escravo poderá travar na sobrecarga de transações durante a replicação.
Para contornar isso, o MariaDB e o MySQL oferecem replicação paralela. A implementação pode diferir por fornecedor e versão. O MySQL 5.6 oferece replicação paralela desde que as consultas sejam separadas por esquema. Tanto o MariaDB 10.0 quanto o MySQL 5.7 podem lidar com a replicação paralela entre esquemas, mas têm outros limites. A execução de consultas por meio de threads escravos paralelos pode acelerar seu fluxo de replicação se você estiver gravando muito. No entanto, se você não estiver, seria melhor manter a replicação tradicional de thread único.
Mudanças de esquema
Realizar alterações de esquema em uma configuração de produção em execução é sempre uma dor. Isso tem a ver com o fato de que uma alteração de DDL na maioria das vezes bloqueará uma tabela e só liberará esse bloqueio quando a alteração de DDL for aplicada. Fica ainda pior quando você começa a replicar essas alterações de DDL por meio da replicação do MySQL, onde, além disso, paralisa o fluxo de replicação.
Uma solução frequentemente usada é aplicar a mudança de esquema aos nós escravos primeiro. Para replicação baseada em instrução, isso funciona bem, mas para replicação baseada em linha, isso pode funcionar até certo ponto. A replicação baseada em linha permite que existam colunas extras no final da tabela, portanto, desde que seja capaz de gravar as primeiras colunas, tudo bem. Primeiro, aplique a alteração a todos os escravos, depois faça failover para um dos escravos e, em seguida, aplique a alteração ao mestre e anexe-o como escravo. Se sua alteração envolver a inserção de uma coluna no meio ou a remoção de uma coluna, isso funcionará com a replicação baseada em linha.
Existem ferramentas que podem realizar alterações de esquema online de forma mais confiável. O Percona Online Schema Change (conhecido como pt-osc) criará uma tabela de sombra com a nova estrutura de tabela, inserirá novos dados por meio de gatilhos e preencherá dados em segundo plano. Assim que terminar de criar a nova tabela, ele simplesmente trocará a antiga pela nova tabela dentro de uma transação. Isso não funciona em todos os casos, especialmente se sua tabela existente já tiver gatilhos.
Uma alternativa é a nova ferramenta Gh-ost do Github. Essa ferramenta de alteração de esquema online fará primeiro uma cópia do layout da tabela existente, alterará a tabela para o novo layout e, em seguida, conectará o processo como uma réplica do MySQL. Ele fará uso do fluxo de replicação para localizar novas linhas que foram inseridas na tabela original e, ao mesmo tempo, preencherá a tabela. Uma vez feito o preenchimento, as tabelas originais e novas serão trocadas. Naturalmente, todas as operações para a nova tabela também terminarão no fluxo de replicação, portanto, em cada réplica, a migração ocorre ao mesmo tempo.
Tabelas de memória e replicação
Enquanto estamos no assunto de DDLs, um problema comum é a criação de tabelas de memória. As tabelas de memória são tabelas não persistentes, sua estrutura de tabela permanece, mas perdem seus dados após a reinicialização do MySQL. Ao criar uma nova tabela de memória em um mestre e um escravo, ambos terão uma tabela vazia e isso funcionará perfeitamente. Depois que qualquer um for reiniciado, a tabela será esvaziada e ocorrerão erros de replicação.
A replicação baseada em linha será interrompida quando os dados no nó escravo retornarem resultados diferentes, e a replicação baseada em instrução será interrompida quando tentar inserir dados que já existem. Para tabelas de memória, esse é um quebra de replicação frequente. A correção é fácil:basta fazer uma nova cópia dos dados, alterar o mecanismo para InnoDB e agora deve ser seguro para replicação.
Definindo a variável read_only como True
Como descrevemos anteriormente, não ter os mesmos dados nos nós escravos pode quebrar a replicação. Muitas vezes isso foi causado por algo (ou alguém) alterando os dados no nó escravo, mas não no nó mestre. Uma vez que os dados do nó mestre forem alterados, isso será replicado para o escravo, onde ele não poderá aplicar a alteração e isso fará com que a replicação seja interrompida.
Existe uma prevenção fácil para isso:definir a variável read_only como true. Isso não permitirá que qualquer pessoa faça alterações nos dados, exceto a replicação e os usuários root. A maioria dos gerenciadores de failover define esse sinalizador automaticamente para evitar que os usuários gravem no mestre usado durante o failover. Alguns deles ainda retêm isso após o failover.
Isso ainda deixa o usuário root executar uma consulta CRUD errônea no nó escravo. Para evitar que isso aconteça, existe uma variável super_read_only desde o MySQL 5.7.8 que bloqueia até mesmo o usuário root de atualizar dados.
Ativando GTID
Na replicação do MySQL, é essencial iniciar o escravo da posição correta nos logs binários. A obtenção dessa posição pode ser feita ao fazer um backup (xtrabackup e mysqldump suportam isso) ou quando você parou de slavar em um nó do qual está fazendo uma cópia. Iniciar a replicação com o comando CHANGE MASTER TO ficaria assim:
mysql> CHANGE MASTER TO MASTER_HOST='x.x.x.x',MASTER_USER='replication_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='master-bin.0001', MASTER_LOG_POS= 04;
Iniciar a replicação no local errado pode ter consequências desastrosas:os dados podem ser gravados duas vezes ou não atualizados. Isso causa desvio de dados entre o nó mestre e o nó escravo.
Além disso, o failover de um mestre para um escravo envolve encontrar a posição correta e alterar o mestre para o host apropriado. O MySQL não retém os logs e posições binários de seu mestre, mas cria seus próprios logs e posições binários. Para realinhar um nó escravo para o novo mestre, isso pode se tornar um problema sério:a posição exata do mestre no failover deve ser encontrada no novo mestre e, em seguida, todos os escravos podem ser realinhados.
Para resolver esse problema, o Global Transaction Identifier (GTID) foi implementado pela Oracle e pelo MariaDB. Os GTIDs permitem o alinhamento automático de escravos e, tanto no MySQL quanto no MariaDB, o servidor descobre por si mesmo qual é a posição correta. No entanto, ambos implementaram o GTID de forma diferente e, portanto, são incompatíveis. Se você precisar configurar a replicação de um para outro, a replicação deverá ser configurada com o posicionamento de log binário tradicional. Além disso, seu software de failover deve ser alertado para não fazer uso de GTIDs.
Conclusão
Esperamos ter dado dicas suficientes para evitar problemas. Estas são todas as práticas comuns dos especialistas em MySQL. Eles tiveram que aprender da maneira mais difícil e, com essas dicas, garantimos que você não precisa.
Temos alguns white papers adicionais que podem ser úteis se você quiser ler mais sobre a replicação do MySQL.
Whitepapers relacionados MySQL Replication BlueprintO whitepaper MySQL Replication Blueprint inclui todos os aspectos de uma topologia de replicação com os prós e contras da implantação, configuração de replicação, monitoramento, upgrades, realização de backups e gerenciamento de alta disponibilidade usando proxies.Download MySQL Replication for High AvailabilityEste tutorial abrange informações sobre o MySQL Replication, com informações sobre os recursos mais recentes introduzidos em 5.6 e 5.7. Há também uma seção mais prática e prática sobre como implantar e gerenciar rapidamente uma configuração de replicação usando o ClusterControl.Download