Estou usando AWS Aurora PostgreSQL Serverless
com escalonamento automático. Parece que o dimensionamento limpa o buffer compartilhado, então, quando queremos aumentar o desempenho, somos forçados a enfrentar um gargalo de E/S. Após o aquecimento, vemos uma grande melhora no desempenho. No entanto, se executarmos consecutivamente uma vez dimensionados, a segunda execução será muito mais rápida. Embora eu não tenha visto nada específico sobre se o buffer compartilhado é limpo no dimensionamento, tenho quase certeza de que é.
O Aurora Serverless está usando atualmente PostgreSQL 10.14
e oferece suporte à pg_prewarm
extensão. Parece que a documentação mais recente sugere que o pré-aquecimento suporta o pré-aquecimento automático após a reinicialização do servidor, mas isso é sem servidor e uma versão que não parece mencionar o pré-aquecimento automático na documentação .
Encontrei este post que funciona muito bem para o PostgreSQL ao reiniciar o servidor ou se recuperar de uma falha.
- Se pudéssemos pelo menos reter o conteúdo do buffer compartilhado do nó ACU inferior após o dimensionamento, tudo bem.
- Se pudéssemos pré-aquecer exatamente o que precisa estar na memória antes do tempo, seria incrível!
- Existem certas mesas que são bastante grandes e gostaríamos de pré-aquecer seletivamente as peças que queremos.
pg_prewarm
suportafirst_block
elast_block
bloqueia números para uma tabela/índice, mas como saber quais valores colocar lá?
Sabemos com antecedência quando é nosso pico e dizemos ao RDS para dimensionar logo antes, então temos uma janela de tempo em que podemos nos preparar.
Quais são minhas opções?
Minha resposta não é específica para AWS Aurora PostgreSQL Serverless, mas para Postgres em geral.
Alternativa simples
Em seu comentário relacionado, você sugeriu que só precisa de linhas das últimas 24 horas. Então você poderia (sem envolver pg_prewarm) simplesmente:
Se
created_at
estiver indexado e o predicado for seletivo o suficiente, os blocos relevantes de tabela e índice serão pré-aquecidos.Como você realmente não deseja recuperar nenhum dado durante o pré-aquecimento, você pode usar
PERFORM
em umaDO
instrução:Mesmo efeito.
Você pode verificar o sucesso com
EXPLAIN (ANALYZE, BUFFERS)
:Se houver memória cache suficiente disponível, agora você verá apenas buffers de "acertos compartilhados". Curti:
Buffers: shared hit=123456
.. onde você veria principalmente "ler" com principalmente cache frio. Curti:
Buffers: shared hit=143 read=153689
Basicamente, basta executar as consultas esperadas e o cache será preenchido de acordo.
pg_prewarm()
Se você ainda quiser usar
pg_prewarm()
com números de bloco, também poderá fazer isso. Permite mais opções, como escolher qual cache preencher (sistema operacional ou cache de buffer de banco de dados) ou alguma outra sutileza. O módulo adicional deve ser instalado primeiro, uma vez por banco de dados:Trabalhar com números de bloco só faz sentido se sua tabela estiver (principalmente) fisicamente agrupada na coluna assumida
created_at
. Esse seria o caso de uma tabela somente leitura (principalmente leitura) em que novas linhas com o carimbo de data/hora atual são anexadas ao final da tabela.Você pode obter o número do bloco de uma linha de seu arquivo
ctid
. Ver:Para obter o número do bloco da primeira linha com menos de 24 horas:
Você consegue algo como
(5759,1)
.5759
é o número do bloco. Então você pode:Como deixamos
last_block
o padrãoNULL
, tudo "através do último bloco da relação" será pré-aquecido. (Não o índice, no entanto. Você pode pré-aquecer isso também.)A chamada da função é feita com "notação mista" (mistura de "notação posicional" e "notação nomeada"). Ver:
Eu acho que você está sem sorte em #1. As notas de lançamento do PG 11 observam a adição desse recurso. E eu não estou familiarizado com Aurora, não tenho nenhuma idéia sobre o número 2.
Para o número 3, tudo depende de quais são as "peças que queremos". Nos comentários da postagem vinculada, você menciona que, para uma tabela, deseja as últimas 24 horas de dados. Se esta for uma tabela somente de acréscimo, a maneira de obter o número do bloco seria consultar o
ctid
de uma linha com 24 horas de idade e, em seguida, usar(ctid::text::point)[0]::bigint
para obter o número do bloco inicial - supondo que você tenha um índice no carimbo de data / hora. Em seguida, basta pré-buscar desse bloco parapg_relation_size('schema.table')/current_setting('block_size')
.Se não for uma tabela somente de acréscimo, se você pode pré-buscar apenas as partes que deseja depende inteiramente dos detalhes; sinta-se à vontade para atualizar a pergunta em caso afirmativo.