Encontrei vários sites falando sobre fazer exatamente isso, mas estou perdendo alguns detalhes importantes. Os passos gerais são
- Corre
FLUSH TABLES WITH READ LOCK
- Tire o instantâneo do ZFS
- Corre
UNLOCK TABLES
Várias fontes relatam que o InnoDB, que estou usando, na verdade não honra a FLUSH
. O manual do usuário do MySQL observa que existe uma FLUSH TABLES...FOR EXPORT
variante para uso com o InnoDB, mas isso requer a especificação de cada tabela individualmente, em vez de fazer backup de todo o banco de dados. Eu preferiria evitar especificar cada tabela individualmente, porque há uma chance decente de que a lista de tabelas fique fora de sincronia com as tabelas que realmente existem.
O outro problema que tenho é que planejei fazer algo assim mysql -h"$HOST" -u"$USERNAME" -p"$PASSWORD" --execute="FLUSH TABLES WITH READ LOCK"
. No entanto, isso interrompe o bloqueio imediatamente após a saída da sessão. Isso faz sentido, mas também é bastante irritante, pois preciso segurar o bloqueio de leitura quando tiro minha captura instantânea.
Minha outra idéia é fazer um backup quente usando uma ferramenta como Percona XtraBackup e tirar instantâneos do backup, mas eu prefiro não pagar o custo de gravar todos os meus dados em um segundo local apenas para capturá-los.
Respostas:
Se você usar o InnoDB apenas para todas as tabelas e definido
innodb_flush_log_at_trx_commit
como:1
(o conteúdo do buffer de log do InnoDB é gravado no arquivo de log em cada transação confirmada e o arquivo de log é liberado no disco) ou,2
(o conteúdo do buffer de log do InnoDB é gravado no arquivo de log após cada transação confirmada e o arquivo de log é liberado no disco aproximadamente uma vez por segundo),então você não precisa de FLUSH TABLES antes de fazer o snapshot, basta executar o snapshot do ZFS diretamente. O InnoDB pode recuperar dados de logs de confirmação de transação sem perda de dados.
Ref: https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit
fonte
Você precisa de um bloqueio completo do banco de dados para fazer backup de um ou mais bancos de dados de forma consistente.
O manual https://dev.mysql.com/doc/refman/5.5/en/backup-methods.html diz que FLUSH TABLES WITH READ LOCK está correto para os snapshots do ZFS especificamente.
É meio ridículo que eles deixem de fora o fato de que você precisa
FLUSH TABLES table_a, table_b, table_c FOR EXPORT
do InnoDB a partir dessas instruções. Também é estúpido ter que especificar cada tabela assim. Mas, como diz o EEAA, você pode gerar uma lista de tabelas ao iniciar o backup com bastante facilidade.Quanto à retenção do bloqueio, você deve manter a conexão db ativa ao executar o instantâneo
Geralmente eu usaria algo como Perl ou outra linguagem de programação que possa conectar, bloquear o banco de dados e, mantendo a conexão com o banco de dados, tire o instantâneo e desbloqueie e desconecte. Não é complexo. Eu apostaria que existem ferramentas por aí que já fazem isso, mas escrever uma é fácil.
Eu digo fácil, não complexo, etc. algumas vezes. Suponho que você tenha alguma programação básica ou boas habilidades de script.
fonte
FLUSH TABLES WITH READ LOCK
e depoisFLUSH TABLES...FOR EXPORT
, enquanto minha leitura do manual do MySQL diz que apenas uma deve ser necessária.Eu rasguei e adaptei um script conceitualmente simples no Bash, que encontrei em outro post de Tobia sobre Server Fault . Deve chegar a cerca de 90% do caminho até lá.
Aqui, o
mysql
comando que você usa é executado em segundo plano e toca em um arquivo. Ele espera em segundo plano o arquivo desaparecer antes de sair e, assim, desbloquear as tabelas. Enquanto isso, o script principal espera até que o arquivo exista, cria o instantâneo e exclui o arquivo.O arquivo apontado por
$mysql_locked
precisa estar acessível para ambas as máquinas, o que você deve poder fazer com bastante facilidade, pois elas podem acessar um conjunto de dados comum (embora possam usar caminhos diferentes, e você deve explicar isso).fonte
system zfs snapshot...
dentro do script principal? Ou a captura instantânea precisa ser executada em um processo separado?SYSTEM
comando executa as coisas localmente. Se eu rodar o cliente mysql na caixa do FreeBSD e executarLOCK; SYSTEM zfs snapshot; UNLOCK
, parece que funcionaria.Você precisa de FLUSH TABLES WITH READ LOCK para myisam porque não está registrando em diário.
Você realmente não precisa de nada para o innodb, IMO, porque é diário. De qualquer forma, será consistente, apenas reverterá o diário automaticamente se algo estiver acontecendo no instante atômico em que você captura a foto.
Se você deseja consistência no nível do aplicativo, ele deve usar transações. Se seu aplicativo usar transações e innodb, qualquer instantâneo será consistente, solicitando o caminho até o nível do aplicativo automaticamente.
fonte
Esta é minha solução, como criar um instantâneo do ZFS, mantendo o bloqueio:
fonte