Come posso verificare se il mio DB ha bisogno di più RAM?


11

Come verifichi se la tua istanza DB postgresql necessita di più memoria RAM per gestire i dati di lavoro attuali?


8
Non c'è bisogno di controllare, hai sempre bisogno di più RAM. :)
Alex Howansky il

1
Non è una domanda di programmazione, sto votando per spostarlo su ServerFault.
GManNickG

1
Non sono un DBA, ma inizierei vedendo che le query più comuni sono al limite di essere hash unite invece di unire annidato in loop. C'è qualche ottimizzazione della configurazione db che puoi fare che potrebbe influire sulla quantità di memoria disponibile anche per qualsiasi query particolare [controlla i documenti o invia la mailing list alla mailing è il mio suggerimento]. Può anche essere utile vedere se hai abbastanza RAM per mantenere le tabelle comunemente utilizzate nella cache. Ma alla fine, a meno che il tuo INTERO DB non si inserisca nella RAM, potresti usarne di più. :)

Risposte:


14

Se tutto ciò che si trova su Linux, la RAM fisica totale dovrebbe essere maggiore della dimensione del database sul disco per ridurre al minimo l'I / O. Alla fine l'intero database sarà nella cache di lettura del sistema operativo e l'I / O sarà limitato al commit delle modifiche sul disco. Preferisco trovare la dimensione del DB eseguendo "du -shc $ PGDATA / base" - quel metodo aggrega tutti i database in un unico numero. Finché sei più grande di quello, dovrebbe andare bene.

Inoltre, puoi consultare la percentuale di riscontri nella cache degli heap e dei recuperi di blocchi di indice. Questi misurano la frequenza degli hit nei buffer condivisi di PostgreSQL. I numeri possono essere un po 'fuorvianti - anche se potrebbe essere stato un errore nella cache dei buffer condivisi, potrebbe comunque essere un successo nella cache di lettura del sistema operativo. Tuttavia, gli hit nei buffer condivisi sono ancora meno costosi degli hit nella cache di lettura del sistema operativo (che, a loro volta, sono meno costosi di un paio di ordini di grandezza rispetto al dover tornare sul disco).

Per esaminare la percentuale di hit dei buffer condivisi, utilizzo questa query:

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;

Questo ti dà i 25 peggiori trasgressori in cui manca la cache del buffer per tutte le tabelle in cui è stato necessario recuperare almeno un blocco dal "disco" (di nuovo, che potrebbe essere la cache di lettura del sistema operativo o l'I / O del disco effettivo). È possibile aumentare il valore nella clausola WHERE o aggiungere un'altra condizione per heap_blks_hit per filtrare le tabelle utilizzate di rado.

La stessa query di base può essere utilizzata per verificare la percentuale di hit dell'indice totale per tabella sostituendo globalmente la stringa "heap" con "idx". Dai un'occhiata a pg_statio_user_indexes per ottenere una suddivisione per indice.

Una breve nota sui buffer condivisi: una buona regola empirica per questo in Linux è di impostare il parametro di configurazione shared_buffers su 1/4 di RAM, ma non più di 8 GB. Questa non è una regola rigida, ma piuttosto un buon punto di partenza per l'ottimizzazione di un server. Se il tuo database ha solo 4 GB e hai un server da 32 GB, 8 GB di buffer condivisi sono effettivamente eccessivi e dovresti essere in grado di impostarlo su 5 o 6 GB e avere ancora spazio per la crescita futura.


9

Ho creato questo SQL per mostrare il rapporto tra tabelle e hit del 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

inserisci qui la descrizione dell'immagine


1

Funziona anche, come detto nel documento di Heroku:

SELECT
    'cache hit rate' AS name,
     sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS ratio
FROM pg_statio_user_tables;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.