web-dev-qa-db-ja.com

PostgreSQLのキャッシュミスを計算する方法

PostgreSQLを使用するツールが実行されるサーバーを管理しています。このツールはほとんどのPostgreSQL構成を単独で処理しますが、いくつかのパフォーマンスの問題を観察しています。 大量のI/Oが行われていることをOSレベルで確認できたため、多くのキャッシュミスが発生していると思われます。

「キャッシュミス」または「キャッシュミスpostgresql」または同様の検索をインターネットで検索すると、「cache_miss statistics」への多くの参照が見つかります。 」しかし、それらを取得する方法はどこにも説明されていません!その値は、フェッチからヒットを差し引いて減算する必要があることを理解しています。しかし、私は経験のないDB管理者ではないので、値が意味するものを本当に理解していません:-S

PostgreSQL-Monitoring Database Activity のドキュメントを見つけましたが、次の式が必要かどうかはわかりません。

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

ダミーの説明をいただければ幸いです。

前もって感謝します!

7
silvavlis

PostgreSqlのドキュメントに段落があります:( ここ

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.

これはあなたの疑問を説明するかもしれません。

1
Mike Lue

このクエリを使用してdisk x cacheヒット:

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

enter image description here

1
Christian