Wie würden Sie überprüfen, ob Ihre Postgresql-DB-Instanz mehr RAM-Speicher benötigt, um ihre aktuellen Arbeitsdaten zu verarbeiten?
Wie würden Sie überprüfen, ob Ihre Postgresql-DB-Instanz mehr RAM-Speicher benötigt, um ihre aktuellen Arbeitsdaten zu verarbeiten?
Antworten:
Wenn Sie nur unter Linux arbeiten, sollte Ihr physischer Gesamtspeicher größer sein als Ihre Datenbankgröße auf der Festplatte, um E / A zu minimieren. Schließlich befindet sich die gesamte Datenbank im Lesecache des Betriebssystems, und die E / A können nur Änderungen an der Festplatte vornehmen. Ich bevorzuge es, die DB-Größe durch Ausführen von "du -shc $ PGDATA / base" zu ermitteln - diese Methode fasst alle Datenbanken zu einer einzigen Zahl zusammen. Solange Sie größer sind, sollte es in Ordnung sein.
Darüber hinaus können Sie die Cache-Trefferquote von Heap- und Indexblockabrufen anzeigen. Diese messen die Trefferquote in den gemeinsam genutzten Puffern von PostgreSQL. Die Zahlen können etwas irreführend sein - auch wenn es sich möglicherweise um einen Fehler im Cache für gemeinsam genutzte Puffer handelt, kann es dennoch zu einem Treffer im Lese-Cache des Betriebssystems kommen. Trotzdem sind Treffer in gemeinsam genutzten Puffern immer noch günstiger als Treffer im Lesecache des Betriebssystems (die wiederum um einige Größenordnungen günstiger sind, als wenn sie auf die Festplatte zurückkehren müssen).
Um die Trefferquote der gemeinsam genutzten Puffer anzuzeigen, verwende ich diese Abfrage:
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;
Dies gibt Ihnen die 25 schlimmsten Straftäter, bei denen der Puffercache für alle Tabellen fehlt, bei denen mindestens ein Block von "Festplatte" abgerufen werden musste (dies kann entweder der Betriebssystem-Lese-Cache oder die tatsächliche Festplatten-E / A sein). Sie können den Wert in der WHERE-Klausel erhöhen oder eine weitere Bedingung für heap_blks_hit hinzufügen, um selten verwendete Tabellen herauszufiltern.
Dieselbe grundlegende Abfrage kann verwendet werden, um die Gesamtindex-Trefferquote pro Tabelle zu überprüfen, indem die Zeichenfolge "heap" global durch "idx" ersetzt wird. Schauen Sie sich pg_statio_user_indexes an, um eine Aufschlüsselung nach Index zu erhalten.
Ein kurzer Hinweis zu gemeinsam genutzten Puffern: Eine gute Faustregel für Linux ist, den Konfigurationsparameter shared_buffers auf 1/4 des Arbeitsspeichers, jedoch nicht mehr als 8 GB festzulegen . Dies ist keine feste Regel, sondern ein guter Ausgangspunkt für die Optimierung eines Servers. Wenn Ihre Datenbank nur 4 GB groß ist und Sie einen 32-GB-Server haben, sind 8 GB gemeinsam genutzte Puffer tatsächlich zu viel des Guten. Sie sollten dies auf 5 oder 6 GB einstellen können und dennoch Platz für zukünftiges Wachstum haben.
Ich habe diese SQL erstellt, um das Verhältnis von Tabellen zu Festplattentreffern 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