Fazer backup de um banco de dados MySQL no Git é uma boa idéia?

57

Estou tentando melhorar a situação de backup do meu aplicativo. Eu tenho um aplicativo Django e banco de dados MySQL. Eu li um artigo sugerindo fazer backup do banco de dados no Git.

Por um lado, gosto, pois manterá uma cópia dos dados e do código sincronizados.

Mas o Git é projetado para código, não para dados. Como tal, ele estará fazendo muito trabalho extra diferindo o despejo do MySQL a cada commit, o que não é realmente necessário. Se eu compactar o arquivo antes de armazená-lo, o git ainda difere os arquivos?

(No momento, o arquivo de despejo está descompactado 100 MB, 5,7 MB quando compactado.)

Edit: as definições de esquema de código e banco de dados já estão no Git, são realmente os dados que me preocupam em fazer backup agora.

wobbily_col
fonte
13
Se sua empresa possui um departamento de TI (operações), eles devem lidar com isso.
Michael Hampton
11
os dados fazem parte do aplicativo ou o que é criado através do aplicativo?
Winston Ewert
11
O Git tentará diferenciar todos os arquivos quando você executar git gc(ou está subjacente git repack; o git, por padrão configurável, ocasionalmente o executará automaticamente). Também os esvaziará sempre , portanto, talvez seja melhor armazená-los descompactados.
Jan Hudec
11
Que tipo de banco de dados é: é um banco de dados de produção ou desenvolvimento?
El.pescado 27/05
6
viget.com/extend/backup-your-database-in-git , ele é um "desenvolvedor sênior".
Wobbily_col #

Respostas:

101

Antes de você perder dados, deixe-me tentar introduzir uma perspectiva de administrador de sistemas nesta pergunta.

Há apenas uma razão para criar backups: possibilitar a restauração quando algo der errado, como sempre ocorrerá. Como tal, um sistema de backup adequado possui requisitos que vão muito além do que o git pode razoavelmente lidar.

Aqui estão alguns dos problemas que posso prever ao tentar fazer backup do seu banco de dados no git:

  • O repositório crescerá dramaticamente a cada "backup". Como o git armazena objetos inteiros (embora compactados) e os difere posteriormente (por exemplo, quando você executa git gc) e mantém o histórico para sempre , você terá uma quantidade muito grande de dados armazenados que você realmente não precisa nem quer. Pode ser necessário limitar a quantidade ou o período de retenção de backups para economizar espaço em disco ou por motivos legais, mas é difícil remover as revisões antigas de um repositório git sem muito dano colateral.
  • A restauração é limitada a pontos no tempo que você armazenou no repositório e, como os dados são muito grandes, a recuperação de mais de uma quantidade trivial de tempo pode ser lenta. Um sistema de backup projetado para esse fim limita a quantidade de dados armazenados e, ao mesmo tempo, fornece mais granularidade e fornece restaurações mais rápidas, reduzindo o tempo de inatividade no caso de um desastre. As soluções de backup com reconhecimento de banco de dados ( exemplo ) também podem fornecer backup contínuo , garantindo que nenhuma transação seja perdida.
  • As confirmações provavelmente também serão lentas e ficarão mais lentas à medida que o banco de dados cresce. Lembre-se de que o git é essencialmente um armazenamento de dados com valor-chave mapeado em um sistema de arquivos e, portanto, está sujeito às características de desempenho do sistema de arquivos subjacente. É possível que esse período exceda o intervalo de backup e, nesse momento, você não poderá mais atender ao seu SLA. Os sistemas de backup adequados também demoram mais tempo para fazer backup à medida que os dados aumentam, mas não de maneira tão dramática, pois gerenciam automaticamente seu próprio tamanho com base na política de retenção que você configurou.

Apesar do fato de que aparentemente existem várias coisas interessantes que você pode fazer com um despejo de banco de dados se o colocar no git, no geral, não posso recomendá-lo com o objetivo de manter backups. Especialmente porque os sistemas de backup estão amplamente disponíveis (e muitos são de código aberto) e funcionam muito melhor para manter seus dados seguros e possibilitar a recuperação o mais rápido possível.

Michael Hampton
fonte
Essa é a melhor resposta, pois Michael abordou questões de consistência. Dependendo do tamanho e uso do banco de dados, um instantâneo não pode reproduzir os dados de maneira confiável em um determinado momento e é provável que você tenha problemas de restrição. A replicação pode ser algo que você quer olhar para - dev.mysql.com/doc/refman/5.0/en/replication.html
Aaron Newton
4
Esta não é apenas a melhor resposta, é a única resposta. Como regra geral, você é um desenvolvedor, portanto os backups não são da sua conta; alguém já está (ou deveria estar) cuidando deles e, se você começar a se envolver, poderá estar interferindo em um sistema que já funciona. Essas caixas devem estar sendo copiadas, para que você tenha um backup, seu próprio backup e um backup do seu próprio backup, todos com tamanho cada vez maior. Isso é loucura. Plus: você é um desenvolvedor: por que (provavelmente) está chegando perto das caixas de produção?
Maximus Minimus
2
@JimmyShelter Existe uma escola de pensamento de que o DevOps não significa que o Dev e o Ops trabalhem juntos, mas que o Dev realmente faz Ops. Geralmente não funciona bem, mas isso não impede as pessoas de tentar.
Michael Hampton
Essa deve ser a resposta aceita. Ele explica claramente os requisitos e a finalidade de um sistema de backup e mostra como o git não se encaixa. Pontos de bônus extras para discussão de consistência e desempenho.
Gabriel Bauman
Deixe-me observar que eu postei minha resposta assumindo que o OP não possui nenhuma equipe de Operações que possa lidar com esse problema. Eu concordo com você que esse tipo de tarefa é melhor deixar para aqueles que realmente estão operando o sistema e que sabem o que fazer. Mas há situações em que você precisa usar um chapéu que não é exatamente seu, e acredito que é melhor tentar aprender algumas práticas recomendadas do que apenas apresentar sua própria solução. Devo dizer que também achei sua resposta muito instrutiva!
logc 28/05
39

Meus dois centavos: não acho que seja uma boa ideia. O GIT faz algo como "armazenar instantâneos de um conjunto de arquivos em diferentes momentos", para que você possa usar perfeitamente o GIT para algo assim, mas isso não significa que você deva . O GIT foi projetado para armazenar o código-fonte; portanto, você perderia a maior parte de sua funcionalidade e trocaria muito desempenho por apenas um pouco de conveniência.

Deixe-me supor que a principal razão pela qual você está pensando sobre isso é "manter uma cópia dos dados e do código sincronizados" e que isso significa que você está preocupado que a versão 2.0 do seu código precise de um esquema de banco de dados diferente da versão 1.0 . Uma solução mais simples seria armazenar o esquema do banco de dados, como um conjunto de scripts SQL com CREATEinstruções, ao longo do código-fonte no seu repositório Git. Em seguida, parte do procedimento de instalação seria executar esses scripts em um servidor de banco de dados instalado anteriormente.

O conteúdo real dessas CREATEtabelas just -d não tem nada a ver com a versão do seu código-fonte. Imagine que você instala o software, versão 1.0, no servidor A e no servidor B, que são usados ​​em diferentes empresas por diferentes equipes. Após algumas semanas, o conteúdo das tabelas será muito diferente, mesmo que os esquemas sejam exatamente os mesmos.

Como você deseja fazer backup do conteúdo do banco de dados, sugiro que você use um script de backup que marque o dump de backup com a versão atual do software ao qual o dump pertence. O script deve estar no repositório GIT (para que ele tenha acesso à cadeia de caracteres da versão do código-fonte), mas os dumps em si não pertencem a um sistema de controle de versão.

EDIT :

Depois de ler o post original que motivou a pergunta , acho essa uma idéia ainda mais duvidosa. O ponto principal é que o mysqldumpcomando transforma o estado atual de um banco de dados em uma série de INSERTinstruções SQL , e o GIT pode diferenciá-las para obter apenas as linhas da tabela atualizadas.

A mysqldumpparte é boa, já que este é um dos métodos de backup listados na documentação do MySQL. A parte GIT é onde o autor falha em perceber que os servidores de banco de dados mantêm um log de transações para se recuperar de falhas, incluindo o MySQL . É usando esse log , não o GIT, que você deve criar backups incrementais para o seu banco de dados. Isso tem, em primeiro lugar, a vantagem de poder girar ou liberar os logs após a recuperação, em vez de inchar um repositório GIT para o infinito e além ...

logc
fonte
2
Não tenho certeza se vejo algum ponto em armazenar o esquema do banco de dados sem os dados no controle de versão. Os dados são a coisa mais importante e é isso que eu quero fazer backup. Eu gosto da idéia de marcar o backup do banco de dados com a versão atual do software. Vou tentar implementar algo assim.
Wobbily_col # 26/14
10
O objetivo de armazenar o esquema sem os dados é que, logo após a instalação, seu software esteja "pronto para ser usado". Se for um wiki, deve estar pronto para começar a criar páginas do wiki e escrever algo nelas. Se você instalar o esquema e o conteúdo, seu wiki já estará cheio de páginas wiki X após a instalação ... Isso não é exatamente "instalar um sistema wiki para escrever nosso conteúdo", mas "copiar um wiki de algum lugar para lê-lo" .
logc 26/05
3
Pode ser uma boa ideia modificar sua pergunta com a situação atual. Mesmo se você não puder postar todos os detalhes, seria importante afirmar que você precisa que muitos dados apareçam inalterados em cada instalação ou há uma única instalação ...
logC
2
@wobbily_col Um formato binário sem texto tem valor limitado no contexto do controle de origem. Você não pode diff -lo, você não pode ramo / fundir -lo, etc. Assim, enquanto você certamente pode usar git para armazenar a DB, a maioria das pessoas preferem roteiro a estrutura DB, bem como os dados necessários. É um compromisso entre ter um pouco mais de trabalho, mas fornecer a lista acima de recursos. Você terá que avaliar se essa é uma boa ideia para sua solução. Caso contrário, você provavelmente poderá fazer com que o GIT armazene o banco de dados diretamente, simplesmente não é exatamente o melhor ajuste para a tarefa.
Daniel B
3
@RaduMurzea: Eu acho que isso é uma questão de princípios. Um sistema de controle de versão foi projetado para gerenciar o código-fonte, e não os binários, é tudo. Não é uma questão de tamanho. Não, os despejos de banco de dados não devem ser registrados no repositório, assim como os vídeos de treinamento também não devem ser registrados. Mas ninguém está impedindo você de fazê-lo. :)
logc
7

Pessoalmente, não acho que seja uma boa idéia usar um sistema de versão de controle de origem para armazenar os arquivos de backup, porque o controle de versão do GIT foi projetado para arquivos de dados, não para binários ou arquivos de despejo, como um arquivo de despejo de backup do MySQL. O fato de você poder fazer isso não significa automaticamente que você deve fazê-lo. Além disso, seu repositório, considerando um novo backup de banco de dados para cada nova confirmação, aumentará drasticamente, usando muito espaço em disco rígido e o desempenho do GIT será afetado, resultando em um sistema de controle de origem lento. Para mim, é bom executar uma estratégia de backup e sempre ter um arquivo de backup pronto quando você precisar restaurar o banco de dados quando algo no seu código der errado, mas as ferramentas de controle de origem não são feitas para armazenar dados binários.

Por esses motivos, não vejo utilidade em armazenar os arquivos de backup do dia 1 e do dia 2 e depois ver as diferenças entre os dois arquivos de backup. Isso exigirá muito trabalho extra e inútil. Em vez de usar o GIT para armazenar backups do banco de dados quando você confirmar um novo código, armazene os backups do banco de dados em um caminho diferente, separados por data e hora e insira no código alguma referência aos novos backups do banco de dados criados para cada versão, usando as tags, como alguém já sugeriu.

Minha nota final sobre os backups do banco de dados e o GIT: Um administrador de banco de dados, quando ele precisa restaurar um banco de dados porque alguns dados foram perdidos, não precisa verificar as diferenças entre o arquivo de backup do dia 1 e o arquivo de backup do dia 2, ele precisa saber apenas qual é o último arquivo de backup que permitirá restaurar o banco de dados, sem erros e perda de dados, reduzindo o tempo de inatividade. De fato, a tarefa de um administrador de banco de dados é disponibilizar os dados para recuperação o mais rápido possível, quando o sistema, por alguns motivos, falhar. Se você armazena os backups do banco de dados no GIT, vinculados às suas confirmações, não permite que o administrador do banco de dados restaure os dados rapidamente, porque seus backups são limitados a pontos no tempo que você armazenou no repositório GIT e reduzem o tempo de inatividade do sistema,

Então, não recomendo armazenar os backups usando o GIT, use uma boa solução de software de backup (existem alguns aqui ), que fornecerá mais granularidade e permitirá manter seus dados seguros e protegidos recuperação de dados simples e rápida em caso de desastres.

Alberto Solano
fonte
Talvez o voto negativo explique por que ele / ela votou negativamente ..
Alberto Solano
11
Não é o downvoter, mas acho que essa abordagem introduz um conflito de mesclagem sempre presente, que não é particularmente propício ao fluxo de trabalho de ramificação - frequentemente, mesclagem - frequentemente que a maioria dos usuários do git prefere.
Daniel B
@DanielB Proponho não usar o sistema de controle de versão para armazenar os arquivos de backup do banco de dados. Eu acho que o problema de backup do banco de dados poderia ser facilmente resolvido sem o uso de nenhum sistema de controle de versão. Os sistemas de controle de versão (GIT, TFS, SVN e assim por diante ..) são projetados para software, não para arquivos de despejo ou backups de banco de dados ou apenas para armazenamento de dados (existem muitas soluções para isso).
Alberto Solano
Eu acho que a maioria dos usuários lê as primeiras frases e diminui o voto, pois parece que você estará dizendo que está tudo bem em usar.
11
@AlbertoSolano Entendo; mas lendo a pergunta ("posso fazer backup do meu banco de dados no GIT?") e, em seguida, sua primeira declaração ("é bom armazenar o arquivo de backup ..."), parece que você está dizendo o contrário. O resto da resposta parece estar dizendo que não está aqui nem ali, enquanto suspeito que muitas pessoas pensam que é um acidente de trem esperando para acontecer.
Daniel B
1

Você não deve armazenar dados binários no Git - especialmente no banco de dados.
Alterações de código e alterações de DML no banco de dados são coisas totalmente diferentes.

MySQL e Oracle podem gravar logs de arquivamento com o objetivo de serem restaurados para qualquer ponto no tempo. Basta fazer backup desses logs para um local seguro e você ficará bem.

Usar o Git para fazer backup desses "logs de arquivamento" não faz sentido. Os logs de arquivamento em ambientes de produção são bastante pesados ​​e devem ser removidos depois de fazer backups completos regulares. Também é inútil colocá-los no git - esses já são um repositório em algum sentido.

Jehy
fonte
11
por que não se usaria o Git para fazer backup desses "logs de arquivamento" criados pelo MySQL?
Gnat 26/05
11
Só porque não faz sentido. Os logs de arquivamento em ambientes de produção são bastante pesados ​​e devem ser removidos depois de fazer backups completos regulares. Também é inútil colocá-los no git - esses já são um repositório em algum sentido. Michael Hampton dá uma resposta muito boa sobre esta questão (nesta página).
Jehy 26/05
11
Por que incomodar a rotação de logs, se você deseja manter uma cópia de tudo no git? É melhor manter apenas um arquivo de log de monstros.
Wobbily_col