Como incrementalmente atualizar um banco de dados ao implantar um site?

5

Usamos o JSF sobre o Tomcat junto com um banco de dados proprietário do backing.

Eu quero saber como a adição de novos campos de bancos de dados e / ou procedimentos armazenados devem ser tratados quando implantarmos uma nova versão do aplicativo.

Nós implantamos enviando um arquivo WAR para a equipe de hospedagem, assim, nosso WAR deve ser capaz de configurar o procedimento armazenado quando for iniciado.

Quais são as possíveis estratégias apropriadas para poder atualizar incrementalmente o banco de dados?

    
por Archan Mishra 11.01.2012 / 16:25
fonte

4 respostas

4

A resposta de Jelayn é muito boa e representa uma prática mais ou menos padronizada, especialmente no mundo do Rails, onde uma solução semelhante é incorporada ao framework. No entanto, o estado da arte, como praticado pelo Facebook, Flickr, Heroku e IMVU - um pioneiro nisso - é um pouco mais avançado.

O problema com a prática padrão é que você pode escrever 2 versões de código e mudar de uma para outra com uma migração rápida à medida que você implanta. Há muitos problemas com isso:

  • Se você tiver muitos dados, uma migração levará tempo. Leva meses para o Facebook migrar dados, mas, a menos que você tenha poucos dados, é raro que a migração seja instantânea. A solução para isso é migrar lentamente. O IMVU foi pioneiro na estratégia aqui:

    • em vez de migrar a tabela, crie uma tabela separada com o novo esquema
    • quando uma linha é lida e não está presente na nova tabela, migre somente essa linha e salve-a na nova tabela. Você pode então excluir a linha antiga.
    • também executa uma tarefa em segundo plano que executa as migrações em lotes (atente para conflitos!)
  • durante uma migração, seu código precisa suportar o esquema antigo e o novo. Portanto, você deve escrever o código que suporta ambos, depois migrar e, em seguida, remover o código antigo em uma implementação separada.

  • Após uma migração com falha, você deve decidir se pode migrar nas duas direções ou apenas para frente. O IMVU só avança - eu acho - então, se eles têm um bug em sua migração, eles consertam em vez de revertê-lo. Eu pessoalmente prefiro corrigir, mas há bons argumentos para revertê-lo também.

Esse material também é altamente relacionado à implantação contínua, e muitas dessas estratégias podem ajudar. Por exemplo, uma técnica comum de CD é habilitar seletivamente o novo código apenas para uma pequena base de usuários para fornecer mais testes, e somente depois habilitá-lo para públicos maiores e maiores (normalmente, você usa uma configuração de banco de dados para cada recurso). Essa prática permite que você ganhe mais confiança em suas migrações, especialmente quando elas são mais complicadas do que apenas adicionar um campo e sem apostar todos os seus dados em uma migração relativamente não testada.

Source : pesquisa de mercado e conversas com os clientes enquanto realizo minha Integração contínua e Implantação .

>     
por 12.01.2012 / 09:35
fonte
3

Concordo com @FrustratedWithFormsDesigner porque é bem possível, E que o script para atualizar a estrutura do banco de dados não deve ser incluído no código do aplicativo. Devido a isso, seu aplicativo exigiria outras permissões, permitindo criar tabelas, alterar tabelas, etc., o que você provavelmente não precisa durante o uso "normal" de seu aplicativo. Então, em termos de segurança, não é uma coisa boa, já que seu aplicativo só deve ter as permissões necessárias para funcionar corretamente.

De qualquer forma, voltemos ao ponto principal. É bem possível fazer isso corretamente criando uma tabela especial em seu banco de dados, digamos X_VERSION, na qual você simplesmente terá a versão atual do esquema do banco de dados (também pode ser um timestamp). Sempre que você alterar seu esquema de banco de dados, coloque essa mudança em um script SQL chamado [Timestamp-XXX-WhateverItIsYouAreDoing.sql], onde:

  • Timestamp é o registro de data e hora, por exemplo, 20110111-165500
  • XXX é um número, que será útil mais tarde para saber a ordem de execução dos scripts
  • O que quer que seja, etc. é algum texto que o ajudará a lembrar o que você faz nesse script

Se o seu programa de atualização de banco de dados está em seu aplicativo ou fora, não importa para as etapas a seguir; sempre que você entregar uma nova versão do seu aplicativo, seu programa de atualização deverá fazer isso:

  • Pesquise o timestamp atual em X_VERSION
  • Verifique todos os scripts que devem ser executados entre a versão encontrada em X_VERSION e a nova versão
  • Faça um loop sobre os scripts e para cada script

    • Execute o script atualizando seu banco de dados / esquema
    • Atualize o registro de data e hora em X_VERSION para o registro de data e hora do script executado

Quando todos os scripts são concluídos, você sabe que seu aplicativo pode ser iniciado com segurança.

Bônus : Se você quiser ter uma maneira segura de voltar para uma versão anterior, sempre que criar um script que altere seu banco de dados, sempre crie um script que permita voltar à versão anterior. Às vezes pode ser um pouco difícil (como remover uma coluna, por exemplo, nem todos os DBMS permitem isso), mas sempre tente. Você então estará preparado para reverter para uma versão anterior, se necessário.

    
por 11.01.2012 / 16:56
fonte
2

Normalmente, tenho alterações do banco de dados implantadas fora do aplicativo principal, geralmente por meio de um script executado pelo DBA.

Suponho que você poderia fazer as alterações de dentro do seu aplicativo, se o seu aplicativo tiver permissão para modificar a estrutura do banco de dados. Eu acho que o que teria que acontecer é o seu aplicativo seria iniciado, algum novo procedimento seria executado na inicialização, fazer todas as alterações necessárias no banco de dados e, em seguida, provavelmente, reiniciar. O truque é garantir que as mudanças só aconteçam uma vez . Isso provavelmente poderia ser feito verificando um número de versão em uma tabela especial e usando isso para decidir se o banco de dados deve ser modificado.

Ele também adiciona atividades de manutenção do banco de dados ao aplicativo principal, o que não é uma boa idéia porque o aplicativo provavelmente foi projetado para fazer outra coisa (blogging, bancos, registros médicos, reservas de hotéis online, etc ...). Às vezes você pode querer manter suas implementações de banco de dados completamente separadas do aplicativo principal.

Do ponto de vista técnico, é bem possível fazer isso. Deve ser feito? Essa é uma pergunta diferente.

    
por 11.01.2012 / 16:33
fonte
0

As duas abordagens padrão para atualizações de banco de dados que eu vi aplicadas são:

  1. A equipe de implantação executando scripts SQL fornecidos pela equipe de DBA. O grupo de DBA forneceria scripts para atualizar o esquema e carregar quaisquer dados que fossem necessários para essa liberação específica.
  2. Usando uma ferramenta automatizada como o Liquibase. Este sistema adiciona uma tabela similar ao que o @Jalayn propõe, que rastreia os changesets (deltas) que devem ser executados para cada tabela. A maioria das operações padrão é suportada.

Em ambos os casos, o resultado final deve ser o mesmo. No entanto, a abordagem que você toma deve refletir os princípios que o seu grupo de desenvolvimento prefere - automatizado versus manual, etc.

    
por 11.01.2012 / 18:53
fonte