DBにRAMがさらに必要かどうかを確認するにはどうすればよいですか?


11

postgresql DBインスタンスが現在の作業データを処理するためにより多くのRAMメモリを必要とするかどうかをどのように確認しますか?


8
チェックする必要はありません。常により多くのRAMが必要です。:)
Alex Howansky

1
プログラミングの質問ではないので、ServerFaultに移動することにします。
GManNickG

1
私はDBAではありませんが、一般的なクエリが、ネストされたマージループではなく、ハッシュ結合の端にあることから始めます。特定のクエリで使用できるメモリの量に影響を与える可能性のあるいくつかのdb configチューニングがあります[ドキュメントを確認するか、メーリングリストにメールを送ってください]。また、よく使用されるテーブルをキャッシュしておくのに十分なRAMがあるかどうかを確認することも役立ちます。ただし、最終的には、DB全体がRAMに収まらない場合は、さらに多く使用できます。:)

回答:


14

Linuxを使用している場合、I / Oを最小限に抑えるために、物理RAMの合計はディスク上のデータベースサイズよりも大きくする必要があります。最終的には、データベース全体がOS読み取りキャッシュに置かれ、I / Oは変更をディスクにコミットすることに限定されます。私は「du -shc $ PGDATA / base」を実行してDBサイズを見つけることを好みます。この方法では、すべてのデータベースが1つの数値に集約されます。あなたがそれよりも大きい限り、それは問題ないはずです。

さらに、ヒープおよびインデックスブロックフェッチのキャッシュヒット率を確認できます。これらは、PostgreSQLの共有バッファへのヒット率を測定します。数値は少し誤解を招く可能性があります-たとえそれが共有バッファキャッシュでのミスであったとしても、それでもOS読み取りキャッシュでのヒットである可能性があります。それでも、共有バッファでのヒットは、OS読み取りキャッシュでのヒットよりも安価です(そのため、ディスクに戻る必要がある場合よりも数桁も安価です)。

共有バッファのヒット率を調べるために、次のクエリを使用します。

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;

これにより、「ディスク」から少なくとも1つのブロックをフェッチする必要があったすべてのテーブルでバッファキャッシュが失われる上位25の最悪の違反者がわかります(これも、OS読み取りキャッシュまたは実際のディスクI / Oのいずれかです)。WHERE句の値を増やすか、heap_blks_hitに別の条件を追加して、使用頻度の低いテーブルを除外できます。

同じ基本的なクエリを使用して、文字列「heap」を「idx」でグローバルに置き換えることにより、テーブルごとの合計インデックスヒット率を確認できます。pg_statio_user_indexesを見て、インデックスごとの内訳を取得してください。

共有バッファに関する簡単なメモ:Linuxでのこれの良い経験則は、構成パラメータshared_buffersをRAMの1/4に設定することですが、8GB以下にしてください。これは厳格な規則ではなく、サーバーをチューニングするための良い出発点です。データベースが4 GBのみで32 GBのサーバーを使用している場合、8 GBの共有バッファーは実際には過剰であり、これを5または6 GBに設定しても、将来の拡張の余地があります。


9

テーブルとディスクヒット率を示すために、このSQLを作成しました。

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

ここに画像の説明を入力してください


1

Heroku docで述べられているように、それも機能します:

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;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.