Veritabanımın daha fazla RAM'e ihtiyacı olup olmadığını nasıl kontrol edebilirim?


11

Postgresql DB yönetim ortamınızın geçerli çalışma verilerini işlemek için daha fazla RAM belleğe ihtiyacı olup olmadığını nasıl kontrol edersiniz?


8
Kontrol etmeye gerek yok, her zaman daha fazla RAM'e ihtiyacınız var. :)
Alex Howansky

1
Bir programlama sorusu değil, bunu ServerFault'a taşımak için oy veriyorum.
GManNickG

1
Ben bir DBA değilim, ama iç içe birleştirilmiş döngü yerine birleştirme karma kenarında olan herhangi bir ortak sorgu görerek başlayacaktı. Herhangi bir sorgu için ne kadar bellek kullanılabilir olduğunu etkileyebilecek yapabileceğiniz bazı db yapılandırma ayarları vardır [belgeleri kontrol edin ya da e-posta listesi benim önerim e-posta]. Sık kullanılan tabloları önbelleğe almak için yeterli RAM'in olup olmadığını görmek de yararlı olabilir. Ama sonuçta, ENTIRE DB'niz RAM'e sığmazsa daha fazlasını kullanabilirsiniz. :)

Yanıtlar:


14

Tüm Linux'taysanız, G / Ç'yi en aza indirmek için toplam fiziksel RAM'iniz diskteki veritabanı boyutundan daha büyük olmalıdır. Sonunda tüm veritabanı OS okuma önbelleğinde olacak ve G / Ç, diskte değişiklik yapmakla sınırlı olacaktır. Ben "du -shc $ PGDATA / base" çalıştırarak DB boyutunu bulmayı tercih ediyorum - bu yöntem tüm veritabanlarını tek bir sayı halinde toplar. Bundan daha büyük olduğunuz sürece, iyi olmalı.

Ayrıca, yığın ve dizin bloğu getirilerinin önbellek isabet oranına bakabilirsiniz. Bunlar, PostgreSQL'in paylaşılan arabelleklerine isabet oranını ölçer. Sayılar biraz yanıltıcı olabilir - paylaşılan arabellek önbelleğinde bir özlüyor olsa bile, işletim sistemi okuma önbelleğinde hala bir hit olabilir. Yine de, paylaşılan arabelleklerdeki isabetler hala OS okuma önbelleğindeki isabetlerden daha ucuzdur (bu da, diske geri dönmek zorunda kalmadan birkaç büyüklük sırası ile daha ucuzdur).

Paylaşılan arabellek isabet oranına bakmak için bu sorguyu kullanıyorum:

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;

Bu, en az bir bloğun "disk" ten alınması gereken tüm tablolar için arabellek önbelleğinin kaçırıldığı en kötü 25 en kötü suçluyu verir (yine OS okuma önbelleği veya gerçek disk G / Ç olabilir). WHERE deyimindeki değeri artırabilir veya nadiren kullanılan tabloları filtrelemek için heap_blks_hit için başka bir koşul ekleyebilirsiniz.

Aynı temel sorgu, "yığın" dizesini genel olarak "idx" ile değiştirerek tablo başına toplam dizin isabet oranını kontrol etmek için kullanılabilir. İndeks başına bir döküm elde etmek için pg_statio_user_indexes adresine göz atın.

Paylaşılan arabellekler hakkında kısa bir not: Linux'ta bunun için iyi bir kural, shared_buffers yapılandırma parametresini RAM'in 1 / 4'üne , ancak 8GB'dan fazla olmamasına ayarlamaktır. Bu zor ve hızlı bir kural değil, bir sunucuyu ayarlamak için iyi bir başlangıç ​​noktasıdır. Veritabanınız sadece 4GB ise ve 32GB'lık bir sunucunuz varsa, 8GB paylaşılan arabellek aslında gereğinden fazladır ve bunu 5 veya 6 GB'a ayarlayabilmeniz ve gelecekteki büyümeniz için hala boş alanınız olması gerekir.


9

Tablolar disk isabet oranı vs göstermek için bu SQL yaptı:

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

resim açıklamasını buraya girin


1

Aynı zamanda Heroku belgesinde de belirtildiği gibi çalışır:

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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.