Data

11 nov, 2016

Validação contínua do backup do MySQL: restaurando backups

Publicidade

Os bancos de dados MySQL do Facebook estão espalhados pelos nossos data centers globais e precisamos ser capazes de nos recuperar de uma interrupção em qualquer um desses locais, em qualquer momento. Em tal evento de desastre, não só temos que recuperar o serviço o mais rápido e confiável possível, mas também precisamos garantir que não percamos dados no processo. Para esse efeito, criamos um sistema que verifica continuamente a capacidade de restaurar os nossos bancos de dados a partir de backups.

Nosso sistema de restauração consiste em dois componentes principais:

  • Continuous Restore Tier (CRT) – Responsável por todo agendamento e monitoramento em torno de restaurações. Ele procura bancos de dados com novos backups e cria tarefas de restauração para eles, monitora o progresso da restauração e garante que cada backup seja restaurado com êxito.
  • ORC Restore Coordinator (ORC) – Compreende os workers de restauração (peons) e um balanceador de carga (warchief). O warchief recebe novas tarefas de restauração da CRT e as atribui a peons. Peons hospeda uma instância local do MySQL, onde eles executam a restauração real.

Os dados CRT coletados sobre o progresso de cada tarefa de restauração nos ajudam a entender nossos requisitos de recursos para restaurações de banco de dados, e a ORC nos ajuda a verificar a integridade do backup. O foco deste artigo são os internos da ORC – especificamente a máquina de estado peon interna e alguns dos desafios que tivemos de superar quando iniciamos o processo de restauração de um único banco de dados.

Visão geral dos backups

Antes de construir um pipeline de restauração contínuo, primeiro precisamos entender a natureza dos backups disponíveis para nós. Atualmente, temos três tipos de backups, todos armazenados em HDFS:

  • Full Logical Backups são feitos a cada poucos dias usando mysqldump;
  • Differencial (diff) backups são realizados nos dias em que não temos backups completos. Fazemos isso por meio de outro descarregamento completo e armazenando apenas a diferença entre ele e o último backup completo que foi feito. Os registros de backup de metadados completos contra o diff foram criados.
  • Binary log (binlog) backups são constantemente transmitidos para o HDFS a partir do masters do banco de dados.

Ambos os backups completos e de dif passam a opção –single-transaction para o mysqldump para que possamos obter um snapshot consistente do banco de dados e ambos podem ser retirados dos slaves, bem como das instâncias master. Vou me referir a diff e backups completos como descargas para o restante deste artigo.

Como as descargas só são feitas uma vez por dia, ter backups de binlog significa ter cobertura completa de cada transação executada contra o banco de dados em que está sendo feito backup. Isso então nos permite realizar restaurações point-in-time, refazendo transações de binlogs em cima de uma descarga restaurada para trazer o estado do banco de dados até um certo ponto no tempo. Todos os nossos servidores de banco de dados também usam IDs de transações globais (GTIDs), o que nos dá uma outra camada de controle ao reproduzir transações de backups de binlog.

Além de armazenar backups em HDFS, gravamos-os em um local externo. A palestra de Shlomo Priymak no Code as Craft abrange nossa arquitetura de backup de forma muito mais detalhada.

ORC: coordenador de restauração ORC

Arquitetura

ORC tem três componentes:

  • Warchief – O balanceador de carga. É um programa Python que expõe uma interface Thrift, através da qual recebe novas solicitações de restauração e agenda-as em peons disponíveis.
  • ORC DB – Banco de dados Central MySQL que mantém o estado sobre os trabalhos atribuídos a cada peon, o estado atual de cada trabalho do peon, estatísticas de vida do peon e muito mais. As informações armazenadas aqui são usadas pelo warchief para decidir a qual peon um trabalho deve ser atribuído, bem como quais peons durante a recuperação de falha.
  • Peon – Os workers de restauração. Eles também são escritos em Python e expõem uma interface Thrift, através da qual várias estatísticas sobre o peon podem ser obtidas. Periodicamente, cada peon sincroniza com a ORC DB para procurar novos trabalhos atribuídos a ele, e relata seu próprio estado de saúde. Os servidores que executam peons também têm uma instância local do MySQL executada neles, para a qual os backups são restaurados.

fb-1

Por baixo do capuz: Peons

Peons contêm toda a lógica relevante para recuperar backups de HDFS, carregá-los em sua instância local do MySQL, e lança-los à frente em um certo ponto no tempo, recolocando binlogs. Cada trabalho de restauração em que um peon trabalha passa por estes cinco estágios:

  1. Select – Decide qual backup precisa ser restaurado para esse shard (por exemplo, full ou diff, HDFS ou offsite etc.).
  2. Dowload – Faz o download dos arquivos selecionados para o disco. Se um backup completo está sendo restaurado, é apenas um único arquivo. Para os backups de dif, primeiro baixamos os backups completos e de dif, aplicamos o diff no topo do backup completo e finalmente armazenamos o resultado no disco. Neste ponto, temos no disco uma única saída mysqldump, independentemente do tipo de backup.
  3. Load – Carrega o backup transferido para a instância MySQL local do peon. Tabelas individuais são restauradas em paralelo, analisando as declarações relativas a essas tabelas a partir do arquivo de backup, semelhante ao mydumper do Percona.
  4. Verify – Executa verificações de resiliência nos dados carregados no MySQL.
  5. Replay – Faz o download e reproduz transações de backups de log binário em cima do backup restaurado, se necessário. Usamos o programa mysqlbinlog para filtrar eventos de binlog de outros bancos de dados e transações vazias e, em seguida, reproduzir as transações necessárias na mesma instância do MySQL.

Cada estágio também tem um estado de falha correspondente, portanto, se uma tarefa falhar em DOWNLOAD, ela move para o estado DOWNLOAD FAILED e não avança para LOAD.

Seleção lógica Binlog

Talvez a parte mais desafiadora do processo de restauração seja determinar quais binlogs devem ser baixados e reproduzidos. Os diffs e os backups completos podem ser tomados do master ou de um slave. No entanto, só levamos backups binlog do master. Isso significa que comparações timestamp simples não podem ser usadas para determinar quais binlogs precisam ser repetidos.

Nós implantamos GTIDs através de nossa frota em 2014, e isso dá a cada transação um identificador globalmente exclusivo. Além disso, cada servidor MySQL em execução mantém uma variável gtid_executed (GTID set), que atua como um contador de transações executadas por essa instância até o momento.

Com GTIDs no lugar, uma transação replicada de master para slave mantém seu GTID, o que significa que sabemos definitivamente se ele está ou não incluído em um conjunto GTID. Também podemos realizar comparações de superset/subset com o valor do servidor gtid_executed, uma vez que é apenas um contador invariável crescente e funciona como um conjunto matemático.

Juntando-os, podemos gravar o valor gtid_executed do servidor quando o dump está sendo feito e gravar o conjunto GTID contido em cada arquivo binlog para executar uma comparação consistente e determinar quais transações em um binlog precisam ser reproduzidas. Além disso, uma vez identificada a primeira transação a ser repetida, sabemos que cada transação subsequente precisa ser repetida e pode evitar comparações GTID adicionais. Também usamos a opção –stop-datetime para mysqlbinlog para determinar onde o fluxo binlog deve ser parado.

Conclusão

Os backups são a última linha de defesa em caso de desastre; eles nos dão confiança em nossa capacidade de recuperação de interrupções. No entanto, apenas fazer backups não é suficiente. A ORC nos ajuda a testar continuamente nossos backups para verificar sua integridade e também nos dá uma compreensão dos recursos que precisaríamos para restaurá-los com êxito.

Fazer um sistema como ORC operar na escala do Facebook exige a adição de um monte de alertas, monitoramento e detecção de falhas automatizadas e remediação. Todos eles são implementados em CRT e serão abordados em um artigo de acompanhamento descrevendo como escalamos nosso processo de restauração para dezenas de milhares de bancos de dados.

***

Este artigo foi escrito por Divij Rajkumar. A tradução foi feita pela Redação iMasters. Você pode conferir o original em https://code.facebook.com/posts/1007323976059780/continuous-mysql-backup-validation-restoring-backups/;