Vale a pena executar o VACUUM em uma tabela que recebe apenas INSERTs?

19

Em uma palestra re: Invent de 2015, a AWS mencionou que o vácuo deve ser executado não apenas após atualizações ou exclusões, mas também após inserções. Aqui está a parte relevante da palestra:

http://www.youtube.com/watch?v=tZXp19q8RFo&t=16m2s

Supostamente, há alguma limpeza que deve ser feita nos blocos, mesmo que eles tenham recebido apenas inserções, e essa limpeza pode ser feita na primeira vez que um bloco é selecionado (diminuindo a velocidade da leitura) ou durante o vácuo. Isso é verdade? Em caso afirmativo, exatamente que limpeza deve ser feita?

foobar0100
fonte

Respostas:

15

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. VACUUMacabará 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 VACUUMnormalmente. 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 SELECTque de repente está criando muito tráfego de gravação. Executar um VACUUMapós a inserção confirma evitará isso. Outra distinção importante é queVACUUMSEMPRE 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 VACUUMpode 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. VACUUMpotencialmente pode marcar essas páginas como totalmente visíveis, mas somente se a transação em execução mais antiga quando VACUUMiniciada 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 FREEZEem 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_LIVEcaso 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

Jim Nasby
fonte
Isso é muito interessante e também explica algumas páginas sujas em certos 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 pelo COMMITor ROLLBACK, certo?
Dezso
3
COMMIT e ROLLBACK na verdade não tocam nas páginas de dados; portanto, esses comandos especificamente nunca poderiam sugerir. Um comando DML ainda pode definir os status de dica xmin e xmax, para tuplas marcadas por outras transações ou potencialmente até tuplas marcadas pela transação atual.
Jim Nasby