Vedi e cancella cache / buffer di Postgres?


90

A volte eseguo una query Postgres che richiede 30 secondi. Quindi, eseguo immediatamente la stessa query e ci vogliono 2 secondi. Sembra che Postgres abbia una sorta di cache. Posso in qualche modo vedere cosa contiene quella cache? Posso forzare la cancellazione di tutte le cache per scopi di ottimizzazione?

Nota: fondamentalmente sto cercando una versione postgres del seguente comando di SQL Server:


DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS

Ma vorrei anche sapere come vedere cosa è effettivamente contenuto in quel buffer.

Grazie per qualsiasi aiuto.

Risposte:


60

Puoi vedere cosa c'è nella cache del buffer di PostgreSQL usando il modulo pg_buffercache. Ho fatto una presentazione chiamata " Inside the PostgreSQL Buffer Cache " che spiega quello che stai vedendo e mostro alcune query più complicate per aiutare a interpretare le informazioni che lo accompagnano.

È anche possibile guardare la cache del sistema operativo anche su alcuni sistemi, vedere [pg_osmem.py] per un esempio piuttosto approssimativo.

Non c'è modo per cancellare facilmente le cache. Su Linux è possibile arrestare il server del database e utilizzare la funzione drop_caches per cancellare la cache del sistema operativo; assicurati di prestare attenzione all'avviso per eseguire prima la sincronizzazione.


29
È possibile bypassare semplicemente la memorizzazione nella cache in una singola sessione? Spesso abbiamo bisogno di testare le prestazioni di query diverse e questa memorizzazione nella cache rende molto difficile valutare se un metodo è migliore di un altro (tranne quando si confrontano le prestazioni memorizzate nella cache!)
EvilPuppetMaster

7
Non è possibile ignorare o svuotare la cache del database. Tutto quello che puoi fare per cancellarlo è riavviare il server.
Greg Smith

2
È concepibile che ciò possa essere reso possibile, ad esempio nello sviluppo futuro? O è solo qualcosa che con i sistemi attuali (PG e Linux) non sarebbe possibile se si dovesse provare?
Kuberchaun

9
Quando si utilizza un'installazione PostgreSQL gestita come Amazon RDS, non si ha accesso al sistema operativo e lo svuotamento delle cache del sistema operativo a scopo di test può essere molto difficile, quindi questa funzionalità sarebbe molto vantaggiosa in PostgreSQL.
Samuli Pahaoja

4
Non riesco a riprodurre una query lenta è un problema, come posso essere sicuro che la mia query venga eseguita dopo un tuning? Il riavvio del server non è un'opzione Sto testando la query in prod perché solo prod ha concorrenza, blocchi e record sufficienti per riprodurre il problema
deFreitas

22

Non ho visto alcun comando per svuotare le cache in PostgreSQL. Quello che vedi è probabilmente solo un normale indice e cache di dati letti dal disco e conservati in memoria. sia da postgresql che dalle cache nel sistema operativo. Per sbarazzarmi di tutto questo, l'unico modo che conosco:

Quello che dovresti fare è:

  1. Spegnere il server di database (pg_ctl, sudo service postgresql stop, sudo systemctl stop postgresql, etc.)
  2. echo 3 > /proc/sys/vm/drop_caches Questo cancellerà le cache di file / blocchi del sistema operativo - molto importante anche se non so come farlo su altri sistemi operativi. (In caso di autorizzazione negata, prova sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"come in quella domanda )
  3. Avvia il server del database (ad es sudo service postgresql start. sudo systemctl start postgresql)

1
Ho pensato che sarebbe stato utile notare: se la directory dei dati di Postgres non è sullo stesso volume su cui è montato '/', potrebbe essere necessario smontare prima / dopo l'operazione sopra (non sono sicuro di quale, davvero). Inoltre (forse un po 'di vudù) prova a eseguire "sincronizzazione" prima e dopo questi passaggi.
tendone

18

La risposta di Greg Smith su drop_caches è stata molto utile. Ho ritenuto necessario interrompere e avviare il servizio postgresql, oltre a eliminare le cache. Ecco uno script di shell che fa il trucco. (Il mio 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

Ho provato con una query che ha impiegato 19 secondi la prima volta e meno di 2 secondi nei tentativi successivi. Dopo aver eseguito questo script, la query ha impiegato nuovamente 19 secondi.


15

Uso questo comando sulla mia macchina Linux:

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

Elimina completamente la cache.


2
Se la versione di Postgresql non è 9.0: sincronizzazione; sudo service postgresql stop; echo 1> / proc / sys / vm / drop_caches; sudo service postgresql start
rusllonrails

@rusllonrails Funzionerà solo se il servizio è denominato postgresql, il che potrebbe non essere il caso.
jpmc26

Penso che syncdovrebbe essere fatto dopo aver arrestato il server, immediatamente prima drop_caches, poiché Postgres può scrivere di nuovo qualcosa durante il processo di arresto.
greatvovan

8

Sì, postgresql ha sicuramente la cache. La dimensione è controllata dall'impostazione shared_buffers . Oltre a questo, come menzionato nella risposta precedente, c'è anche la cache dei file del sistema operativo che viene utilizzata.

Se vuoi vedere cosa c'è nella cache, c'è un modulo contrib chiamato pg_buffercache disponibile (in contrib / nell'albero dei sorgenti, nell'RPM contrib, o dovunque sia appropriato per come l'hai installato). Come usarlo è elencato nella documentazione PostgreSQL standard.

Non ci sono modi per svuotare la cache del buffer, oltre a riavviare il server. Puoi eliminare la cache del sistema operativo con il comando menzionato nell'altra risposta, a condizione che il tuo sistema operativo sia Linux.


7

Ho avuto questo errore.

psql: /cygdrive/e/test_insertion.sql: 9: ERRORE: il tipo di parametro 53 (t_stat_gardien) non corrisponde a quello durante la preparazione del piano (t_stat_avant)

Stavo cercando di svuotare il piano attuale e ho trovato questo:

SCARTARE PIANI

Avevo questo tra i miei inserti e risolve il mio problema.


2
Il piano di
eliminazione

1
La sintassi giusta è DISCARD PLANS;. E, come afferma la documentazione: "DISCARD rilascia risorse interne associate a una sessione di database ".
EAmez

6

Sì, è possibile cancellare sia la cache buffer Postgres condiviso E la cache del sistema operativo. La soluzione qui sotto è per Windows ... altri hanno già fornito la soluzione Linux.

Come molte persone hanno già detto, per cancellare i buffer condivisi puoi semplicemente riavviare Postgres (non è necessario riavviare il server). Ma solo facendo questo non si cancella la cache del sistema operativo.

Per svuotare la cache del sistema operativo utilizzata da Postgres, dopo aver interrotto il servizio, utilizzare l'eccellente RamMap ( https://technet.microsoft.com/en-us/sysinternals/rammap ), dall'eccellente Sysinternals Suite. Una volta eseguito RamMap, fai clic su "Svuota" -> "Elenco vuoto in standby" nel menu principale.

Riavvia Postgres e vedrai che ora la tua prossima query sarà damm lenta a causa dell'assenza di cache.

Puoi anche eseguire RamMap senza chiudere Postgres, e probabilmente avrai i risultati "no cache" che desideri, poiché come si è già detto, i buffer condivisi di solito danno poco impatto rispetto alla cache del sistema operativo. Ma per un test affidabile, preferirei interrompere postgres come tutti prima di svuotare la cache del sistema operativo per assicurarmene.

Nota: AFAIK, non consiglio di cancellare le altre cose oltre a "Standby list" quando si utilizza RamMap, perché gli altri dati vengono in qualche modo utilizzati e se lo fai potresti potenzialmente causare problemi / perdere dati. Ricorda che stai cancellando la memoria non solo utilizzata dai file postgres, ma anche da qualsiasi altra app e sistema operativo.

Saluti, Thiago L.


Sono contento che abbia aiutato;)
Thiago Linhares de Oliveira

5

questa è la mia scorciatoia

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;

5

C'è un pg_buffercachemodulo per esaminare la shared_bufferscache. E ad un certo punto ho dovuto eliminare la cache per eseguire alcuni test delle prestazioni sulla cache "fredda", quindi ho scritto un'estensione pg_dropcache che fa esattamente questo. Per favore controlla.


0

Se si dispone di un database di test dedicato, è possibile impostare il parametro: buffer condivisi su 16. Questo dovrebbe disabilitare la cache per tutte le query.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.