Comment vérifieriez-vous si votre instance de base de données postgresql a besoin de plus de mémoire RAM pour gérer ses données de travail actuelles?
Comment vérifieriez-vous si votre instance de base de données postgresql a besoin de plus de mémoire RAM pour gérer ses données de travail actuelles?
Réponses:
Si tout ce que vous êtes sur Linux, votre RAM physique totale doit être supérieure à la taille de votre base de données sur le disque afin de minimiser les E / S. Finalement, toute la base de données sera dans le cache de lecture du système d'exploitation et les E / S seront limitées à la validation des modifications sur le disque. Je préfère trouver la taille de la base de données en exécutant "du -shc $ PGDATA / base" - cette méthode regroupe toutes les bases de données en un seul numéro. Tant que vous êtes plus grand que ça, ça devrait aller.
En outre, vous pouvez consulter le taux d'accès au cache des récupérations de tas et d'index. Ceux-ci mesurent le taux de hits dans les tampons partagés de PostgreSQL. Les chiffres peuvent être un peu trompeurs - même si cela a pu être un échec dans le cache des tampons partagés, il peut toujours être un succès dans le cache de lecture du système d'exploitation. Pourtant, les hits dans les tampons partagés sont toujours moins chers que les hits dans le cache de lecture du système d'exploitation (qui, à leur tour, sont moins chers de quelques ordres de grandeur que d'avoir à revenir sur le disque).
Afin de regarder le taux de réussite des tampons partagés, j'utilise cette requête:
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;
Cela vous donne les 25 pires contrevenants où le cache tampon est manquant pour toutes les tables où au moins un bloc a dû être récupéré à partir du "disque" (encore une fois, qui pourrait être le cache de lecture du système d'exploitation ou les E / S de disque réelles). Vous pouvez augmenter la valeur dans la clause WHERE ou ajouter une autre condition pour que heap_blks_hit filtre les tables rarement utilisées.
La même requête de base peut être utilisée pour vérifier le taux de réussite d'index total par table en remplaçant globalement la chaîne "heap" par "idx". Jetez un œil à pg_statio_user_indexes pour obtenir une ventilation par index.
Une note rapide sur les tampons partagés: une bonne règle de base pour cela sous Linux est de définir le paramètre de configuration shared_buffers sur 1/4 de RAM, mais pas plus de 8 Go. Ce n'est pas une règle stricte et rapide, mais plutôt un bon point de départ pour régler un serveur. Si votre base de données ne fait que 4 Go et que vous avez un serveur de 32 Go, 8 Go de tampons partagés sont en fait exagérés et vous devriez pouvoir définir cela à 5 ou 6 Go et avoir encore de la place pour une croissance future.
J'ai fait ce SQL pour montrer le rapport tables / disques:
-- 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