Alterar tabela em bancos de dados de produção ao vivo

24

Como a maioria dos sistemas de banco de dados "populares" (MySQL, Postgres ...) lida com a alteração de tabelas em bancos de dados de produção ao vivo (como adicionar, excluir ou alterar o tipo de colunas)?

Eu sei que a maneira correta é fazer backup de tudo, agendar o tempo de inatividade e, em seguida, fazer as alterações.

Mas ... algum sistema de banco de dados atual suporta fazer essas coisas "on-line" sem parar nada? (talvez apenas adie as consultas que fazem referência a uma coluna que está sendo alterada / excluída)

E o que acontece quando eu apenas faço um ALTER TABLE...banco de dados em execução ao vivo? Tudo para quando isso acontece? Os dados podem ser corrompidos? etc.

Mais uma vez, estou me referindo principalmente ao Postgres ou MySQL, pois é isso que encontro.

(E, sim, sempre que eu tinha que fazer isso antes de fazer "da maneira certa", fazendo backup, agendando o downtine etc. ... mas eu só quero saber se é possível fazer esse tipo de coisa "de maneira rápida e sujo "ou se houver algum sistema de banco de dados que realmente suporte as alterações de esquema" rápidas, ativas e sujas ")


Alguém acabou de sugerir o Online Schema Change for MySQL a partir do script do Facebook (com um tutorial aqui e a fonte aqui ) ... parece ser uma boa maneira de automatizar um conjunto de maneiras "hacky" de fazer isso ... alguém já usou isso algo semelhante à produção?

NeuronQ
fonte
3
Nota: a "maneira correta" especificada é relativa ao MySQL e não ao PostgreSQL. A "maneira correta" no PostgreSQL é tipicamente muito fácil, embora possa estar envolvida. O uso de pg_reorgpode ajudar nos cenários mais difíceis.
19412 Sean
Eu adoraria ter um vídeo detalhado sobre isso, com alguém explicando o maior número possível de estratégias.
Sandeepan Nath

Respostas:

22

Quando você publica um ALTER TABLEno PostgreSQL , é necessário um ACCESS EXCLUSIVEbloqueio que bloqueia tudo, inclusiveSELECT . No entanto, esse bloqueio pode ser bastante breve, se a tabela não requer re-escrita, sem novas UNIQUE, CHECKou FOREIGN KEYrestrições precisa caros varreduras de tabela completa para verificar, etc.

Em caso de dúvida, você geralmente pode tentar! Todo o DDL no PostgreSQL é transacional, por isso é muito bom cancelar um ALTER TABLEcaso demore muito e comece a realizar outras consultas. Os níveis de bloqueio exigidos por vários comandos estão documentados na página de bloqueio .

Algumas operações normalmente lentas podem ser aceleradas para serem seguras sem tempo de inatividade. Por exemplo, se você possui uma tabela te deseja alterar a coluna customercode integer NOT NULLpara textporque o cliente decidiu que todos os códigos do cliente devem começar agora com um X, você pode escrever:

ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );

... mas isso trancaria a tabela inteira para a reescrita. O mesmo acontece com a adição de uma coluna com a DEFAULT. Isso pode ser feito em algumas etapas para evitar o bloqueio longo, mas os aplicativos devem ser capazes de lidar com a duplicação temporária:

ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;

Isso só vai impedir que escreve para tdurante o processo; o nome da fechadura EXCLUSIVEé um tanto enganador, pois exclui tudo, excetoSELECT ; o ACCESS EXCLUSIVEmodo é o único que exclui absolutamente tudo. Veja os modos de bloqueio . Existe o risco de que esta operação possa causar um bloqueio de impasse devido à atualização de bloqueio exigida pelo ALTER TABLE, mas, na pior das hipóteses, você precisará fazer isso novamente.

Você pode até mesmo evitar que o bloqueio e fazer a coisa toda ao vivo, criando uma função gatilho em tque sempre que um INSERTou UPDATEentra, preenche automaticamente customercode_newde customercode.

Também existem ferramentas integradas, como CREATE INDEX CONCURRENTLYe ALTER TABLE ... ADD table_constraint_using_indexprojetadas para permitir que os DBAs reduzam as durações de bloqueio exclusivas, trabalhando mais devagar e de maneira favorável à concorrência.

A pg_reorgferramenta ou seu sucessor também pg_repackpode ser usada para algumas operações de reestruturação de tabelas.

Craig Ringer
fonte
11
O principal no que o @Craig disse foi: "se não for necessário reescrever". Usar um ALTER TABLE t ADD COLUMN i INTé uma operação rápida (normalmente <1 ms) depois que a trava é adquirida. A aquisição do bloqueio pode enfileirar as conexões, no entanto, portanto, não é "gratuito" ... embora seja melhor do que o que você precisa fazer no MySQL. Adicionar uma NOT NULLrestrição é mais difícil e não para a fingida de coração.
19412 Sean
Parece haver consenso sobre pg_repacko sucessor aprimorado de pg_reorg.
Erwin Brandstetter
Uma boa resposta, ao adicionar uma coluna com uma maneira padrão (ou calculada) de forma menos "bloqueadora", é criar uma nova tabela inteira, bloquear a tabela antiga para inserir / atualizar / excluir, mas permitir selecionar e preencher a nova. Finalmente, emita um breve bloqueio exclusivo na tabela antiga para selecionar, excluí-lo e renomear novo para antigo. Dependendo do cenário, você pode até começar a preencher o novo sem bloquear inserções no velho e questão que bloqueio exclusivo apenas enquanto resolvendo o diff (espero apenas inserindo alguns novos registros)
jean
7

A Percona criou sua própria ferramenta para realizar alterações de esquema on-line

A ferramenta é chamada pt-online-schema-change

Envolve gatilhos, portanto, leia atentamente a documentação.

De acordo com a documentação, as principais operações realizadas são

  • Verificações de sanidade
  • Chunking
  • Alteração de esquema online
    • Criar e alterar tabela temporária
    • Capturar alterações da tabela para a tabela temporária
    • Copiar linhas da tabela para a tabela temporária
    • Sincronize a tabela e a tabela temporária
    • Troque / renomeie a tabela e a tabela temporária
    • Limpar
RolandoMySQLDBA
fonte
graças, parece ser uma versão "soldified" da abordagem do Facebook que eu podia confiar mais ...
NeuronQ
pt-online-schema-change é definitivamente a maneira preferida de fazer isso se você estiver executando seu próprio servidor MySQL. A partir do Percona Tools 2.2, (infelizmente) eles não suportam RDS / Aurora na AWS. pt-online-schema-change insere um gatilho na tabela de origem para copiar linhas (baixa prioridade para MyISAM) para o table_temp de destino e executa um único bloqueio rápido e renomeia no final quando todas as linhas estão sincronizadas entre a origem e o destino tabelas.
Phpuru Apr
6

Desligar o sistema e fazer todas as alterações ao mesmo tempo pode ser muito arriscado. Se algo der errado, e freqüentemente acontece, não há caminho mais fácil de voltar.

Como desenvolvedor Agile, às vezes preciso refatorar tabelas sem nenhum tempo de inatividade, pois essas tabelas estão sendo modificadas e lidas.

A abordagem a seguir tem baixo risco, porque a alteração é feita em várias etapas de baixo risco que são muito fáceis de reverter:

  • Verifique se todos os módulos que acessam a tabela estão bem cobertos com testes automatizados.
  • Crie uma nova tabela. Altere todos os procedimentos que modificam a tabela antiga, para que eles modifiquem as tabelas antiga e nova.
  • Migrar dados existentes para uma nova estrutura. Faça isso em lotes pequenos, para não afetar seriamente o desempenho geral do servidor.
  • Verifique se a migração de dados foi bem-sucedida.
  • Redirecione alguns dos procedimentos de seleção da tabela antiga para os novos. Use testes automatizados para garantir que os módulos alterados ainda estejam corretos. Verifique se o desempenho deles é aceitável. Implante os procedimentos alterados.
  • Repita a etapa anterior até que todos os relatórios usem a nova tabela.
  • Altere os procedimentos que modificam as tabelas, para que eles acessem apenas a nova tabela.
  • Arquive a tabela antiga e remova-a do sistema.

Usamos essa abordagem várias vezes para alterar grandes tabelas de produção ao vivo sem tempo de inatividade, sem problemas.

AK
fonte
3
grande ... mas isso é exatamente o tipo de "dor" que eu estou olhando para evitar :)
NeuronQ
@NeuronQ " Não há caminho mais fácil " - existe no Postgres: basta colocar tudo em uma transação e rollbackse algo der errado.
A_horse_with_no_name 25/09
2

Sim, muitos bancos de dados modernos permitem adicionar uma coluna ou alterar as características de uma coluna, como adicionar ou remover nulos.

Se você soltar uma coluna, os dados serão perdidos, mas não haverá muito medo de corrupção.

Marlin Pierce
fonte
0

A ferramenta Percona usa gatilhos para ajudar na alteração e não funciona muito bem se sua mesa já possui gatilhos. Acabei tendo que escrever um que realmente lide bem com os gatilhos existentes, pois eles são super importantes para nosso banco de dados https://github.com/StirlingMarketingGroup/smg-live-alter

Brian diz Restabelecer Monica
fonte
-1

Para responder à pergunta sobre o que acontece com uma ALTER TABLEdeclaração, isso depende da extensão de suas alterações. Em casos específicos, se você adicionar uma nova coluna, pelo menos no MS SQL Server, o mecanismo criará uma cópia temporária da tabela, enquanto cria a nova definição de tabela e, em seguida, insere os dados nela. Durante a duração da alteração, a tabela ficaria inacessível para os usuários.

Um exemplo das operações específicas para o servidor MSSQL está aqui: http://support.microsoft.com/kb/956176/en-us

Eu diria que outros RMDBs têm métodos semelhantes, embora a implementação exata seja algo que você precisaria verificar com a documentação do fornecedor.

SchmitzIT
fonte
-1 Isso está completamente errado para o SQL Server: "Se você adicionar uma nova coluna, pelo menos no MS SQL Server, o mecanismo criará uma cópia temporária da tabela, enquanto cria a nova definição de tabela e depois insere os dados novamente. lá "
AK
@AlexKuznetsov - Imaginei a linha anterior, assim como o link com alguns dos casos listados esclareceria que isso nem sempre acontece. Eu alterei a frase para refletir melhor isso.
21412 SchmitzIT
11
Você está mencionando o comportamento da GUI, SSMS, não o comportamento do próprio SQL Server. Seguindo o seu link, o conselho é usar o T-SQL diretamente para fazer alterações no DDL. O SSMS não é uma ferramenta muito boa para alterar o DDL.
AK
@AlexKuznetsov - li o artigo dizendo que há riscos envolvidos, mas não como desânimo. De qualquer forma, não vinculei o artigo para o bit da GUI, mas como uma indicação de algumas das operações que levam a uma instrução ALTER que leva à criação de uma tabela temporária devido a alterações na estrutura de dados subjacente. Não testei se exatamente o mesmo se aplica ao emitir a instrução diretamente do T-SQL, mas acho que o processo é bem parecido e que o SL Server faz o trabalho braçal nos bastidores.
21412 SchmitzIT
Você pode iniciar o Profiler, executar a instrução ALTER TABLE diretamente e ver o que está acontecendo. Em seguida, você pode alterar uma tabela através de uma caixa de diálogo e ver por si mesmo os comandos que estão sendo executados.
AK