Voir et effacer les caches / tampons Postgres?

89

Parfois, j'exécute une requête Postgres, cela prend 30 secondes. Ensuite, j'exécute immédiatement la même requête et cela prend 2 secondes. Il semble que Postgres dispose d'une sorte de mise en cache. Puis-je voir d'une manière ou d'une autre ce que contient ce cache? Puis-je forcer tous les caches à être effacés à des fins de réglage?

Remarque: je recherche essentiellement une version postgres de la commande SQL Server suivante:


DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS

Mais j'aimerais aussi savoir comment voir ce qui est réellement contenu dans ce tampon.

Merci pour toute aide.

Utilisateur1
la source

Réponses:

59

Vous pouvez voir ce qu'il y a dans le cache du tampon PostgreSQL en utilisant le module pg_buffercache. J'ai fait une présentation intitulée « À l'intérieur du cache de tampon PostgreSQL » qui explique ce que vous voyez, et je montre quelques requêtes plus compliquées pour aider à interpréter ces informations qui vont avec.

Il est également possible de regarder le cache du système d'exploitation sur certains systèmes, voir [pg_osmem.py] pour un exemple un peu approximatif.

Il n'y a aucun moyen de vider facilement les caches. Sous Linux, vous pouvez arrêter le serveur de base de données et utiliser la fonction drop_caches pour vider le cache du système d'exploitation; assurez-vous de tenir compte de l'avertissement ici pour exécuter d'abord la synchronisation.

Greg Smith
la source
29
Est-il possible de contourner simplement la mise en cache en une seule session? Nous avons souvent besoin de tester les performances de différentes requêtes et cette mise en cache rend très difficile d'évaluer si une méthode est meilleure qu'une autre (sauf en comparant les performances en cache!)
EvilPuppetMaster
7
Il n'y a aucun moyen de contourner ou de vider le cache de la base de données. Tout ce que vous pouvez faire pour l'effacer est de redémarrer le serveur.
Greg Smith
2
Est-il concevable que cela puisse être rendu possible, par exemple dans le développement futur? Ou est-ce juste quelque chose qui avec les systèmes actuels (PG et Linux) ne serait pas possible si on essayait?
Kuberchaun
9
Lorsque vous utilisez une installation PostgreSQL gérée telle qu'Amazon RDS, vous n'avez pas accès au système d'exploitation, et vider les caches du système d'exploitation à des fins de test peut être très difficile, cette fonctionnalité serait donc très utile dans PostgreSQL.
Samuli Pahaoja
4
Impossible de reproduire une requête lente, c'est un problème, comment puis-je être sûr que ma requête fonctionne après un réglage? Redémarre le serveur n'est pas une option Je teste la requête dans prod car juste prod a la concurrence, les verrous et les enregistrements suffisants pour reproduire le problème
deFreitas
21

Je n'ai vu aucune commande pour vider les caches dans PostgreSQL. Ce que vous voyez est probablement juste des caches d'index et de données normaux lus à partir du disque et conservés en mémoire. par postgresql et par les caches dans le système d'exploitation. Pour me débarrasser de tout ça, le seul moyen que je connaisse:

Ce que vous devez faire est:

  1. Arrêtez le serveur de base de données (pg_ctl, sudo service postgresql stop, sudo systemctl stop postgresql, etc.)
  2. echo 3 > /proc/sys/vm/drop_caches Cela effacera les caches de fichiers / blocs du système d'exploitation - très important même si je ne sais pas comment faire cela sur d'autres systèmes d'exploitation. (En cas d'autorisation refusée, essayezsudo sh -c "echo 3 > /proc/sys/vm/drop_caches" comme dans cette question )
  3. Démarrez le serveur de base de données (par exemple sudo service postgresql start, sudo systemctl start postgresql)
Leeeroy
la source
1
J'ai pensé qu'il serait utile de noter: si le répertoire de données de Postgres n'est pas sur le même volume que '/' est monté, vous devrez peut-être démonter avant / après l'opération ci-dessus (pas sûr lequel, vraiment). De plus (peut-être un peu vaudou) essayez d'exécuter 'sync' avant et après ces étapes.
marqué
18

La réponse de Greg Smith à propos de drop_caches a été très utile. J'ai trouvé nécessaire d'arrêter et de démarrer le service postgresql, en plus de supprimer les caches. Voici un script shell qui fait l'affaire. (Mon environnement est Ubuntu 14.04 et PostgreSQL 9.3.)

#!/usr/bin/sudo bash

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

J'ai testé avec une requête qui a pris 19 secondes la première fois, et moins de 2 secondes sur les tentatives suivantes. Après avoir exécuté ce script, la requête a de nouveau pris 19 secondes.

Steve Saporta
la source
15

J'utilise cette commande sur ma machine Linux:

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

Il se débarrasse complètement du cache.

Mike Starov
la source
2
Si la version Postgresql n'est pas 9.0: sync; sudo service postgresql stop; echo 1> / proc / sys / vm / drop_caches; sudo service postgresql start
rusllonrails
@rusllonrails Cela ne fonctionnera que si le service est nommé postgresql, ce qui peut ne pas être le cas.
jpmc26
Je pense que cela syncdevrait être fait après l'arrêt du serveur, immédiatement avant drop_caches, car Postgres peut à nouveau écrire quelque chose pendant le processus d'arrêt.
greatvovan
8

Oui, postgresql a certainement une mise en cache. La taille est contrôlée par le paramètre shared_buffers . En dehors de cela, il existe, comme le mentionne la réponse précédente, le cache de fichiers du système d'exploitation qui est également utilisé.

Si vous voulez voir ce qu'il y a dans le cache, il y a un module contrib appelé pg_buffercache disponible (dans contrib / dans l'arborescence des sources, dans le RPM contrib, ou là où c'est approprié pour la façon dont vous l'avez installé). Son utilisation est répertoriée dans la documentation standard de PostgreSQL.

Il n'existe aucun moyen de vider le cache de la mémoire tampon, autre que de redémarrer le serveur. Vous pouvez supprimer le cache du système d'exploitation avec la commande mentionnée dans l'autre réponse - à condition que votre système d'exploitation soit Linux.

Magnus Hagander
la source
7

J'ai eu cette erreur.

psql: /cygdrive/e/test_insertion.sql: 9: ERREUR: le type de paramètre 53 (t_stat_gardien) ne correspond pas à celui lors de la préparation du plan (t_stat_avant)

Je cherchais à vider le plan actuel et j'ai trouvé ceci:

REJETER LES PLANS

J'avais ceci entre mes inserts et cela résout mon problème.

Luc M
la source
2
Le plan de suppression n'a pas été résolu pour moi, la requête semble encore mise en cache
deFreitas
1
La bonne syntaxe est DISCARD PLANS;. Et, comme l'indique la documentation: "DISCARD libère les ressources internes associées à une session de base de données ".
EAmez
6

Oui, il est possible d'effacer à la fois le cache postgres des tampons partagés ET le cache du système d'exploitation. La solution ci-dessous est pour Windows ... d'autres ont déjà donné la solution linux.

Comme beaucoup de gens l'ont déjà dit, pour vider les tampons partagés, vous pouvez simplement redémarrer Postgres (pas besoin de redémarrer le serveur). Mais cela ne videra pas le cache du système d'exploitation.

Pour effacer le cache du système d'exploitation utilisé par Postgres, après avoir arrêté le service, utilisez l'excellent RamMap ( https://technet.microsoft.com/en-us/sysinternals/rammap ), de l'excellent Sysinternals Suite. Une fois que vous avez exécuté RamMap, cliquez simplement sur "Vider" -> "Vider la liste d'attente" dans le menu principal.

Redémarrez Postgres et vous verrez maintenant que votre prochaine requête sera très lente en raison de l'absence de cache.

Vous pouvez également exécuter le RamMap sans fermer Postgres, et vous obtiendrez probablement les résultats "sans cache" que vous voulez, car comme les gens l'ont déjà dit, les tampons partagés ont généralement peu d'impact par rapport au cache du système d'exploitation. Mais pour un test fiable, je préfère arrêter les postgres comme tout avant de vider le cache du système d'exploitation pour m'en assurer.

Remarque: AFAIK, je ne recommande pas d'effacer les autres choses en plus de "Liste de veille" lorsque vous utilisez RamMap, car les autres données sont en quelque sorte utilisées, et vous pouvez potentiellement causer des problèmes / perdre des données si vous faites cela. N'oubliez pas que vous effacez la mémoire non seulement utilisée par les fichiers postgres, mais également par toute autre application et système d'exploitation.

Cordialement, Thiago L.

Thiago Linhares de Oliveira
la source
Heureux que cela ait aidé;)
Thiago Linhares de Oliveira
5

c'est mon raccourci

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
la source
5

Il existe un pg_buffercachemodule pour rechercher dans le shared_bufferscache. Et à un moment donné, j'ai dû supprimer le cache pour faire des tests de performance sur le cache «froid», j'ai donc écrit une extension pg_dropcache qui fait exactement cela. Vérifie s'il te plaît.

Ildar Musin
la source