Here is a summary of the common database schema change mistakes, translated and structured in Korean:
Erros relacionados à concorrência
- Falha ao adquirir lock
- Atualizar linhas demais de uma só vez
- Manter a transação aberta por muito tempo após adquirir um lock exclusivo
Erros relacionados à correção das etapas - questões lógicas
- Desvio de esquema inesperado
- Incompatibilidade entre esquema e código da aplicação
- Dados inesperados
Outros erros
- Atingir
statement_timeout - Usar chave primária inteira de 4 bytes em tabelas que podem crescer
- Ignorar o funcionamento do
VACUUMe o risco de bloat
Caso 1. Incompatibilidade de esquema
- Funcionou em desenvolvimento/teste, mas falhou em QA/Staging/Produção
- É preciso identificar a causa e resolver melhorando o fluxo de trabalho
Caso 2. Uso indevido de IF [NOT] EXISTS
- Não tente ignorar erros de incompatibilidade de esquema com
IF NOT EXISTS - É preciso identificar e resolver a causa raiz do problema
Caso 3. Atingir statement_timeout
- Teste todas as mudanças com grandes volumes de dados para descobrir isso com antecedência
Caso 4. Alterações massivas sem limite
- Alterar linhas demais em uma única transação afeta outras transações
- Se o checkpointer não estiver ajustado, pode haver geração excessiva de dados WAL
- Pode ocorrer degradação geral de desempenho por saturação de escrita em disco
- Podem surgir problemas de
VACUUM/bloat - Divida em lotes e faça a gestão do
VACUUM
Caso 5. Espera dentro da transação após adquirir lock exclusivo
- Se você fizer outras operações entre
BEGIN/ALTER TABLE/COMMIT, o lock ficará retido por mais tempo - Depois de adquirir um lock exclusivo, a transação deve ser concluída o mais rápido possível
Caso 6. Transação com DDL + DML em grande volume
- O lock adquirido na etapa de DDL permanece por muito tempo até a etapa de DML
- Separe DDL e DML em transações/etapas de migração distintas
Caso 7. Bloqueio de outras sessões por espera na aquisição de lock exclusivo
- Quando o autovacuum está no modo de prevenção de wraparound, ele não faz yield para DDL
- Até mesmo
SELECTfica bloqueado enquanto se espera pela aquisição do lock - Defina
lock_timeoutbaixo e crie lógica de retry
Caso 8. Cuidados ao criar FK
- Ao criar FK em tabelas grandes, a varredura da tabela referenciada consome tempo
- Defina a FK com a opção
not valide valide em uma transação separada
Caso 9. Cuidados ao remover FK
- Como é necessário lock nas duas tabelas, é preciso lógica de retry com
lock_timeout
Caso 10. Cuidados ao adicionar restrição CHECK
- Ocorre varredura da tabela inteira, então use uma abordagem em 2 etapas semelhante à de FK
Caso 11. Cuidados ao adicionar NOT NULL
- Em versões anteriores ao Postgres 11, adicionar
NOT NULLa uma nova coluna causa varredura da tabela - A partir do Postgres 11, isso pode ser resolvido com adição de coluna
NOT NULL DEFAULT - A partir do Postgres 12, é possível definir
NOT NULLadicionando uma restriçãoCHECK
Caso 12. Cuidados ao alterar o tipo de dado de uma coluna
- Pode ocorrer regravação da tabela inteira
- É necessária uma abordagem de adicionar nova coluna e copiar os dados com trigger
Caso 13. Cuidados ao usar CREATE INDEX
- Em OLTP, deve-se usar
CREATE INDEX CONCURRENTLY - Se a criação de índice único falhar, é preciso limpar o índice inválido
Caso 14. Cuidados ao usar DROP INDEX
- Como há problema de aquisição de lock, use
DROP INDEX CONCURRENLTY
Caso 15. Cuidados ao renomear objetos
- É preciso ajustar a ordem de deploy para evitar incompatibilidade entre código da aplicação e esquema do banco
Caso 16. Adicionar coluna com valor DEFAULT
- Antes do PG 11, ocorria regravação da tabela inteira
- A partir do PG 11, ficou mais rápido adicionar coluna com valor
DEFAULT
Caso 17. Limpeza de resíduos quando CREATE INDEX CONCURRENTLY falha
- Se falhar, fica um índice inválido, então é preciso limpá-lo antes de tentar novamente
Caso 18. Uso de chave primária inteira de 4 bytes em tabelas grandes
- Deve-se usar
int8. A maioria dos frameworks já usaint8.
Recomendações
- Testar com volumes de dados realistas
- Verificar o tempo de retenção de locks exclusivos
- Melhorar a automação de deploy
- Aprender com outras pessoas e compartilhar conhecimento
Opinião do GN⁺
Este texto organiza muito bem vários erros e cuidados que podem surgir em alterações reais de esquema de banco de dados. Em especial, há muitas menções a problemas relacionados a locks exclusivos, algo que pode causar impactos ainda mais sérios em bancos de dados de grande porte.
Também explica de forma concreta os cuidados ao lidar com FK, NOT NULL, índices e outros pontos que os desenvolvedores costumam ignorar com facilidade. Entender e aproveitar as melhorias por versão do Postgres também parece bastante útil.
Acima de tudo, concordo com a ideia de que testar com volumes de dados realistas e melhorar a automação de deploy é o ponto-chave para minimizar os riscos de alterações de esquema. Para testes e automação de deploy, também pode ser interessante usar ferramentas como o Database Lab Engine.
Seria ótimo ver mais posts técnicos compartilhando dicas úteis como estas. Quanto mais esse tipo de informação se espalhar, mais isso certamente ajudará a elevar a capacidade dos desenvolvedores que trabalham com bancos de dados.
Ainda não há comentários.