PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 18 beta 2 » Annexes » Modules et extensions supplémentaires fournis » pg_buffercache -- inspecter l'état du cache disque de PostgreSQL

F.25. pg_buffercache -- inspecter l'état du cache disque de PostgreSQL #

Le module pg_buffercache fournit un moyen pour examiner ce qui se passe dans le cache partagé en temps réel. Il offre aussi une façon bas niveau de supprimer des données du cache, pour des tests.

Ce module fournit la fonction pg_buffercache_pages() (utilisée dans la vue pg_buffercache), la fonction pg_buffercache_numa_pages() function (intégrée dans la vue pg_buffercache_numa), la fonction pg_buffercache_summary(), la fonction pg_buffercache_usage_counts(), la fonction pg_buffercache_evict(), la fonction pg_buffercache_evict_relation() et la fonction pg_buffercache_evict_all().

La fonction pg_buffercache_pages() renvoie un ensemble d'enregistrements, chaque ligne décrivant l'état d'une entrée du cache disque. La vue pg_buffercache intègre la fonction pour une utilisation plus simple.

La fonction pg_buffercache_numa_pages() fournit les correspondances de nœuds NUMA pour les enregistrements du cache disque. Cette information ne fait pas partie de pg_buffercache_pages() elle-même, car elle est beaucoup plus longue à récupérer. La vue pg_buffercache_numa intègre la fonction pour une utilisation plus simple.

La fonction pg_buffercache_summary() renvoie une seule ligne résumant l'état du cache disque.

La fonction pg_buffercache_usage_counts() renvoie un ensemble d'enregistrements, chaque ligne décrivant le nombre de tampons pour un décompte d'utilisation donné.

Par défaut, l'utilisation des fonctions ci-dessus est restreinte aux superutilisateurs et aux rôles disposant des attributs du rôle pg_monitor. L'accès peut être accordé à d'autres rôle en utilisant GRANT.

La fonction pg_buffercache_evict() permet de supprimer un bloc du cache disque d'après son identifiant. L'utilisation de cette fonction est réservée aux superutilisateurs.

La fonction pg_buffercache_evict_relation() permet à tous les blocs non verrouillés en cache d'une relation d'être enlevés du cache. L'utilisation de cette fonction est restreinte aux superutilisateurs.

La fonction pg_buffercache_evict_all() permet à tous les blocs non verrouillés en cache d'être enlevés du cache. L'utilisation de cette fonction est restreinte aux superutilisateurs.

F.25.1. La vue pg_buffercache #

Voici la définition des colonnes exposées par la vue affichée dans Tableau F.14 :

Tableau F.14. Colonnes de pg_buffercache

Type de la colonne

Description

bufferid integer

ID, qui va de 1 à shared_buffers

relfilenode oid (references pg_class.relfilenode)

Numéro filenode de la relation

reltablespace oid (references pg_tablespace.oid)

OID du tablespace de la relation

reldatabase oid (references pg_database.oid)

OID de la base de données de la relation

relforknumber smallint

Numéro du fork dans la relation ; voir common/relpath.h

relblocknumber bigint

Numéro de page dans la relation

isdirty boolean

Page modifiée ?

usagecount smallint

Compteur d'accès clock-sweep

pinning_backends integer

Nombre de processus serveur en accès sur ce bloc


Il y a une ligne pour chaque tampon dans le cache partagé. Les tampons inutilisés sont affichés avec des champs NULL sauf pour bufferid. Les catalogues systèmes partagés sont affichés comme appartenant à la base de données zéro.

Comme le cache est partagé par toutes les bases de données, il y aura des pages de relations n'appartenant pas à la base de données courante. Cela signifie qu'il pourrait y avoir des lignes sans correspondance dans pg_class, ou qu'il pourrait y avoir des jointures incorrectes. Si vous essayez une jointure avec pg_class, une bonne idée est de restreindre la jointure aux lignes ayant un reldatabase égal à l'OID de la base de données actuelle ou à zéro.

Comme des verrous du gestionnaire de tampons ne sont pas acquis pour copier les données d'état du tampon que la vue affichera, accéder à la vue pg_buffercache a moins d'impact sur l'activité normale du tampon, mais il ne fournit pas un ensemble cohérent de résultats sur tous les tampons. Néanmoins, nous nous assurons que l'information de chaque tampon est cohérente avec lui-même.

F.25.2. Vue pg_buffercache_numa #

La définition des colonnes exposées par la vue est affichée dans Tableau F.15.

Tableau F.15. Colonnes pg_buffercache_numa

Type de données

Description

bufferid integer

ID, dans l'intervalle 1..shared_buffers

os_page_num bigint

Nombre de blocs mémoire de l'OS pour ce tampon

numa_node int

ID du nœud NUMA


Comme la recherche de chaque bloc à partir d'un identifiant de nœud NUMA requiert que les pages mémoires soient lues, la première exécution de cette fonction peut prendre beaucoup de temps. Dans tous les cas (première exécution ou pas), récupérer cette information est coûteux et requêter la vue à une grande fréquence n'est pas recommandé.

Avertissement

Lors de la détermination du nœud NUMA, la vue touche tous les blocs mémoire du segment de mémoire partagée. Ceci forcera l'allocation de la mémoire partagée, si elle n'est pas déjà allouée, et la mémoire pourrait être allouée sur un seul nœud NUMA (suivant la configuration du système).

F.25.3. Fonction pg_buffercache_summary() #

Les définitions des colonnes exposées par la fonction sont affichées dans Tableau F.16.

Tableau F.16. Colonnes en sortie de pg_buffercache_summary()

Type de colonne

Description

buffers_used int4

Nombre de tampons utilisés

buffers_unused int4

Nombre de tampons inutilisés

buffers_dirty int4

Nombres de tampons modifiés

buffers_pinned int4

Nombre de tampons verrouillés

usagecount_avg float8

Décompte moyen d'utilisation des tampons


La fonction pg_buffercache_summary() renvoie une seule ligne résumant l'état de tous les tampons partagés. Une information similaire bien que plus détaillée est fournie par la vue pg_buffercache mais pg_buffercache_summary() est plus performante.

Tout comme la vue pg_buffercache, pg_buffercache_summary() n'acquiert pas de verrous dans le gestionnaire de tampons. Donc une activité concurrente peut amener des inexactitudes mineuses dans le résultat.

F.25.4. Fonction pg_buffercache_usage_counts() #

Les définitions des colonnes exposées par la fonction sont affichées dans Tableau F.17.

Tableau F.17. Colonnes en sortie de pg_buffercache_usage_counts()

Type de colonne

Description

usage_count int4

Décompte d'utilisation des tampons

buffers int4

Nombre de tampons pour ce décompte

dirty int4

Nombre de tampons modifiés pour ce décompte

pinned int4

Nombre de tampons verrouillés pour ce décompte


La fonction pg_buffercache_usage_counts() renvoie un ensemble de lignes résumant les états des tampons partagés, agrégés sur les valeurs possibles du décompte. Une information similaire mais plus détaillée est fournie par la vue pg_buffercache mais la fonction pg_buffercache_usage_counts() est plus performante.

Tout comme la vue pg_buffercache, la fonction pg_buffercache_usage_counts() n'acquiert pas de verrous par le gestionnaire de tampons. De ce fait, l'activité concurrente peut amener à des inexactitudes mineures dans le résultat.

F.25.5. Fonction pg_buffercache_evict #

La fonction pg_buffercache_evict() prend en entrée un identifiant de buffer, comme indiqué par la colonne bufferid de la vue pg_buffercache. Elle renvoie des informations sur le bloc qui a été enlevé du cache et stocké sur disque. La colonne buffer_evicted vaut true en cas de succès, et false si le bloc n'était pas valide, s'il ne pouvait pas être enlevé parce qu'il était verrouillé, ou s'il est de nouveau modifié après une tentative pour l'écrire. La colonne buffer_flushed vaut true si le bloc a été vidé sur disque. Ceci ne signifie pas nécessairement que le bloc a été vidé par nous, il peut avoir été vidé par quelqu'un d'autre. Le résultat est immédiatement obsolète car le bloc pourrait être de nouveau valide à tout moment avec une activité concurrente. La fonction est principalement destinée aux développeurs pour des tests.

F.25.6. Fonction pg_buffercache_evict_relation #

La fonction pg_buffercache_evict_relation() est très similaire à la fonction pg_buffercache_evict(). La différence est que pg_buffercache_evict_relation() prend un identifiant de relation à la place d'un identifiant de bloc. Elle essaie de vider tous les blocs de tous les fichiers de cette relation. Elle renvoie le nombre de blocs vidés, de blocs écrits sur disque et le nombre de blocs qui n'ont pas pu être vidés. Les blocs vidés n'ont pas forcément été vidés par nous, ils peuvent l'avoir été par quelqu'un d'autre. Le résultat est immédiatement obsolète car les blocs pourraient avoir été lus de nouveau avec une activité concurrente. La fonction est destinée aux développeurs pour des tests.

F.25.7. Fonction pg_buffercache_evict_all #

La fonction pg_buffercache_evict_all() est très similaire à la fonction pg_buffercache_evict(). La différence est que la fonction pg_buffercache_evict_all() ne prend pas d'arguments ; à la place, elle essaie de vider tous les blocs du cache. Elle renvoie le nombre de blocs vidés, de blocs enregistrés sur disque et le nombre de blocs qui n'ont pas pu être vidés. Les blocs vidés n'ont pas été forcément vidés par nous, ils peuvent l'avoir été par d'autre personne. Le résultat est immédiatement obsolète, car les blocs pourraient avoir été lus de nouveau avec l'activité concurrente. La fonction est destinée aux développeurs pour des tests.

F.25.8. Affichage en sortie #

  regression=# SELECT n.nspname, c.relname, count(*) AS buffers
               FROM pg_buffercache b JOIN pg_class c
               ON b.relfilenode = pg_relation_filenode(c.oid) AND
                  b.reldatabase IN (0, (SELECT oid FROM pg_database
                                        WHERE datname = current_database()))
               JOIN pg_namespace n ON n.oid = c.relnamespace
               GROUP BY n.nspname, c.relname
               ORDER BY 3 DESC
               LIMIT 10;

  nspname   |        relname         | buffers
------------+------------------------+---------
 public     | delete_test_table      |     593
 public     | delete_test_table_pkey |     494
 pg_catalog | pg_attribute           |     472
 public     | quad_poly_tbl          |     353
 public     | tenk2                  |     349
 public     | tenk1                  |     349
 public     | gin_test_idx           |     306
 pg_catalog | pg_largeobject         |     206
 public     | gin_test_tbl           |     188
 public     | spgist_text_tbl        |     182
  (10 rows)

regression=# SELECT * FROM pg_buffercache_summary();
 buffers_used | buffers_unused | buffers_dirty | buffers_pinned | usagecount_avg
--------------+----------------+---------------+----------------+----------------
          248 |        2096904 |            39 |              0 |       3.141129
(1 row)


regression=# SELECT * FROM pg_buffercache_usage_counts();
 usage_count | buffers | dirty | pinned
-------------+---------+-------+--------
           0 |   14650 |     0 |      0
           1 |    1436 |   671 |      0
           2 |     102 |    88 |      0
           3 |      23 |    21 |      0
           4 |       9 |     7 |      0
           5 |     164 |   106 |      0
(6 rows)
  

F.25.9. Auteurs #

Mark Kirkwood

Suggestions de conception : Neil Conway

Conseils pour le débogage : Tom Lane