Ajuste de vácuo automático no Banco de Dados do Azure para PostgreSQL – Servidor Flexível
APLICA-SE A: Banco de Dados do Azure para PostgreSQL – Servidor Flexível
Este artigo fornece uma visão geral do recurso de autovácuo para o servidor flexível do Banco de Dados do Azure para PostgreSQL e os guias de solução de problemas de recursos disponíveis para monitorar o inchaço do banco de dados, bloqueadores de autovácuo e também informações sobre a distância do banco de dados em situações de emergência ou de encapsulamento.
O que é o vácuo automático
A consistência de dados interna no PostgreSQL baseia-se no mecanismo MVCC (Controle de Simultaneidade de Várias Versões), que permite que o mecanismo de banco de dados mantenha várias versões de uma linha e forneça maior simultaneidade com bloqueio mínimo entre os diferentes processos.
Os bancos de dados PostgreSQL precisam de manutenção apropriada. Por exemplo, quando uma linha é excluída, ela não é removida fisicamente. Em vez disso, a linha é marcada como "morta". Assim como para atualizações, a linha é marcada como "inativa" e uma nova versão da linha é inserida. Essas operações deixam para trás registros mortos, chamados tuplas inativas, mesmo depois da conclusão de todas as transações que podem ver essas versões. A menos que estejam limpas, as tuplas inativas permanecem consumindo espaço em disco e sobrecarregando tabelas e índices que resultam em desempenho de consulta lento.
O PostgreSQL usa um processo chamado de vácuo automático para limpar automaticamente tuplas mortas.
Vácuo automático interno
O vácuo automático faz a leitura das páginas procurando por tuplas mortas e, se nenhuma for encontrada, o vácuo automático descarta a página. Quando o vácuo automático encontra tuplas inativas, ele as remove. O custo é baseado em:
vacuum_cost_page_hit
: Custo de leitura de uma página que já está em buffers compartilhados e não precisa de uma leitura de disco. O valor padrão é definido como 1.vacuum_cost_page_miss
: Custo da busca de uma página que não está em buffers compartilhados. O valor padrão é definido como 10.vacuum_cost_page_dirty
: custo de gravação em uma página quando tuplas inativas são encontradas nela. O valor padrão é definido como 20.
A quantidade de vácuo automático de trabalho depende de dois parâmetros:
autovacuum_vacuum_cost_limit
é a quantidade de trabalho que o vácuo automático faz de uma só vez.autovacuum_vacuum_cost_delay
número de milissegundos em que o vácuo automático está em suspensão depois de atingir o limite de custo especificado pelo parâmetroautovacuum_vacuum_cost_limit
.
Em todas as versões atualmente com suporte do Postgres, o padrão para autovacuum_vacuum_cost_limit
é 200 (na verdade, ele é definido como -1, o que o torna igual ao valor do vacuum_cost_limit
regular que, por padrão, é 200).
Quanto ao autovacuum_vacuum_cost_delay
, na versão 11 do Postgres, o padrão é 20 milissegundos, enquanto nas versões 12 e posteriores do Postgres, o padrão é 2 milissegundos.
O vácuo automático é ativado 50 vezes (50*20 ms=1000 ms) a cada segundo. Toda vez que é ativado, o vácuo automático lê 200 páginas.
Isso significa que, em um segundo, o vácuo automático pode fazer:
- ~80 MB/S [ (200 páginas/
vacuum_cost_page_hit
) * 50 * 8 KB por página] se todas as páginas com tuplas inativas forem encontradas em buffers compartilhados. - ~8 MB/S [ (200 páginas/
vacuum_cost_page_miss
) * 50 * 8 KB por página] se todas as páginas com tuplas inativas forem lidas no disco. - ~4 MB/S [ (200 páginas/
vacuum_cost_page_dirty
) * 50 * 8 KB por página] o vácuo automático pode gravar até 4 MB/s.
Monitorar o vácuo automático
Use as seguintes consultas para monitorar o vácuo automático:
select schemaname,relname,n_dead_tup,n_live_tup,round(n_dead_tup::float/n_live_tup::float*100) dead_pct,autovacuum_count,last_vacuum,last_autovacuum,last_autoanalyze,last_analyze from pg_stat_all_tables where n_live_tup >0;
As seguintes colunas ajudam a determinar se o vácuo automático está alcançando a atividade da tabela:
- dead_pct: porcentagem de tuplas mortas em comparação com as tuplas vivas.
- last_autovacuum: a data da última vez que a tabela foi aspirada automaticamente.
- last_autoanalyze: a data da última vez que a tabela foi analisada automaticamente.
Quando o PostgreSQL dispara o vácuo automático
Uma ação de vácuo automático (ANALYZE ou VACUUM) é disparada quando o número de tuplas inativas excede um número específico que depende de dois fatores: a contagem total de linhas em uma tabela, além de um limite fixo. ANALYZE, por padrão, é disparado quando 10% da tabela mais 50 linhas são alteradas, enquanto VACUUM é disparado quando 20% da tabela mais 50 linhas são alteradas. Como o limite VACUUM é duas vezes mais alto que o limite ANALYZE, ANALYZE é disparado anteriormente ao VACUUM.
As equações exatas para cada ação são:
- Autoanalyze = autovacuum_analyze_scale_factor * tuples + autovacuum_analyze_threshold
- Autovacuum = autovacuum_vacuum_scale_factor * tuples + autovacuum_vacuum_threshold
Por exemplo, analise gatilhos após a alteração de 60 linhas em uma tabela que contém 100 linhas e gatilhos de vácuo quando 70 linhas são alteradas na tabela, usando as seguintes equações:
Autoanalyze = 0.1 * 100 + 50 = 60
Autovacuum = 0.2 * 100 + 50 = 70
Use a consulta a seguir para listar as tabelas em um banco de dados e identificar as tabelas que se qualificam para o processo de salvamento automático:
SELECT *
,n_dead_tup > av_threshold AS av_needed
,CASE
WHEN reltuples > 0
THEN round(100.0 * n_dead_tup / (reltuples))
ELSE 0
END AS pct_dead
FROM (
SELECT N.nspname
,C.relname
,pg_stat_get_tuples_inserted(C.oid) AS n_tup_ins
,pg_stat_get_tuples_updated(C.oid) AS n_tup_upd
,pg_stat_get_tuples_deleted(C.oid) AS n_tup_del
,pg_stat_get_live_tuples(C.oid) AS n_live_tup
,pg_stat_get_dead_tuples(C.oid) AS n_dead_tup
,C.reltuples AS reltuples
,round(current_setting('autovacuum_vacuum_threshold')::INTEGER + current_setting('autovacuum_vacuum_scale_factor')::NUMERIC * C.reltuples) AS av_threshold
,date_trunc('minute', greatest(pg_stat_get_last_vacuum_time(C.oid), pg_stat_get_last_autovacuum_time(C.oid))) AS last_vacuum
,date_trunc('minute', greatest(pg_stat_get_last_analyze_time(C.oid), pg_stat_get_last_autoanalyze_time(C.oid))) AS last_analyze
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE C.relkind IN (
'r'
,'t'
)
AND N.nspname NOT IN (
'pg_catalog'
,'information_schema'
)
AND N.nspname !~ '^pg_toast'
) AS av
ORDER BY av_needed DESC ,n_dead_tup DESC;
Observação
A consulta não leva em consideração que o vácuo automático pode ser configurado por tabela usando o comando DDL "alter table".
Problemas comuns de vácuo automático
Analise a seguinte lista de possíveis problemas comuns com o processo de vácuo automático.
Não acompanhar o servidor ocupado
O processo de salvamento automático estima o custo de cada operação de E/S, acumula um total para cada operação executada e pausa quando o limite superior do custo é atingido. autovacuum_vacuum_cost_delay
e autovacuum_vacuum_cost_limit
são os dois parâmetros de servidor que são usados no processo.
Por padrão, autovacuum_vacuum_cost_limit
é definido como –1, o que significa que o limite de custo de vácuo automático é o mesmo valor que o parâmetro vacuum_cost_limit
, que usa 200 como padrão. vacuum_cost_limit
é o custo de um vácuo manual.
Se autovacuum_vacuum_cost_limit
estiver definido como -1
, o vácuo automático, usará o parâmetro vacuum_cost_limit
, mas se o próprio autovacuum_vacuum_cost_limit
estiver definido como maior do que -1
, o parâmetro autovacuum_vacuum_cost_limit
será considerado.
Caso o vácuo automático não esteja funcionando corretamente, os seguintes parâmetros poderão ser alterados:
Parâmetro | Descrição |
---|---|
autovacuum_vacuum_scale_factor |
Padrão: 0.2 , alcance: 0.05 - 0.1 . O fator de escala é específico da carga de trabalho e deve ser definido dependendo da quantidade de dados nas tabelas. Antes de alterar o valor, investigue a carga de trabalho e os volumes de tabela individuais. |
autovacuum_vacuum_cost_limit |
Padrão: 200 . O limite de custos pode ser aumentado. A utilização de E/S e CPU no banco de dados deve ser monitorada antes e depois de fazer alterações. |
autovacuum_vacuum_cost_delay |
Versão 11 do Postgres - Padrão: 20 ms . O parâmetro pode ser reduzido para 2-10 ms .Versões do Postgres 12 e superiores - Padrão: 2 ms . |
Observação
O valor autovacuum_vacuum_cost_limit
é distribuído proporcionalmente entre os trabalhos de vácuo automático em execução, de modo que, se houver mais de um, a soma dos limites para cada trabalho não excede o valor do parâmetro autovacuum_vacuum_cost_limit
Vácuo automático em constante execução
Executar continuamente o vácuo automático pode afetar a utilização da CPU e de E/S no servidor. Os seguintes podem ser possíveis motivos:
maintenance_work_mem
O daemon de vácuo automático usa autovacuum_work_mem
o que é, por padrão, definido como -1
significando que autovacuum_work_mem
teria o mesmo valor que o parâmetro maintenance_work_mem
. Este documento pressupõe que autovacuum_work_mem
está definido como -1
e maintenance_work_mem
é usado pelo daemon de vácuo automático.
Se maintenance_work_mem
for baixo, ele poderá ser aumentado para até 2 GB no Banco de Dados do Azure para servidor flexível PostgreSQL. Uma regra geral é alocar 50 MB para maintenance_work_mem
para cada 1 GB de RAM.
Grande quantidade de bancos de dados
O vácuo automático tenta iniciar um trabalho em cada banco de dados a cada autovacuum_naptime
segundos.
Por exemplo, se um servidor tiver 60 bancos de dados e autovacuum_naptime
for definido como 60 segundos, o trabalho de vácuo automático será iniciado a cada segundo [autovacuum_naptime/Number of DBs].
É uma boa ideia aumentar autovacuum_naptime
se houver mais bancos de dados em um cluster. Ao mesmo tempo, o processo de vácuo automático pode se tornar mais agressivo aumentando o autovacuum_cost_limit
e diminuindo os parâmetros autovacuum_cost_delay
e aumentando o autovacuum_max_workers
do padrão de 3 para 4 ou 5.
Erros de memória insuficiente
Valores de maintenance_work_mem
excessivamente agressivos podem periodicamente causar erros fora da memória no sistema. É importante entender a RAM disponível no servidor antes de fazer qualquer alteração no parâmetro maintenance_work_mem
.
O vácuo automático é muito disruptivo
Se o vácuo automático estiver consumindo muitos recursos, o seguinte poderá ser feito:
Parâmetros de vácuo automático
Avalie os parâmetros autovacuum_vacuum_cost_delay
, autovacuum_vacuum_cost_limit
. autovacuum_max_workers
. Definir incorretamente parâmetros de vácuo automático pode levar a cenários em que o vácuo automático se torna muito disruptivo.
Se o vácuo automático estiver muito disruptivo, considere o seguinte:
- Aumente
autovacuum_vacuum_cost_delay
e reduzaautovacuum_vacuum_cost_limit
se definido acima do padrão de 200. - Reduza o número de
autovacuum_max_workers
se ele for definido acima do padrão de 3.
Muitos trabalhos do vácuo automático
Aumentar o número de trabalhadores de vácuo automático não necessariamente aumentará a velocidade do vácuo. Não é recomendável ter um alto número de trabalhos de vácuo automático.
Aumentar o número de trabalhos de vácuo automático resultará em mais consumo de memória e, dependendo do valor de maintenance_work_mem
, pode causar degradação de desempenho.
Cada processo de trabalho de vácuo automático só obtém (1/autovacuum_max_workers) do autovacuum_cost_limit
total e, portanto, ter um alto número de trabalhos faz com que cada um fique mais lento.
Se o número de trabalhos for aumentado, autovacuum_vacuum_cost_limit
também deverá ser aumentado e/ou autovacuum_vacuum_cost_delay
deverá ser reduzido para acelerar o processo de vácuo.
No entanto, se alterarmos o nível autovacuum_vacuum_cost_delay
ou autovacuum_vacuum_cost_limit
da tabela, os parâmetros, os trabalhos em execução nessas tabelas serão isentos de serem considerados no algoritmo de balanceamento [autovacuum_cost_limit/autovacuum_max_workers].
Proteção contra solução alternativa de ID de transação (TXID) de vácuo automático
Quando um banco de dados é executado na proteção contra solução alternativa da ID da transação, uma mensagem de erro como a seguinte poderá ser observada:
Database isn't accepting commands to avoid wraparound data loss in database 'xx'
Stop the postmaster and vacuum that database in single-user mode.
Observação
Essa mensagem de erro é um descuido de longa data. Normalmente, você não precisa mudar para o modo de usuário único. Em vez disso, você pode executar os comandos VACUUM necessários e executar o ajuste para que o VACUUM seja executado rapidamente. Embora não seja possível executar nenhuma linguagem de manipulação de dados (DML), você ainda pode executar VACUUM.
O problema de encapsulamento ocorre quando o banco de dados não é aspirado ou há muitas tuplas mortas que não puderam ser removidas pelo vácuo automático. Os erros podem ser causados pelos seguintes motivos:
Carga de trabalho pesada
A carga de trabalho pode causar muitas tuplas inativas em um breve período, o que dificulta a recuperação automática. As tuplas inativas no sistema se somam em um período que leva à degradação do desempenho da consulta e leva à situação de solução alternativa. Uma das razões para essa situação surgir pode ser porque os parâmetros de vácuo automático não estão definidos adequadamente e não está acompanhando um servidor ocupado.
Transações de longa execução
Qualquer transação de execução prolongada no sistema não permitirá que tuplas mortas sejam removidas enquanto o vácuo automático estiver em execução. Elas são um bloqueador ao processo de vácuo. A remoção das transações de execução prolongada libera tuplas inativas para exclusão quando o vácuo automático é executado.
Transações de longa execução podem ser detectadas usando a seguinte consulta:
SELECT pid, age(backend_xid) AS age_in_xids,
now () - xact_start AS xact_age,
now () - query_start AS query_age,
state,
query
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY 2 DESC
LIMIT 10;
Instruções preparadas
Se houver instruções preparadas que não sejam confirmadas, elas evitarão que tuplas mortas sejam removidas.
A consulta a seguir ajuda a localizar instruções preparadas não confirmadas:
SELECT gid, prepared, owner, database, transaction
FROM pg_prepared_xacts
ORDER BY age(transaction) DESC;
Use COMMIT PREPARED ou ROLLBACK PREPARED para confirmar ou reverter essas instruções.
Slots de replicação não utilizados
Slots de replicação não utilizados impedem que o vácuo automático reclame tuplas inativas. A consulta a seguir ajuda a identificar slots de replicação não utilizados:
SELECT slot_name, slot_type, database, xmin
FROM pg_replication_slots
ORDER BY age(xmin) DESC;
Use pg_drop_replication_slot()
para excluir slots de replicação não utilizados.
Quando o banco de dados for executado na proteção contra solução alternativa da ID da transação, verifique se há bloqueadores conforme mencionado anteriormente e remova-os manualmente para que o salvamento automático continue e seja concluído. Você também pode aumentar a velocidade do vácuo automático definindo autovacuum_cost_delay
como 0 e aumentando autovacuum_cost_limit
para um valor maior que 200. No entanto, as alterações nesses parâmetros não serão aplicadas aos trabalhadores de vácuo automático existentes. Reinicie o banco de dados ou mate os trabalhos existentes manualmente para aplicar alterações de parâmetros.
Requisitos específicos da tabela
Parâmetros de vácuo automático podem ser definidos para tabelas individuais. É especialmente importante para tabelas pequenas e grandes. Por exemplo, para uma tabela pequena que contém apenas 100 linhas, o vácuo automático dispara a operação VACUUM quando 70 linhas são alteradas (conforme calculado anteriormente). Se essa tabela for atualizada com frequência, você poderá ver centenas de operações de salvamento automático por dia. Isso impede que o vácuo automático mantenha outras tabelas nas quais o percentual de alterações não é tão grande. Como alternativa, uma tabela que contenha um bilhão de linhas precisa alterar 200 milhões de linhas para disparar operações de vácuo automático. A definição de parâmetros de vácuo automático impede adequadamente esses cenários.
Para definir a configuração de vácuo automático por tabela, altere os parâmetros do servidor como os seguintes exemplos:
ALTER TABLE <table name> SET (autovacuum_analyze_scale_factor = xx);
ALTER TABLE <table name> SET (autovacuum_analyze_threshold = xx);
ALTER TABLE <table name> SET (autovacuum_vacuum_scale_factor = xx);
ALTER TABLE <table name> SET (autovacuum_vacuum_threshold = xx);
ALTER TABLE <table name> SET (autovacuum_vacuum_cost_delay = xx);
ALTER TABLE <table name> SET (autovacuum_vacuum_cost_limit = xx);
Cargas de trabalho somente inserção
Nas versões do PostgreSQL anteriores à 13, o vácuo automático não será executado em tabelas com uma carga de trabalho somente inserção, pois se não houver atualizações ou exclusões, não haverá tuplas mortas e nenhum espaço livre que precise ser recuperado. No entanto, a autoanálise será executada para cargas de trabalho de somente inserção, pois há novos dados. As desvantagens dessa arquitetura são:
- O mapa de visibilidade das tabelas não é atualizado e, portanto, o desempenho da consulta, especialmente onde há Apenas Verificações de Índice, começa a sofrer ao longo do tempo.
- O banco de dados pode ser executado na proteção de solução alternativa da ID da transação.
- Os bits de dica não serão definidos.
Soluções
Versões do Postgres anteriores à 13
Usando a extensão pg_cron, um trabalho cron pode ser configurado para agendar uma análise periódica de vácuo na tabela. A frequência do trabalho cron depende da carga de trabalho.
Para obter diretrizes passo a passo usando pg_cron, confira Extensões.
Postgres 13 e versões posteriores
O vácuo automático será executado em tabelas com uma carga de trabalho somente inserção. Dois novos parâmetros de servidor autovacuum_vacuum_insert_threshold
e autovacuum_vacuum_insert_scale_factor
ajudam a controlar quando o vácuo automático puder ser disparado em tabelas somente inserção.
Guias de solução de problemas
Usando os guias de solução de problemas de recursos, que estão disponíveis no portal do servidor flexível do Banco de Dados do Azure para PostgreSQL, é possível monitorar o inchaço no nível do banco de dados ou do esquema individual, além de identificar possíveis bloqueadores para o processo de autovácuo. Dois guias de solução de problemas estão disponíveis primeiro; um é o monitoramento de vácuo automático, que pode ser usado para monitorar o bloat no banco de dados ou no nível de esquema individual. O segundo guia de solução de problemas são os bloqueadores de vácuo automático e a solução alternativa, que ajuda a identificar possíveis bloqueadores de vácuo automático, juntamente com informações sobre o quão longe os bancos de dados no servidor estão da solução alternativa ou da situação de emergência. Os guias de solução de problemas também compartilham recomendações para atenuar possíveis problemas. Para saber como configurar os guias de solução de problemas para usá-los, siga configurar os guias de solução de problemas.