O Problema do Versionamento do Banco de Dados

Database

Muitas aplicações que usam banco de dados – tipicamente sistemas web – sofrem de um mal comum:
O nível de rigidez do processo de controle de versão  – na verdade o nome mais adequado é Gerência de Configuração – de banco de dados é muito mais relaxado do que o processo usado pro resto do código da aplicação.

Atualizar a versão de uma aplicação web (em produção) envolve duas coisas: atualizar o código da aplicação, e atualizar o banco de dados.
A atualização do código é fácil. Vc pega a versão 1.0 do código que tá lá, JOGA FORA, e põe o código da versão 2.0 no lugar.
Com o banco vc não pode chegar dropando as tabelas e criando tudo de novo – ou melhor, até pode: a aplicação vai funcionar -, mas o cliente provavelmente vai ficar meio chateado quando descobrir que tudo que ele cadastrou na versão 1.0… já era.

Por isso, o que se faz é ter um “patch”, ou um conjunto de patches, com os comandos SQL que fazem a migração 1.0 -> 2.0 no BD.

Todo mundo tem lá o seu SVN, CVS, GIT ou qq outra coisa onde armazena o código fonte da aplicação.
Por isso mesmo a solução mais comum pra esse problema é armazenar esses patches em arquivos .SQL no controle de versão, em alguma pastinha que todos os desenvolvedores têm acesso.
Quando um desenvolvedor implementa uma funcionalidade que precisa alterar o banco, ele comita o código e também o .SQL do patch necessário.

A questão é que: sem um controle automatizado_fácil_rápido da versão desses patches, alguns problemas começam a surgir.

Exemplo: João e Zé são dois desenvolvedores trabalhando em funcionalidades distintas do mesmo sistema.

  • O João vai lá e comita uma nova funcinalidade + patch.
  • O Zé não sabe o que o João fez, mas ele deu um “svn update” e o código do João veio junto. Mas ele não pegou os patches, que ficam em outra pasta do SVN.
  • Na hora que o Zé vai fazer um teste de um novo código que ele fez, a aplicação não sobe, pq o mapeamento objeto-relacional está quebrado (faltou uma coluna COR_FAVORITA na tabela PESSOA).
  • O Zé já tá esperto: “Humm, isso aí é patch! Deixa eu ver se tem algum arquivo novo lá na pastinha de patches…”
  • O Zé vai lá dar um “svn update” na pasta de patches (coisa q ele não faz há umas 2 semanas) e tem uns 20 patches novos lá.
  • “POUTZ… dá pra tomar uma Kaiser antes?” – Ele pensa – “é, Kaiser não dá, mas um café vai bem…”
  • Depois do cafezinho, o Zé começa a executar os patches na ordem (sim, pq alguém teve a excelente idéia de usar uma nomenclatura cronológica, tipo: 2012_03_14_FuncionalidadeX.sql, ufa!)
  • No sexto patch que ele executou dá erro.
  • “Ah, que se dane! Vou abrir esse 20 patches no Notepad++ e fazer um CTRL+Find ‘COR_FAVORITA’ (search in all open files = CHECK!). Preciso terminar logo minha implementação!” – Ele pensa.
  • O Zé encontra o patch relevante, executa e tenta subir a aplicação de novo.
  • Agora ele consegue continuar desenvolvendo a funcionalidade dele!
  • VITÓRIA!!!

Viiitória??? Será mesmo? Peraí rapaz… vamo analisar umas coisas aqui…

  • O Zé perdeu pelo menos un 20 minutos nessa brincadeira (sem contar a pausa pro café…).
  • Como ele nem rodou todos os patches que tinham lá, isso significa que tem outros bugs “de tocaia”, só esperando pra pular na cara dele numa hora que ele tiver bem aperreado.
  • E como daqui uma semana ele não vai lembrar quais patches ele rodou e quais não, ele vai perder mais tempo ainda.
  • Não é só ele. Outros desenvolvedores também costumam perder tempo resolvendo esse tipo de coisa. Mesmo os caras mais disciplinados (que não ficam mais de 2 dias sem atualizar o banco), ainda gastam 5-10 minutos quando isso acontece.
  • E não é só o João que dá esse tipo de trabalho pros outros. Da próxima vai ser a vez do Zé fazer o papel do vilão.
  • O nome disso é prejuízo. Ninguém mede, ninguém vê (especialmente a direção/gerência), mas ele está lá.
  • E quanto maior a equipe, mais frequente esse tipo de coisa. Num time de 6-10 pessoas desenvolvendo ativamente, isso é suficiente pra causar um verdadeiro “patch hell”.
  • A causa disso está no processo, não nas pessoas.

Apesar desse cenário caótico, esse processo tem poucas causas de falhas. Na verdade ele é quase bom! O problema é que as poucas falhas que tem realmente são capazes de fazer esse estrago mesmo.
Mas é possível resolver esses problemas se o processo conseguir atender aos seguintes requisitos:

  • 1) Existe uma ordem pré-definida e conhecida na qual os patches devem rodar.
  • 2) Para cada instância de banco, existe um meio fácil_rápido de saber se um dado patch foi rodado ou não.
  • 3) Existe um meio fácil_rápido de executar todos os patches que ainda não rodaram num dado banco

E melhor ainda se:

  • 4) Os desenvolvedores atualizam o BD dos seus ambientes de desenvolvimento com mais frequência.
  • 5) Existe um meio fácil_rápido de “DESAPLICAR” os patches até uma determinada data, ou versão. Ou seja, voltar o banco da versão 2.0 -> 1.0.
  • 6) Os patches não são “amarrados” com um SGBD específico.

Se vc se identificou com essa situação, e sente que precisa urgente dar um jeito nisso (como eu senti há uns 2 anos atrás na P2D), saiba que existe uma ferramentinha muito legal chamada liquibase, e que se vc incorporá-la no teu processo, ela te dá de cara os requisitos 1, 2 e 3.

Normalmente, o 4 acaba vindo como consequência de 3.
E, com um pouquinho de trabalho a mais, vc pode garantir também o 5 e o 6.

É isso aí… aguarde e confie😉

[ ]’s
O Lâmpada

 

Não perca nos próximos posts:

 

É lógico que vc não precisa esperar eu ter tempo de postar de novo. Vai logo dando uma olhada lá no liquibase!

5 comentários em “O Problema do Versionamento do Banco de Dados

  1. Fala Lâmpada!
    Muito bom o seu texto. Mas para mim essa situação é reflexo direto de não ter ninguem responsável pela arquitetura do BD. Como assim cada um faz o que quiser no BD para desenvolver suas funcionalidades?

  2. Opa, valeu pelo comentário!🙂

    > para mim essa situação é reflexo direto de não ter ninguem responsável pela arquitetura do BD

    Minha opinião é que esse cenário pouco tem a ver com a presençca dessa figura – que em muitas empresas = o velho e bom DBA.

    Eu inclusive já trabalhei numa empresa/projeto que existia um DBA que fazia exatamente isso.
    O DBA acabava conhecendo o domínio da aplicação (criado pela equipe de desenvolvimento) apenas superficialmente – e quem era responsável por criar os patches eram os desenvolvedores.
    O trabalho do DBA acabava se resumindo a garantir – através de um processo quase artesanal – a consistência da base de dados dos vários ambientes onde o sistema rodava (teste, homologação, produção – menos o ambiente de desenvolvimento dos devs, onde o jeito mais garantido era recriar o banco inteiro a cada novo patch que alguém criava).

    Garantir essa consistência é um trabalho repetitivo, nada criativo e propenso a erros (também conhecido como “serviço corno”).
    Esse é exatamente o tipo de coisa na qual máquinas são excelentes.

    Da minha experiência, o *uso de uma ferramenta que torne automática a garantia dessa consistência* foi a única coisa que eu já vi resolver (mas resolver MESMO) esse problema.

  3. Os patchs são genéricos? Tipo, além de atualização de tabelas e colunas, também servem para cargas no banco?

    Uma coisa legal desde que comecei a trabalhar com o Big Table do Google é que como o “Esquema” fica apenas no próprio código fonte, as mudanças ficam só no fonte mesmo, sem a necessidade de patches =D.

    Abs,

  4. Sim, basicamente ele tem uma tag XML pra grande maioria das operações basicas de SQL.
    E pro resto, existe a tag 🙂

    Ah sim, esse planeta do GAE é um negócio que eu quero explorar melhor depois tb.

    Eu ouvi dizer que no caso do BigTable, o fato do esquema ficar *só* no codigo acaba sendo uma faca de dois gumes:
    – Alguns aspectos de migração de dados e retrocompatibilidade com dados antigos acabam tendo que ficar no código também, e não é tão trivial bolar uma arquitetura que permita separar esse tipo de coisa da lógica de negócio.

    Na tua experiência, até que ponto isso chega a ser um problema?

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s