PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

PostgreSQL VACUUM and ANALYZE dicas de práticas recomendadas


VACUUM e ANALYZE são as duas operações mais importantes de manutenção do banco de dados PostgreSQL.

Um vácuo é usado para recuperar o espaço ocupado por “tuplas mortas” em uma tabela. Uma tupla morta é criada quando um registro é excluído ou atualizado (uma exclusão seguida de uma inserção). O PostgreSQL não remove fisicamente a linha antiga da tabela, mas coloca um “marcador” nela para que as consultas não retornem essa linha. Quando um processo de vácuo é executado, o espaço ocupado por essas tuplas mortas é marcado como reutilizável por outras tuplas.

Uma operação de “analisar” faz o que seu nome diz – analisa o conteúdo das tabelas de um banco de dados e coleta estatísticas sobre a distribuição de valores em cada coluna de cada tabela. O mecanismo de consulta PostgreSQL usa essas estatísticas para encontrar o melhor plano de consulta. À medida que as linhas são inseridas, excluídas e atualizadas em um banco de dados, as estatísticas da coluna também mudam. ANALYZE – executado manualmente pelo DBA ou automaticamente pelo PostgreSQL após um autovacuum – garante que as estatísticas estejam atualizadas.

Embora pareçam relativamente simples, os bastidores, aspirar e analisar são dois processos complexos. Felizmente, os DBAs não precisam se preocupar muito com seus componentes internos. No entanto, eles geralmente ficam confusos sobre como executar esses processos manualmente ou definir os valores ideais para os parâmetros de configuração.

Neste artigo, compartilharemos algumas práticas recomendadas para VACUUM e ANALYZE.

Dica 1:não execute VACUUM ou ANALYZE manual sem motivo


A limpeza do PostgreSQL (autovacuum ou manual) minimiza a sobrecarga da tabela e evita o wraparound de ID de transação. Autovacuum não recupera o espaço em disco ocupado por tuplas mortas. No entanto, executar um VACUUM FULL comando fará isso. VACUUM FULL tem sua implicação de desempenho, no entanto. A tabela de destino é bloqueada exclusivamente durante a operação, impedindo leituras uniformes na tabela. O processo também faz uma cópia completa da tabela, o que requer espaço extra em disco ao ser executado. Recomendamos não executar VACUUM FULL a menos que haja uma porcentagem muito alta de inchaço e as consultas estejam sofrendo muito. Também recomendamos o uso de períodos de menor atividade do banco de dados para isso.

Também é uma prática recomendada não executar vácuos manuais com muita frequência em todo o banco de dados; o banco de dados de destino já pode ser aspirado de forma otimizada pelo processo de autovacuum. Como resultado, um vácuo manual pode não remover nenhuma tupla morta, mas causar cargas de E/S desnecessárias ou picos de CPU. Se necessário, os aspiradores manuais só devem ser executados tabela por tabela quando houver necessidade, como baixas proporções de linhas vivas para linhas mortas ou grandes intervalos entre os autovacuums. Além disso, os aspiradores manuais devem ser executados quando a atividade do usuário for mínima.

O Autovacuum também mantém as estatísticas de distribuição de dados de uma tabela atualizadas (não as reconstrói). Quando executado manualmente, o ANALISAR O comando realmente reconstrói essas estatísticas em vez de atualizá-las. Novamente, a reconstrução de estatísticas quando elas já estão atualizadas de forma otimizada por um autovacuum regular pode causar pressão desnecessária nos recursos do sistema.

O momento em que você deve executar ANALYZE manualmente é imediatamente após o carregamento em massa de dados na tabela de destino. Um grande número (mesmo algumas centenas) de novas linhas em uma tabela existente distorcerá significativamente sua distribuição de dados de coluna. As novas linhas farão com que todas as estatísticas de coluna existentes fiquem desatualizadas. Quando o otimizador de consulta usa essas estatísticas, o desempenho da consulta pode ser muito lento. Nesses casos, executar o comando ANALYZE imediatamente após um carregamento de dados para reconstruir completamente as estatísticas é uma opção melhor do que esperar que o autovacuum entre em ação.

Dica 2:ajuste o limite de vácuo automático


É essencial verificar ou ajustar o autovacuum e analisar os parâmetros de configuração no postgresql.conf arquivo ou em propriedades de tabelas individuais para encontrar um equilíbrio entre autovacuum e ganho de desempenho.

O PostgreSQL usa dois parâmetros de configuração para decidir quando iniciar um autovacuum:
  • autovacuum_vacuum_threshold :tem um valor padrão de 50
  • autovacuum_vacuum_scale_factor :tem um valor padrão de 0,2

Juntos, esses parâmetros dizem ao PostgreSQL para iniciar um autovacuum quando o número de linhas mortas em uma tabela exceder o número de linhas naquela tabela multiplicado pelo fator de escala, mais o limite de vácuo. Em outras palavras, o PostgreSQL iniciará o autovacuum em uma tabela quando:
pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor)  + autovacuum_vacuum_threshold

Para mesas pequenas e médias, isso pode ser suficiente. Por exemplo, uma tabela com 10.000 linhas, o número de linhas mortas deve ser superior a 2.050 ((10.000 x 0,2) + 50) antes que um autovacuum seja iniciado.

Nem todas as tabelas em um banco de dados experimentam a mesma taxa de modificação de dados. Normalmente, algumas tabelas grandes sofrerão modificações de dados frequentes e, como resultado, terão um número maior de linhas mortas. Os valores padrão podem não funcionar para essas tabelas. Por exemplo, com os valores padrão, uma tabela com 1 milhão de linhas precisará ter mais de 200.050 linhas mortas antes que um autovacuum seja iniciado ((1000.000 x 0,2) + 50). Isso pode significar intervalos mais longos entre os autovacuums, tempos de autovacuum cada vez mais longos e, pior, o autovacuum não sendo executado se as transações ativas na tabela o estiverem bloqueando.

Portanto, o objetivo deve ser definir esses limites para valores ideais para que o autovacuum possa ocorrer em intervalos regulares e não demore muito (e afete as sessões do usuário), mantendo o número de linhas mortas relativamente baixo.

Uma abordagem é usar um ou outro parâmetro. Portanto, se definirmos autovacuum_vacuum_scale_factor como 0 e, em vez disso, definirmos autovacuum_vacuum_threshold como, digamos, 5.000, uma tabela será autovacuada quando seu número de linhas mortas for maior que 5.000.

Dica 3:ajuste o limite de análise automática


Semelhante ao autovacuum, o autoanalyze também usa dois parâmetros que decidem quando o autovacuum também acionará uma autoanálise:
  • autovacuum_analyze_threshold :tem um valor padrão de 50
  • autovacuum_analyze_scale_factor :isso tem um valor padrão de 0,1

Assim como o autovacuum, o parâmetro autovacuum_analyze_threshold pode ser definido como um valor que determina o número de tuplas inseridas, excluídas ou atualizadas em uma tabela antes do início de uma análise automática. Recomendamos definir esse parâmetro separadamente em tabelas grandes e de alta transação. A configuração da tabela substituirá os valores postgresql.conf.

O trecho de código abaixo mostra a sintaxe SQL para modificar a configuração autovacuum_analyze_threshold para uma tabela.
ALTER TABLE <table_name> 
SET (autovacuum_analyze_threshold = <threshold rows>)

Dica 4:ajuste os trabalhadores do Autovacuum


Outro parâmetro frequentemente ignorado pelos DBAs é autovacuum_max_workers , que tem um valor padrão de 3. Autovacuum não é um processo único, mas vários segmentos de vácuo individuais executados em paralelo. A razão para especificar vários trabalhadores é garantir que a limpeza de tabelas grandes não atrapalhe a limpeza de tabelas menores e sessões de usuário. O parâmetro autovacuum_max_workers diz ao PostgreSQL para aumentar o número de threads de trabalho do autovacuum para fazer a limpeza.

Uma prática comum dos DBAs do PostgreSQL é aumentar o número máximo de threads de trabalho na esperança de acelerar o autovacuum. Isso não funciona, pois todos os encadeamentos compartilham o mesmo autovacuum_vacuum_cost_limit , que tem um valor padrão de 200. Cada thread de autovacuum recebe um limite de custo usando esta fórmula mostrada abaixo:
individual thread’s cost_limit = autovacuum_vacuum_cost_limit / autovacuum_max_workers

O custo do trabalho realizado por uma rosca de autovacuum é calculado usando três parâmetros:
  • vacuum_cost_page_hit :isso tem um valor padrão de 1
  • vacuum_cost_page_miss :tem um valor padrão de 10
  • vacuum_cost_page_dirty :tem um valor padrão de  20

O que esses parâmetros significam é o seguinte:
  • Quando um segmento de vácuo encontra a página de dados que deve limpar no buffer compartilhado, o custo é 1. 
  • Se a página de dados não estiver no buffer compartilhado, mas no cache do SO, o custo será de 10. 
  • Se a página tiver que ser marcada como suja porque o tópico de vácuo teve que excluir linhas mortas, o custo será de 20.

Um número maior de threads de trabalho reduzirá o limite de custo para cada thread. Como cada thread recebe um limite de custo mais baixo, ele irá dormir com mais frequência, pois o limite de custo é facilmente alcançado, fazendo com que todo o processo de vácuo fique lento. Recomendamos aumentar o autovacuum_vacuum_cost_limit para um valor mais alto, como 2000, e depois ajustar o número máximo de threads de trabalho.

Uma maneira melhor é ajustar esses parâmetros para tabelas individuais somente quando necessário. Por exemplo, se o autovacuum de uma grande tabela transacional estiver demorando muito, a tabela pode ser configurada temporariamente para usar seu próprio limite de custo de vácuo e atrasos de custo. O limite de custo e o atraso substituirão os valores de todo o sistema definidos em postgresql.conf.

O trecho de código abaixo mostra como configurar tabelas individuais.
ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_limit = <large_value>)
ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_delay = <lower_cost_delay>)

O uso do primeiro parâmetro garantirá que o encadeamento de autovacuum atribuído à tabela realizará mais trabalho antes de dormir. Abaixando o autovacuum_vacuum_cost_delay também significará que o thread está dormindo menos tempo.

Considerações finais


Como você pode ver, alterar os parâmetros de configuração para vácuo e análise é simples, mas primeiro requer uma observação cuidadosa. Cada banco de dados é diferente em termos de tamanho, padrão de tráfego e taxa de transações. Recomendamos que os DBAs comecem reunindo informações suficientes sobre seu banco de dados antes de alterar os parâmetros ou implementar um regime manual de vácuo/análise. Tais informações podem ser:
  • Número de linhas em cada tabela
  • Número de tuplas mortas em cada tabela
  • A hora do último vácuo para cada tabela
  • A hora da última análise de cada tabela
  • A taxa de inserção/atualização/exclusão de dados em cada tabela
  • O tempo gasto pelo autovacuum para cada mesa
  • Avisos sobre as tabelas não serem aspiradas
  • Desempenho atual das consultas mais críticas e das tabelas que elas acessam
  • Desempenho das mesmas consultas após uma limpeza/análise manual

A partir daqui, os DBAs podem selecionar algumas tabelas “piloto” para começar a otimizar. Eles podem começar a alterar as propriedades de vácuo/análise das tabelas e verificar o desempenho. O PostgreSQL é um mecanismo de banco de dados inteligente – os DBAs geralmente acharão que é melhor deixar o PostgreSQL fazer a limpeza e a análise em vez de fazê-los manualmente.