Ver e limpar caches / buffers do Postgres?

90

Às vezes, executo uma consulta do Postgres que leva 30 segundos. Então, eu executo imediatamente a mesma consulta e leva 2 segundos. Parece que o Postgres tem algum tipo de cache. Posso ver de alguma forma o que esse cache está segurando? Posso forçar a limpeza de todos os caches para fins de ajuste?

Nota: Basicamente, estou procurando uma versão postgres do seguinte comando do SQL Server:


DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS

Mas também gostaria de saber o que realmente está contido nesse buffer.

Obrigado por qualquer ajuda.

Usuário1
fonte

Respostas:

60

Você pode ver o que está no cache de buffer do PostgreSQL usando o módulo pg_buffercache. Fiz uma apresentação chamada "Por dentro do cache de buffer do PostgreSQL " que explica o que você está vendo e mostro algumas consultas mais complicadas para ajudar a interpretar as informações que vêm junto com isso.

Também é possível examinar o cache do sistema operacional em alguns sistemas, consulte [pg_osmem.py] para um exemplo um pouco grosso.

Não há como limpar os caches facilmente. No Linux, você pode parar o servidor de banco de dados e usar o recurso drop_caches para limpar o cache do SO; certifique-se de seguir o aviso lá para executar a sincronização primeiro.

Greg Smith
fonte
29
É possível simplesmente ignorar o armazenamento em cache em uma única sessão? Freqüentemente, precisamos testar o desempenho de consultas diferentes e esse armazenamento em cache torna muito difícil avaliar se um método é melhor do que outro (exceto ao comparar o desempenho em cache!)
EvilPuppetMaster
7
Não há como ignorar ou limpar o cache do banco de dados. Tudo o que você pode fazer para limpá-lo é reiniciar o servidor.
Greg Smith
2
É concebível que isso seja possível, por exemplo, no desenvolvimento futuro? Ou isso é apenas algo que com os sistemas atuais (PG e Linux) não será possível se tentarmos?
Kuberchaun
9
Ao usar uma instalação gerenciada de PostgreSQL, como Amazon RDS, não se tem acesso ao sistema operacional, e esvaziar os caches do sistema operacional para fins de teste pode ser muito difícil, portanto, esse recurso seria muito benéfico no PostgreSQL.
Samuli Pahaoja
4
Não consigo reproduzir uma consulta lenta, é um problema, como posso ter certeza de que minha consulta está funcionando após um ajuste? Reiniciar o servidor não é uma opção Estou testando a consulta no prod porque apenas o prod tem simultaneidade, bloqueios e registros suficientes para reproduzir o problema
deFreitas
22

Não vi nenhum comando para liberar os caches no PostgreSQL. O que você vê provavelmente é apenas um índice normal e caches de dados sendo lidos do disco e mantidos na memória. pelo postgresql e pelos caches no sistema operacional. Para me livrar de tudo isso, da única maneira que conheço:

O que você deve fazer é:

  1. Desligar o servidor de banco de dados (pg_ctl, sudo service postgresql stop, sudo systemctl stop postgresql, etc.)
  2. echo 3 > /proc/sys/vm/drop_caches Isso limpará os caches de arquivo / bloqueio do SO - muito importante, embora eu não saiba como fazer isso em outros SOs. (Em caso de permissão negada, tente sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"como na pergunta )
  3. Inicie o servidor de banco de dados (por exemplo sudo service postgresql start, sudo systemctl start postgresql)
Leeeroy
fonte
1
Achei que seria útil notar: se o diretório de dados do Postgres não estiver no mesmo volume em que '/' está montado, você pode precisar desmontar antes / depois da operação acima (não tenho certeza qual, realmente). Além disso (talvez um pouco de vodu), tente executar 'sync' antes e depois dessas etapas.
marcado em
18

A resposta de Greg Smith sobre drop_caches foi muito útil. Achei necessário parar e iniciar o serviço postgresql, além de descartar os caches. Aqui está um script de shell que faz o truque. (Meu ambiente é Ubuntu 14.04 e PostgreSQL 9.3.)

#!/usr/bin/sudo bash

service postgresql stop
sync
echo 3 > /proc/sys/vm/drop_caches
service postgresql start

Testei com uma consulta que levou 19 segundos na primeira vez e menos de 2 segundos nas tentativas subsequentes. Depois de executar esse script, a consulta mais uma vez levou 19 segundos.

Steve Saporta
fonte
15

Eu uso este comando na minha máquina Linux:

sync; /etc/init.d/postgresql-9.0 stop; echo 1 > /proc/sys/vm/drop_caches; /etc/init.d/postgresql-9.0 start

Ele elimina completamente o cache.

Mike Starov
fonte
2
Se a versão do Postgresql não for 9.0: sincronizar; sudo service postgresql stop; echo 1> / proc / sys / vm / drop_caches; sudo service postgresql start
rusllonrails
@rusllonrails Isso só funcionará se o serviço for nomeado postgresql, o que pode não ser o caso.
jpmc26 de
Eu acho que syncdeve ser feito depois de parar o servidor, imediatamente antes drop_caches, pois o Postgres pode escrever algo durante o processo de parada novamente.
greatvovan
8

Sim, o postgresql certamente tem cache. O tamanho é controlado pela configuração shared_buffers . Fora isso, existe como a resposta anterior menciona, o cache de arquivos do sistema operacional que também é usado.

Se você quiser ver o que está no cache, existe um módulo contrib chamado pg_buffercache disponível (em contrib / na árvore de código-fonte, no RPM contrib ou onde for apropriado para como você o instalou). Como usá-lo está listado na documentação padrão do PostgreSQL.

Não há maneiras de limpar o cache do buffer, a não ser reiniciar o servidor. Você pode descartar o cache do sistema operacional com o comando mencionado na outra resposta - desde que seu sistema operacional seja Linux.

Magnus Hagander
fonte
7

Eu tive esse erro.

psql: /cygdrive/e/test_insertion.sql: 9: ERROR: o tipo de parâmetro 53 (t_stat_gardien) não corresponde a isso ao preparar o plano (t_stat_avant)

Eu estava procurando esvaziar o plano atual e encontrei isto:

PLANOS DE DESCARTE

Tive isso entre minhas inserções e resolve meu problema.

Luc M
fonte
2
O plano de descarte não corrigiu para mim, a consulta parece estar em cache ainda
deFreitas
1
A sintaxe certa é DISCARD PLANS;. E, como afirma a documentação: "DISCARD libera recursos internos associados a uma sessão de banco de dados ".
EAmez
6

Sim, é possível limpar o cache postgres de buffers compartilhados E o cache do sistema operacional. A solução abaixo é para Windows ... outros já deram a solução para Linux.

Como muitas pessoas já disseram, para limpar os buffers compartilhados basta reiniciar o Postgres (não é necessário reiniciar o servidor). Mas apenas fazer isso não limpará o cache do sistema operacional.

Para limpar o cache do sistema operacional usado pelo Postgres, após interromper o serviço, use o excelente RamMap ( https://technet.microsoft.com/en-us/sysinternals/rammap ), do excelente Sysinternals Suite. Depois de executar o RamMap, clique em "Esvaziar" -> "Lista de espera vazia" no menu principal.

Reinicie o Postgres e você verá agora que sua próxima consulta será muito lenta devido à falta de cache.

Você também pode executar o RamMap sem fechar o Postgres, e provavelmente terá os resultados "sem cache" que deseja, visto que, como as pessoas já disseram, os buffers compartilhados geralmente dão pouco impacto em comparação com o cache do sistema operacional. Mas, para um teste confiável, prefiro parar o postgres antes de limpar o cache do sistema operacional para ter certeza.

Nota: AFAIK, não recomendo limpar as outras coisas além da "Lista de espera" ao usar o RamMap, porque os outros dados estão de alguma forma sendo usados ​​e você pode causar problemas / dados perdidos se fizer isso. Lembre-se de que você está limpando a memória usada não apenas pelos arquivos do postgres, mas também por qualquer outro aplicativo e sistema operacional.

Atenciosamente, Thiago L.

Thiago Linhares de Oliveira
fonte
Ainda bem que ajudou;)
Thiago Linhares de Oliveira
5

este é o meu atalho

echo 1 > /proc/sys/vm/drop_caches; echo 2 > /proc/sys/vm/drop_caches; echo 3 > /proc/sys/vm/drop_caches; rcpostgresql stop; rcpostgresql start;
wutzebaer
fonte
5

Existe um pg_buffercachemódulo para examinar o shared_bufferscache. E em algum ponto eu precisei descartar o cache para fazer alguns testes de desempenho no cache 'frio', então escrevi uma extensão pg_dropcache que faz exatamente isso. Por favor, confira.

Ildar Musin
fonte
0

Se você tiver um banco de dados de teste dedicado, pode definir o parâmetro: buffers compartilhados para 16. Isso deve desabilitar o cache para todas as consultas.

Charlie Chen
fonte