¿Cómo comprobaría si su instancia de DB postgresql necesita más memoria RAM para manejar sus datos de trabajo actuales?
¿Cómo comprobaría si su instancia de DB postgresql necesita más memoria RAM para manejar sus datos de trabajo actuales?
Respuestas:
Si todo lo que está en Linux, su RAM física total debe ser mayor que el tamaño de su base de datos en el disco para minimizar la E / S. Finalmente, toda la base de datos estará en la caché de lectura del sistema operativo y la E / S se limitará a confirmar los cambios en el disco. Prefiero encontrar el tamaño de la base de datos ejecutando "du -shc $ PGDATA / base", ese método agrega todas las bases de datos en un solo número. Mientras seas más grande que eso, debería estar bien.
Además, puede ver la tasa de aciertos de caché de las capturas de bloque de índice y montón. Estos miden la tasa de visitas a los buffers compartidos de PostgreSQL. Los números pueden ser un poco engañosos, aunque puede haber sido un error en la memoria caché de buffers compartidos, aún puede ser un éxito en la memoria caché de lectura del sistema operativo. Aún así, los hits en los buffers compartidos son aún menos costosos que los hits en la memoria caché de lectura del sistema operativo (que, a su vez, son menos costosos en un par de órdenes de magnitud que tener que volver al disco).
Para ver la tasa de aciertos de los buffers compartidos, utilizo esta consulta:
SELECT relname, heap_blks_read, heap_blks_hit,
round(heap_blks_hit::numeric/(heap_blks_hit + heap_blks_read),3)
FROM pg_statio_user_tables
WHERE heap_blks_read > 0
ORDER BY 4
LIMIT 25;
Esto le da a los 25 peores delincuentes principales donde se pierde la memoria caché del búfer para todas las tablas donde al menos un bloque tuvo que ser recuperado del "disco" (nuevamente, que podría ser la memoria caché de lectura del sistema operativo o la E / S del disco real). Puede aumentar el valor en la cláusula WHERE o agregar otra condición para heap_blks_hit para filtrar las tablas poco utilizadas.
La misma consulta básica se puede utilizar para verificar la tasa de aciertos del índice total por tabla reemplazando globalmente la cadena "montón" con "idx". Eche un vistazo a pg_statio_user_indexes para obtener un desglose por índice.
Una nota rápida sobre los buffers compartidos: una buena regla general para esto en Linux es establecer el parámetro de configuración shared_buffers en 1/4 de RAM, pero no más de 8GB. Esta no es una regla estricta, sino un buen punto de partida para ajustar un servidor. Si su base de datos es de solo 4 GB y tiene un servidor de 32 GB, 8 GB de memorias intermedias compartidas en realidad es excesivo y debería poder configurarlo en 5 o 6 GB y aún tener espacio para el crecimiento futuro.
Hice este SQL para mostrar las tablas vs la proporción de aciertos de disco:
-- perform a "select pg_stat_reset();" when you want to reset counter statistics
with
all_tables as
(
SELECT *
FROM (
SELECT 'all'::text as table_name,
sum( (coalesce(heap_blks_read,0) + coalesce(idx_blks_read,0) + coalesce(toast_blks_read,0) + coalesce(tidx_blks_read,0)) ) as from_disk,
sum( (coalesce(heap_blks_hit,0) + coalesce(idx_blks_hit,0) + coalesce(toast_blks_hit,0) + coalesce(tidx_blks_hit,0)) ) as from_cache
FROM pg_statio_all_tables --> change to pg_statio_USER_tables if you want to check only user tables (excluding postgres's own tables)
) a
WHERE (from_disk + from_cache) > 0 -- discard tables without hits
),
tables as
(
SELECT *
FROM (
SELECT relname as table_name,
( (coalesce(heap_blks_read,0) + coalesce(idx_blks_read,0) + coalesce(toast_blks_read,0) + coalesce(tidx_blks_read,0)) ) as from_disk,
( (coalesce(heap_blks_hit,0) + coalesce(idx_blks_hit,0) + coalesce(toast_blks_hit,0) + coalesce(tidx_blks_hit,0)) ) as from_cache
FROM pg_statio_all_tables --> change to pg_statio_USER_tables if you want to check only user tables (excluding postgres's own tables)
) a
WHERE (from_disk + from_cache) > 0 -- discard tables without hits
)
SELECT table_name as "table name",
from_disk as "disk hits",
round((from_disk::numeric / (from_disk + from_cache)::numeric)*100.0,2) as "% disk hits",
round((from_cache::numeric / (from_disk + from_cache)::numeric)*100.0,2) as "% cache hits",
(from_disk + from_cache) as "total hits"
FROM (SELECT * FROM all_tables UNION ALL SELECT * FROM tables) a
ORDER BY (case when table_name = 'all' then 0 else 1 end), from_disk desc