So berechnen Sie Cache-Fehler für PostgreSQL


7

Ich verwalte einen Server, auf dem ein Tool mit PostgreSQL ausgeführt wird. Das Tool kümmert sich selbst um die meisten PostgreSQL-Konfigurationen, aber ich beobachte einige Leistungsprobleme. Ich konnte auf Betriebssystemebene bestätigen, dass viele E / A-Vorgänge stattfinden , daher vermute ich, dass viele Cache-Fehler auftreten.

Wenn Sie im Internet nach "Cache Miss" oder "Cache Miss Postgresql" oder ähnlichen Suchanfragen suchen, finden Sie viele Verweise auf " cache_miss statistics ". Aber nirgends wird erklärt, wie man sie bekommt! Ich habe irgendwie verstanden, dass dieser Wert berechnet werden muss, indem Treffer von Abrufen abgezogen werden . Aber da ich kein erfahrener DB-Administrator bin, verstehe ich nicht wirklich, dass Werte gemeint sind: -S

Ich habe die Dokumentation zu PostgreSQL - Monitoring Database Activity gefunden , bin mir aber nicht sicher, ob die folgende Formel alles ist, was ich brauche:

cache_miss = "result_of" pg_stat_get_db_blocks_fetched(oid) - "result_of" pg_stat_get_db_blocks_hit(oid)

Eine Erklärung für Dummies wäre sehr dankbar.

Vielen Dank im Voraus!


Wie groß ist die Datenbank? Passt die Datenbank in den Speicher? Überprüfen Sie vmstat / iostat bei einem Kaltstart? Denken Sie daran, dass die Datenbank in den Speicher geladen werden muss, bevor das Caching wirksam werden kann.
François Beausoleil

Leider passt die DB nie in den Speicher, da sie über 200 GB groß ist! = -OIch habe vmstat / iostat bei einem Kaltstart nicht überprüft und werde es mir ansehen. Aber es würde mir nur die Kernel-Cache-Fehler geben, nicht wahr? Ich fange an zu denken, dass der fehlende DB-Cache das Feld blks_read aus der Ansicht pg_stat_database
silvavlis

Antworten:


1

In der Dokumentation von PostgreSql gibt es einen Absatz: ( Hier )

Note: pg_stat_get_blocks_fetched minus pg_stat_get_blocks_hit gives the number of kernel read() calls issued for the table, index, or database; the number of actual physical reads is usually lower due to kernel-level buffering. The *_blks_read statistics columns use this subtraction, i.e., fetched minus hit.

Dies könnte Ihren Zweifel erklären.


1

Ich benutze diese Abfrage, um disk x cacheTreffer anzuzeigen:

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

Geben Sie hier die Bildbeschreibung ein


Hallo. Ihre "Festplatten-Treffer" können also immer noch den Festplatten-Cache des Betriebssystems treffen, oder? Das heißt, es trifft auf den Speicher der gemeinsam genutzten Puffer?
Duarte Carreira

Ja! Der Wert "Festplattentreffer" bedeutet, dass das Tupel nicht in den gemeinsam genutzten Puffern der Datenbank gefunden wurde. Dies bedeutet jedoch nicht unbedingt, dass db auf die Festplatte gegangen ist, um das Tupel zu erhalten. Manchmal erhalten Sie einen guten Hinweis, insbesondere wenn Sie einen dedizierten Server haben, auf dem fast der gesamte Speicher für die gemeinsam genutzten Puffer reserviert ist. Wenn Sie in diesem Fall einen hohen Prozentsatz an "Festplatten-Treffern" haben, bedeutet dies sicherlich, dass es Zeit ist, den Speicher zu aktualisieren.
Christian

In den Fällen, in denen Sie einen gemeinsam genutzten Server haben (und Sie können nicht fast den gesamten Speicher für gemeinsam genutzte Puffer "reservieren") und einen hohen Prozentsatz an "Festplattentreffern" haben, bedeutet dies, dass die Datenbank durch die Speichernutzung gegen die anderen Prozesse "antritt" und abhängig von der Speichernutzung (durch die anderen Prozesse) wird es wahrscheinlich auf die Festplatte gehen, um Tupel zu erhalten. In dem einen oder anderen Fall müssen Sie also hohe Prozentsätze für "Festplatten-Treffer" vermeiden.
Christian
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.