F.25. pg_buffercache — inspeccionar el estado de la caché de búfer de PostgreSQL #

F.25.1. La vista pg_buffercache
F.25.2. La vista pg_buffercache_numa
F.25.3. La función pg_buffercache_summary()
F.25.4. La función pg_buffercache_usage_counts()
F.25.5. La función pg_buffercache_evict()
F.25.6. La función pg_buffercache_evict_relation()
F.25.7. La función pg_buffercache_evict_all()
F.25.8. Ejemplo de salida
F.25.9. Autores

El módulo pg_buffercache proporciona un medio para examinar lo que está sucediendo en la caché de búfer compartido (shared buffer cache) en tiempo real. También ofrece una forma de bajo nivel para desalojar (evict) datos de ella, con fines de prueba.

Este módulo proporciona la función pg_buffercache_pages() (envuelta en la vista pg_buffercache), la función pg_buffercache_numa_pages() (envuelta en la vista pg_buffercache_numa), la función pg_buffercache_summary(), la función pg_buffercache_usage_counts(), la función pg_buffercache_evict(), la función pg_buffercache_evict_relation() y la función pg_buffercache_evict_all().

La función pg_buffercache_pages() devuelve un conjunto de registros, donde cada fila describe el estado de una entrada del búfer compartido. La vista pg_buffercache envuelve la función para facilitar su uso.

La función pg_buffercache_numa_pages() proporciona asociaciones de nodos NUMA para las entradas del búfer compartido. Esta información no forma parte de pg_buffercache_pages() en sí misma, ya que es mucho más lenta de recuperar. La vista pg_buffercache_numa envuelve la función para facilitar su uso.

La función pg_buffercache_summary() devuelve una única fila que resume el estado de la caché de búfer compartido.

La función pg_buffercache_usage_counts() devuelve un conjunto de registros, donde cada fila describe el número de búferes con un recuento de uso dado.

Por defecto, el uso de las funciones anteriores está restringido a superusuarios y roles con privilegios del rol pg_monitor. Se puede otorgar acceso a otros mediante el uso de GRANT.

La función pg_buffercache_evict() permite desalojar un bloque del grupo de búferes (buffer pool) proporcionando un identificador de búfer. El uso de esta función está restringido únicamente a los superusuarios.

La función pg_buffercache_evict_relation() permite desalojar del grupo de búferes todos los búferes compartidos no anclados (unpinned) en la relación, proporcionando un identificador de relación. El uso de esta función está restringido únicamente a los superusuarios.

La función pg_buffercache_evict_all() permite desalojar todos los búferes compartidos no anclados en el grupo de búferes. El uso de esta función está restringido únicamente a los superusuarios.

F.25.1. La vista pg_buffercache #

Las definiciones de las columnas expuestas por la vista se muestran en la Table F.14.

Table F.14. Columnas de pg_buffercache

Columna Tipo

Descripción

bufferid integer

ID, en el rango 1..shared_buffers

relfilenode oid (hace referencia a pg_class.relfilenode)

Número de nodo de archivo (filenode) de la relación

reltablespace oid (hace referencia a pg_tablespace.oid)

OID del tablespace de la relación

reldatabase oid (hace referencia a pg_database.oid)

OID de la base de datos de la relación

relforknumber smallint

Número de bifurcación (fork number) dentro de la relación; ver common/relpath.h

relblocknumber bigint

Número de página dentro de la relación

isdirty boolean

¿Está sucia (dirty) la página?

usagecount smallint

Recuento de accesos del algoritmo clock-sweep

pinning_backends integer

Número de backends que tienen anclado (pinning) este búfer


Hay una fila para cada búfer en la caché compartida. Los búferes no utilizados se muestran con todos los campos nulos excepto bufferid. Los catálogos compartidos del sistema se muestran como pertenecientes a la base de datos cero.

Debido a que la caché es compartida por todas las bases de datos, normalmente habrá páginas de relaciones que no pertenecen a la base de datos actual. Esto significa que puede que no haya filas de unión coincidentes en pg_class para algunas filas, o incluso que se produzcan uniones incorrectas. Si estás intentando realizar una unión con pg_class, es una buena idea restringir la unión a las filas que tengan reldatabase igual al OID de la base de datos actual o a cero.

Dado que no se adquieren bloqueos del gestor de búfer para copiar los datos de estado del búfer que mostrará la vista, el acceso a la vista pg_buffercache tiene un menor impacto en la actividad normal del búfer, pero no proporciona un conjunto de resultados coherente para todos los búferes. Sin embargo, nos aseguramos de que la información de cada búfer sea coherente consigo misma.

F.25.2. La vista pg_buffercache_numa #

Las definiciones de las columnas expuestas por la vista se muestran en la Table F.15.

Table F.15. Columnas de pg_buffercache_numa

Columna Tipo

Descripción

bufferid integer

ID, en el rango 1..shared_buffers

os_page_num bigint

Número de página de memoria del sistema operativo para este búfer

numa_node int

ID del nodo NUMA


Dado que la consulta del ID del nodo NUMA para cada página requiere que las páginas de memoria estén cargadas en la memoria física (paged-in), la primera ejecución de esta función puede tomar un tiempo perceptible. En todos los casos (sea la primera ejecución o no), recuperar esta información es costoso y no se recomienda consultar la vista con una frecuencia alta.

Warning

Al determinar el nodo NUMA, la vista toca todas las páginas de memoria del segmento de memoria compartida. Esto forzará la asignación de la memoria compartida, si no estaba ya asignada, y la memoria podría asignarse en un único nodo NUMA (dependiendo de la configuración del sistema).

F.25.3. La función pg_buffercache_summary() #

Las definiciones de las columnas expuestas por la función se muestran en la Table F.16.

Table F.16. Columnas de salida de pg_buffercache_summary()

Columna Tipo

Descripción

buffers_used int4

Número de búferes compartidos utilizados

buffers_unused int4

Número de búferes compartidos no utilizados

buffers_dirty int4

Número de búferes compartidos sucios (dirty)

buffers_pinned int4

Número de búferes compartidos anclados (pinned)

usagecount_avg float8

Recuento medio de uso de los búferes compartidos utilizados


La función pg_buffercache_summary() devuelve una única fila que resume el estado de todos los búferes compartidos. La vista pg_buffercache proporciona información similar y más detallada, pero pg_buffercache_summary() es significativamente más barata.

Al igual que la vista pg_buffercache, pg_buffercache_summary() no adquiere bloqueos del gestor de búfer. Por lo tanto, la actividad concurrente puede provocar pequeñas imprecisiones en el resultado.

F.25.4. La función pg_buffercache_usage_counts() #

Las definiciones de las columnas expuestas por la función se muestran en la Table F.17.

Table F.17. Columnas de salida de pg_buffercache_usage_counts()

Columna Tipo

Descripción

usage_count int4

Un valor posible del recuento de uso del búfer

buffers int4

Número de búferes con el recuento de uso indicado

dirty int4

Número de búferes sucios con el recuento de uso indicado

pinned int4

Número de búferes anclados con el recuento de uso indicado


La función pg_buffercache_usage_counts() devuelve un conjunto de filas que resumen los estados de todos los búferes compartidos, agregados por los posibles valores de recuento de uso. La vista pg_buffercache proporciona información similar y más detallada, pero pg_buffercache_usage_counts() es significativamente más barata.

Al igual que la vista pg_buffercache, pg_buffercache_usage_counts() no adquiere bloqueos del gestor de búfer. Por lo tanto, la actividad concurrente puede provocar pequeñas imprecisiones en el resultado.

F.25.5. La función pg_buffercache_evict() #

La función pg_buffercache_evict() recibe un identificador de búfer, como se muestra en la columna bufferid de la vista pg_buffercache. Devuelve información sobre si el búfer fue desalojado y vaciado (flushed). La columna buffer_evicted es verdadera en caso de éxito, y falsa si el búfer no era válido, si no se pudo desalojar porque estaba anclado o si se volvió a ensuciar (dirty) después de intentar escribirlo. La columna buffer_flushed es verdadera si el búfer fue vaciado. Esto no significa necesariamente que el búfer haya sido vaciado por nosotros; podría haber sido vaciado por otro proceso. El resultado queda desactualizado inmediatamente después de ser devuelto, ya que el búfer podría volver a ser válido en cualquier momento debido a la actividad concurrente. La función está pensada únicamente para pruebas de desarrollo.

F.25.6. La función pg_buffercache_evict_relation() #

La función pg_buffercache_evict_relation() es muy similar a la función pg_buffercache_evict(). La diferencia es que la función pg_buffercache_evict_relation() recibe un identificador de relación en lugar de un identificador de búfer. Intenta desalojar todos los búferes para todas las bifurcaciones (forks) en esa relación. Devuelve el número de búferes desalojados, los búferes vaciados y el número de búferes que no pudieron ser desalojados. Los búferes vaciados no necesariamente han sido vaciados por nosotros; podrían haber sido vaciados por otro proceso. El resultado queda desactualizado inmediatamente después de ser devuelto, ya que los búferes podrían volver a leerse inmediatamente debido a la actividad concurrente. La función está pensada únicamente para pruebas de desarrollo.

F.25.7. La función pg_buffercache_evict_all() #

La función pg_buffercache_evict_all() es muy similar a la función pg_buffercache_evict(). La diferencia es que la función pg_buffercache_evict_all() no recibe ningún argumento; en su lugar, intenta desalojar todos los búferes en el grupo de búferes. Devuelve el número de búferes desalojados, los búferes vaciados y el número de búferes que no pudieron ser desalojados. Los búferes vaciados no han sido necesariamente vaciados por nosotros; podrían haber sido vaciados por otro proceso. El resultado queda desactualizado inmediatamente después de ser devuelto, ya que los búferes podrían volver a leerse inmediatamente debido a la actividad concurrente. La función está pensada únicamente para pruebas de desarrollo.

F.25.8. Ejemplo de salida #

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. Autores #

Mark Kirkwood

Sugerencias de diseño: Neil Conway

Consejos de depuración: Tom Lane