Outro dia, Amit Kapila cometeu um adesivo Masahiko Sawada, que permite a limpeza em paralelo. A tabela em si ainda é limpa por um processo (principal), mas, para limpar índices, agora pode iniciar fluxos de trabalho em segundo plano, um para cada índice. No modo manual, isso permite acelerar a limpeza de tabelas grandes com vários índices; a limpeza automática ainda não usa esse recurso.Links Relacionados:
Como você sabe , o processo de limpeza da mesa consiste em várias fases.Primeiro, a tabela é varrida e os links para versões desnecessárias ("inoperantes") das linhas são coletados na memória. A memória é limitada pelo parâmetro maintenance_work_mem , portanto, todos os links podem não caber ao mesmo tempo.Todos os índices são classificados sequencialmente (como antes) e os ponteiros para as versões mortas encontradas das seqüências de caracteres são limpos deles.Em seguida, a parte já visualizada da tabela é varrida novamente e as versões mortas das linhas já são limpas.Se ao mesmo tempo não foi possível processar todas as versões mortas de seqüências de caracteres, a memória é limpa e todo o processo é repetido novamente do local em que paramos da última vez.Todo esse esquema permanece inalterado, mas agora os índices podem ser limpos em paralelo. Para fazer isso, o processo principal inicia vários fluxos de trabalho que analisam os índices existentes e os processam. Um índice é processado por apenas um processo. Depois que todos os índices são limpos, os fluxos de trabalho são concluídos e o facilitador prossegue para a próxima fase.Por exemplo, pegue a ticket_flights
tabela de voo da desmobase . Há um índice nele, mas você pode criar mais alguns.demo=# CREATE index on ticket_flights (fare_conditions);
demo=# CREATE index on ticket_flights (amount);
Somente índices cujo tamanho excede o valor do parâmetro min_parallel_index_scan_size estão envolvidos no processamento paralelo . Nossos índices são adequados:demo=# SHOW min_parallel_index_scan_size;
min_parallel_index_scan_size
------------------------------
512kB
(1 row)
demo=# SELECT pg_size_pretty(pg_relation_size(indexname::regclass))
FROM pg_indexes
WHERE tablename = 'ticket_flights';
pg_size_pretty
----------------
325 MB
187 MB
180 MB
(3 rows)
Atualize metade das linhas para carregar o trabalho de limpeza:demo=# UPDATE ticket_flights SET amount = amount + 1 WHERE random() > 0.5;
UPDATE 4194262
Vai.demo=# VACUUM VERBOSE ticket_flights;
INFO: vacuuming "bookings.ticket_flights"
INFO: launched 2 parallel vacuum workers for index vacuuming (planned: 2)
INFO: scanned index "ticket_flights_fare_conditions_idx" to remove 4194262 row versions by parallel vacuum worker
DETAIL: CPU: user: 1.84 s, system: 0.41 s, elapsed: 11.82 s
INFO: scanned index "ticket_flights_amount_idx" to remove 4194262 row versions by parallel vacuum worker
DETAIL: CPU: user: 2.31 s, system: 0.44 s, elapsed: 12.95 s
INFO: scanned index "ticket_flights_pkey" to remove 4194262 row versions
...
INFO: "ticket_flights": found 4194262 removable, 8391852 nonremovable row versions in 104885 out of 104885 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 630
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 9.91 s, system: 4.40 s, elapsed: 121.40 s.
VACUUM
Pode-se ver que o processo principal lançou dois trabalhadores e obteve um índice.O número de processos de trabalho pode ser especificado explicitamente (em qualquer caso, é claro, não excederá max_parallel_maintenance_workers , que não excederá max_worker_processes ). Uma indicação explícita pode, em particular, ser usada para desativar a simultaneidade:demo=# VACUUM (PARALLEL 0, VERBOSE) ticket_flights;
Espero que este tópico seja mais desenvolvido. A tabela pode ser digitalizada em paralelo por vários processos (isso estava no patch Savada original, mas não incluído no final), e cada índice também poderia ser limpo em paralelo. Também é necessário ensinar a limpeza automática a usar paralelismo.P. S. , . . - , , .