Como você atualiza o esquema da base de dados / banco de dados de produção sem causar tempo de inatividade?

42

Quais são algumas técnicas para atualizar o esquema de base de dados / banco de dados de um servidor de produção sem causar nenhum tempo de inatividade?

Olivier Lalonde
fonte
1
Boa pergunta, porque vejo tantas pessoas ignorando isso. Tempo é dinheiro e o tempo de inatividade nunca parece bom para os usuários finais, independentemente da razão do motivo.
Dan McGrath
@ Dan McGrath: que suponha que você realmente possa ter um tempo de inatividade, eu trabalho para um sistema que (normalmente) fica inativo apenas 4 vezes por ano (interrupção de um quarto) e por 15 minutos no máximo a cada vez (durante o qual o tráfego está na fila). .. alterações de banco de dados são fortemente examinado :)
Matthieu M.
2
Essa seria uma ótima pergunta para o dba.stackexchange.com , que entra na versão beta pública em algumas horas.
Larry Coleman

Respostas:

20

Geralmente, os sites em que trabalhei que tinham esse tipo de requisito estavam atrás de balanceadores de carga ou tinham locais de failover separados. Neste exemplo, presumirei que você tenha um único balanceador de carga, 2 servidores Web (A e B) e 2 servidores de banco de dados (M&N - geralmente servidores de banco de dados são vinculados via logshipping - pelo menos no mundo do SQL Server )

  1. O servidor da Web A deve ser desconectado do balanceador de carga (para que todo o tráfego recebido vá para B).
  2. O envio do log foi interrompido (o DB Server M será atualizado primeiro).
  3. Atualizar servidor da Web A. Aponte a configuração para o DB Server M.
  4. Teste e verifique se a atualização funcionou (geralmente as pessoas estão acessando o endereço IP diretamente).
  5. Defina o balanceador de carga para que as sessões existentes continuem indo para B. Novas sessões vão para A.
  6. Aguarde até que todas as sessões em B expirem (pode demorar meia hora ou mais, geralmente assistimos ao trânsito e temos um intervalo de 1 hora agendado).
  7. Atualização B e N.
  8. Teste e verifique se a atualização funcionou.
  9. Configure o envio de logs novamente e teste se ele funciona.
  10. Defina o balanceador de carga para operação normal.

Em aplicativos da Web muito complicados, o que é descrito nas etapas de 1 a 5 pode demorar a noite toda e ser uma planilha do Excel de 50 páginas com horários e números de contato de emergência. Nessas situações, a atualização da metade do sistema está agendada para as 18:00 às 06:00, deixando o sistema disponível para os usuários. O tratamento da atualização para o site de recuperação de desastres geralmente é agendado para a noite seguinte - só espero que nada ocorra no primeiro dia.

Onde o tempo de atividade é um requisito, os patches são testados primeiro no ambiente de controle de qualidade, que idealmente é o mesmo hardware que a produção. Se eles não mostrarem interrupções, poderão ser aplicados regularmente, normalmente no fim de semana.

Tangurena
fonte
7
Como você propõe mesclar novos dados do DB M e DB N? Ambos terão registros novos, atualizados e excluídos que o outro não possui.
sixtyfootersdude
@ Tangurena, você pode responder ao comentário acima?
sino
9

Para bancos de dados típicos (Oracle, por exemplo), é possível alterar o esquema do banco de dados enquanto ainda executa consultas em paralelo. No entanto, requer algum planejamento futuro.

Existem algumas restrições para a alteração a ser aplicada:

  • deve funcionar com o código existente, o que significa que o código deve lidar com as versões antiga e nova do esquema
  • não deve incorrer em tal carga no banco de dados que as transações sejam interrompidas (estou olhando para você CREATE INDEX)
  • não deve resultar na perda de dados (você não pode eliminar e recriar uma tabela)

Para que o esquema seja compatível com versões anteriores, geralmente você pode ADICIONAR ou MODIFICAR uma coluna, só pode soltar algo se o código existente não o usar mais.

Se o seu código não puder lidar com a alteração de forma transparente, altere o código antes de alterar o banco de dados.

Conselhos simples sobre o planejamento futuro: sempre explique os nomes das colunas nas suas solicitações de banco de dados (não use SELECT * FROM). Dessa forma, você não terá novas colunas aparecendo em solicitações antigas.

Matthieu M.
fonte
1
Na verdade, para o planejamento e a adaptabilidade futuros, selecionar * é infinitamente melhor do que listar as colunas manualmente. O uso de nomes explícitos de coluna resulta em muita dívida técnica na maioria dos casos. Se seu código quebrar de novas colunas, ele já está quebrado.
Morg.
@Org: Na verdade não. Por segurança, você precisa usar variáveis ​​de ligação, que na estrutura que eu uso (pelo menos) exigem o fornecimento de variáveis ​​para gravação e precisa haver exatamente quantas variáveis ​​forem as colunas de saída, o que select *significa que o código será interrompido se um nova coluna é adicionada (por falta de uma variável na qual a gravar). Obviamente, isso pode ser o resultado do uso de uma linguagem fortemente tipada.
Matthieu M.
Sim, realmente, não há segurança adicional para evitar a seleção *. Não tem nada a ver com linguagens fortemente tipadas e tudo a ver com um design muito ruim. Se sua estrutura não puder lidar com alterações sem problemas, é inútil. Quando altero uma coluna, meu aplicativo nunca para de funcionar. Quando você faz isso quebra. Acho que não há dúvida sobre qual é mais confiável ou seguro.
Morg.
@Org: Não vejo como select *é mais confiável e seguro. Se você costumava ter, select one, two from ...então você estava apenas usando onee two; se thirdfor adicionado à tabela, você não terá utilidade para isso (aqui), portanto, não há motivo para recuperá-lo. E se você precisar usá-lo repentinamente, modificará o código, para que também possa modificar a consulta neste momento!
precisa
@Org: Bem, parece que estamos falando um do outro, provavelmente porque nossas experiências são diferentes. Trabalho em produtos em que o desempenho é uma propriedade primordial, e isso significa que selectprecisa ser o mais seletivo possível (e coberto por um índice), caso contrário, eu sou brindado (mesmo antes das junções obrigatórias). Lamento dizer, mas a abordagem que você está descrevendo foi um fracasso total nesses produtos.
amigos estão
5

Nem todos os sistemas podem, ele deve ser configurado de uma maneira que o suporte.

Por exemplo, um dos nossos principais sistemas que ajudei a atualizar há alguns anos deve estar disponível 24 horas por dia, 7 dias por semana. Consistia em várias camadas, incluindo uma camada de comunicação pura entre a Camada de Interface do Usuário e a Camada de Negócios externos. Devido à maneira como a camada de comunicação foi codificada, qualquer alteração futura no esquema da camada de negócios ou do banco de dados pode ser implementada sem uma interrupção real. Na pior das hipóteses, um usuário experimentaria uma pausa de 10 a 30 segundos à medida que as alterações entrassem em vigor.

Se as alterações fossem puramente alterações de código na camada de negócios, elas poderiam ser colocadas na fila e 'entradas em ciclo' com atraso de apenas milissegundos.

Isso poderia ser feito porque:

  • A camada de comunicação pode conter mensagens. Isso nos permitiu uma interrupção real em qualquer uma das camadas, exceto a Camada da interface do usuário, sem a necessidade de desativar a interface do usuário.
  • A camada de negócios manipulada pelo MVDB chamada UniData . Isso mantém todo o código na memória. Após compilar o código, você pode usar um comando para forçar o novo código do objeto na memória, substituindo o antigo.

Outras técnicas envolvem a replicação de transações para outro espelho do sistema existente. Aplicando a atualização a uma, alternando e reproduzindo todas as transações realizadas entre a atualização e a alternância. YMMV, dependendo dos seus sistemas.

Dan McGrath
fonte
1

Aqui está uma perspectiva diferente, do mundo dos sistemas de banco de dados e sistemas embarcados. Os sistemas embarcados incluem vários equipamentos de infraestrutura de rede / telecomunicações e, nesse campo, costumam falar em 99,999% (cinco 9s) de tempo de atividade.

Nós (McObject) somos o fornecedor da família eXtremeDB de produtos de sistemas de banco de dados incorporados, incluindo o eXtremeDB High Availability.

Primeiro, entenda que "banco de dados incorporado" significa que o sistema de banco de dados é uma biblioteca que é compilada e vinculada ao código do aplicativo; nesse sentido, ele é "incorporado" no seu aplicativo.

Com o eXtremeDB High Availability, há uma instância MASTER do seu aplicativo (que pode ser um ou vários processos) e uma ou mais instâncias REPLICA do seu aplicativo. Quando uma réplica estabelece uma conexão com o mestre, ela recebe uma cópia do banco de dados do mestre através de um processo chamado "sincronização inicial". Isso pode ser feito enquanto o aplicativo mestre continua seu trabalho. Uma vez sincronizado, ele recebe as transações do mestre por meio de replicação. Portanto, uma réplica sempre possui dados atuais e pode assumir o controle (por meio de um processo chamado failover) caso o mestre falhe.

Um recurso da sincronização inicial é chamado de "evolução do esquema binário". Em inglês simples, isso significa que o processo de preenchimento do banco de dados da réplica acomodará diferenças entre o esquema do banco de dados da réplica e o esquema do banco de dados do mestre.

Na prática, isso significa que você pode criar uma versão mais recente do seu aplicativo (com tabelas novas / descartadas, campos novos / descartados / alterados, índices novos / descartados), anexar essa nova versão do aplicativo a um mestre e fazer com que réplica mais nova para se tornar o novo mestre (ou seja, forçar um failover para a nova réplica, para que ele se torne o mestre e o antigo mestre se desligue). Você migrou seu aplicativo da versão N para N + 1, sem interromper a disponibilidade do seu sistema. Agora você pode atualizar o master antigo e quaisquer outras réplicas para a versão N + 1.


fonte