¿Ver y borrar cachés / búferes de Postgres?

89

A veces ejecuto una consulta de Postgres, tarda 30 segundos. Luego, inmediatamente ejecuto la misma consulta y toma 2 segundos. Parece que Postgres tiene algún tipo de almacenamiento en caché. ¿Puedo de alguna manera ver qué contiene ese caché? ¿Puedo forzar que se borren todos los cachés con fines de ajuste?

Nota: Básicamente estoy buscando una versión de postgres del siguiente comando de SQL Server:


DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS

Pero también me gustaría saber cómo ver qué contiene realmente ese búfer.

Gracias por cualquier ayuda.

Usuario1
fuente

Respuestas:

59

Puede ver lo que hay en la memoria caché del búfer de PostgreSQL utilizando el módulo pg_buffercache. Hice una presentación llamada " Dentro de la caché de búfer de PostgreSQL " que explica lo que está viendo y muestro algunas consultas más complicadas para ayudar a interpretar la información que acompaña a eso.

También es posible mirar el caché del sistema operativo en algunos sistemas, consulte [pg_osmem.py] para ver un ejemplo un tanto aproximado.

No hay forma de borrar los cachés fácilmente. En Linux, puede detener el servidor de la base de datos y utilizar la función drop_caches para borrar el caché del sistema operativo; asegúrese de prestar atención a la advertencia para ejecutar la sincronización primero.

Greg Smith
fuente
29
¿Es posible simplemente omitir el almacenamiento en caché en una sola sesión? A menudo necesitamos probar el rendimiento de diferentes consultas y este almacenamiento en caché hace que sea muy difícil evaluar si un método es mejor que otro (¡excepto cuando se compara el rendimiento en caché!)
EvilPuppetMaster
7
No hay forma de omitir o vaciar el caché de la base de datos. Todo lo que puede hacer para borrarlo es reiniciar el servidor.
Greg Smith
2
¿Es concebible que esto pueda hacerse posible, por ejemplo, en el desarrollo futuro? ¿O es esto simplemente algo que con los sistemas actuales (PG y Linux) no sería posible si se intentara?
Kuberchaun
9
Cuando se utiliza una instalación administrada de PostgreSQL como Amazon RDS, uno no tiene acceso al sistema operativo y vaciar las cachés del sistema operativo con fines de prueba puede ser muy difícil, por lo que esta característica sería muy beneficiosa en PostgreSQL.
Samuli Pahaoja
4
No puedo reproducir una consulta lenta, es un problema, ¿cómo puedo estar seguro de que mi consulta funciona después de un ajuste? Reiniciar el servidor no es una opción.Estoy probando la consulta en prod porque solo prod tiene concurrencia, bloqueos y registros suficientes para reproducir el problema
deFreitas
21

No he visto ningún comando para vaciar los cachés en PostgreSQL. Lo que ve es probablemente solo índices normales y cachés de datos que se leen desde el disco y se mantienen en la memoria. tanto por postgresql como por las cachés del sistema operativo. Para deshacerme de todo eso, la única forma que conozco:

Lo que debes hacer es:

  1. Apagar el servidor de base de datos (pg_ctl, sudo service postgresql stop, sudo systemctl stop postgresql, etc.)
  2. echo 3 > /proc/sys/vm/drop_caches Esto borrará los cachés de archivos / bloques del sistema operativo, muy importante, aunque no sé cómo hacerlo en otros sistemas operativos. (En caso de denegación del permiso, intente sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"como en esa pregunta )
  3. Inicie el servidor de la base de datos (por ejemplo sudo service postgresql start, sudo systemctl start postgresql)
Leeeroy
fuente
1
Pensé que sería útil tener en cuenta: si el directorio de datos de Postgres no está en el mismo volumen en el que está montado '/', es posible que deba desmontar antes / después de la operación anterior (no estoy seguro de cuál, en realidad). Además (tal vez un poco de vudú) intente ejecutar 'sincronización' antes y después de esos pasos.
Marcado el
18

La respuesta de Greg Smith sobre drop_caches fue muy útil. Encontré necesario detener e iniciar el servicio postgresql, además de eliminar las cachés. Aquí hay un script de shell que hace el truco. (Mi entorno es Ubuntu 14.04 y PostgreSQL 9.3).

#!/usr/bin/sudo bash

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

Probé con una consulta que tomó 19 segundos la primera vez y menos de 2 segundos en los intentos posteriores. Después de ejecutar este script, la consulta nuevamente tomó 19 segundos.

Steve Saporta
fuente
15

Utilizo este comando en mi caja de Linux:

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

Elimina por completo el caché.

Mike Starov
fuente
2
Si la versión de Postgresql no es 9.0: sync; sudo service postgresql stop; echo 1> / proc / sys / vm / drop_caches; sudo service postgresql start
rusllonrails
@rusllonrails Eso solo funcionará si se nombra el servicio postgresql, lo que puede no ser el caso.
jpmc26
Creo que syncdebería hacerse después de detener el servidor, inmediatamente antes drop_caches, ya que Postgres puede escribir algo durante el proceso de detención nuevamente.
greatvovan
8

Sí, postgresql ciertamente tiene almacenamiento en caché. El tamaño está controlado por la configuración shared_buffers . Aparte de eso, existe, como menciona la respuesta anterior, el caché de archivos del sistema operativo que también se usa.

Si desea ver qué hay en el caché, hay un módulo contrib llamado pg_buffercache disponible (en contrib / en el árbol de fuentes, en el RPM contrib, o donde sea apropiado para cómo lo instaló). Cómo usarlo se enumera en la documentación estándar de PostgreSQL.

No hay formas de borrar la memoria caché del búfer, salvo reiniciar el servidor. Puede eliminar el caché del sistema operativo con el comando mencionado en la otra respuesta, siempre que su sistema operativo sea Linux.

Magnus Hagander
fuente
7

Tuve este error.

psql: /cygdrive/e/test_insertion.sql: 9: ERROR: el tipo de parámetro 53 (t_stat_gardien) no coincide con eso al preparar el plan (t_stat_avant)

Estaba buscando vaciar el plan actual y encontré esto:

DESECHAR PLANES

Tenía esto entre mis inserciones y resuelve mi problema.

Luc M
fuente
2
El plan de descarte no se solucionó para mí, la consulta parece almacenada en caché todavía
deFreitas
1
La sintaxis correcta es DISCARD PLANS;. Y, como dice la documentación: "DISCARD libera recursos internos asociados con una sesión de base de datos ".
EAmez
6

Sí, es posible borrar los búferes compartidos de la caché de postgres Y la caché del sistema operativo. La siguiente solución es para Windows ... otros ya han dado la solución de Linux.

Como ya han dicho muchas personas, para borrar los búferes compartidos, puede simplemente reiniciar Postgres (no es necesario reiniciar el servidor). Pero simplemente hacer esto no borrará el caché del sistema operativo.

Para borrar el caché del sistema operativo utilizado por Postgres, después de detener el servicio, utilice el excelente RamMap ( https://technet.microsoft.com/en-us/sysinternals/rammap ), de la excelente Sysinternals Suite. Una vez que ejecute RamMap, simplemente haga clic en "Vaciar" -> "Lista de espera vacía" en el menú principal.

Reinicie Postgres y verá que su próxima consulta será muy lenta debido a que no hay caché en absoluto.

También puede ejecutar RamMap sin cerrar Postgres, y probablemente obtendrá los resultados "sin caché" que desea, ya que, como ya se ha dicho, los búferes compartidos suelen tener poco impacto en comparación con el caché del sistema operativo. Pero para una prueba confiable, prefiero detener postgres como todo antes de borrar la caché del sistema operativo para asegurarme.

Nota: AFAIK, no recomiendo borrar las otras cosas además de "Lista de espera" cuando se usa RamMap, porque los otros datos se están usando de alguna manera, y puede causar problemas / perder datos si lo hace. Recuerde que está borrando la memoria no solo utilizada por los archivos de Postgres, sino también por cualquier otra aplicación y sistema operativo.

Saludos, Thiago L.

Thiago Linhares de Oliveira
fuente
Me alegro de haber ayudado;)
Thiago Linhares de Oliveira
5

este es mi atajo

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
fuente
5

Hay un pg_buffercachemódulo para buscar en el shared_bufferscaché. Y en algún momento necesité eliminar el caché para realizar algunas pruebas de rendimiento en el caché 'frío', así que escribí una extensión pg_dropcache que hace exactamente esto. Por favor, míralo.

Ildar Musin
fuente