tl; dr: O primeiro processo que lê dados depois que eles são confirmados definirá bits de dica. Isso sujará a página, criando atividade de gravação. A outra coisa VACUUM
(mas não outros comandos) faz é marcar a página como totalmente visível, se apropriado. VACUUM
acabará tendo que bater na mesa para congelar as tuplas.
O trabalho que precisa ser feito após uma inserção não é realmente uma limpeza, pelo menos não no sentido de outro trabalho VACUUM
normalmente. Antes de entrar em detalhes, observe que esta resposta é baseada no código 9.6 atual (não lançado) e estou ignorando os efeitos da replicação de streaming, mesmo que isso possa afetar a visibilidade.
Por causa do MVCC , toda vez que o Postgres avalia se uma tupla deve estar visível para uma consulta, ele deve considerar se a transação que criou a tupla (registrada no campo oculto xmin) foi confirmada, juntamente com alguns outros critérios. Essa verificação é cara e, assim que se sabe que uma transação é visível para todas as transações atualmente abertas, um "bit de dica" é definido no cabeçalho da tupla, indicando isso. A configuração desse bit suja a página, o que significa que ela precisará ser gravada no disco. Isso pode ser muito confuso se o próximo comando para ler os dados for um SELECT
que de repente está criando muito tráfego de gravação. Executar um VACUUM
após a inserção confirma evitará isso. Outra distinção importante é queVACUUM
SEMPRE sugere dicas de tuplas em uma página (desde que tenha o bloqueio de limpeza na página), mas a maioria dos outros comandos apenas indica se a transação de inserção foi confirmada antes do início do comando.
Um ponto importante sobre a gravação de todos esses bits de dica é que VACUUM
pode ser regulado (e o vácuo automático é regulado por padrão). Outros comandos não são regulados e geram dados sujos o mais rápido possível.
VACUUM
é o único método para marcar páginas como totalmente visíveis, o que é uma consideração importante de desempenho para algumas operações (principalmente as verificações de índice). Se você fizer uma inserção grande, é muito provável que haja muitas páginas com nada além de tuplas recém-inseridas. VACUUM
potencialmente pode marcar essas páginas como totalmente visíveis, mas somente se a transação em execução mais antiga quando VACUUM
iniciada for mais recente que a transação que inseriu os dados .
Por causa de como o MVCC funciona, as tuplas que foram inseridas há mais de ~ 2 bilhões de transações atrás devem ser marcadas como " congeladas ". Por padrão, o autovacuum entra em ação para fazer isso a cada 200 milhões de transações. A execução de um aspirador manual com vacuum_freeze_min_age definido como 0 após uma inserção em massa pode ajudar a reduzir o impacto disso. Mais agressivamente, você pode correr VACUUM FREEZE
em cima da mesa após a inserção. Isso "reiniciaria o relógio" quando a próxima verificação de congelamento ocorresse.
Se você quiser conhecer os detalhes específicos, dê uma olhada no HEAPTUPLE_LIVE
caso após a chamada para HeapTupleSatisfiesVacuum()
dentro lazy_scan_heap()
. Veja também HeapTupleSatisfiesVacuum()
ele próprio e compare-o HeapTupleSatisfiesMVCC()
.
Existem outras duas apresentações minhas que podem ser interessantes. O primeiro vídeo está disponível em http://www.pgcon.org/2015/schedule/events/829.en.html , enquanto o segundo (que eu acho que foi um pouco melhor) em https://www.youtube. com / watch? v = L8nErzxPJjQ
EXPLAIN (ANALYZE, BUFFERS) outputs. But, if I understand things correctly, some of the hint bits (at least
* COMMITTED` e*INVALID
) já podem (já) ser definidas peloCOMMIT
orROLLBACK
, certo?