PostgreSQL yüksek CPU kullanıyor: önce pg_stat_statements'a bakın
PostgreSQL'de CPU yükseldiğinde kaynağı sunucu grafiği yerine sorgu istatistikleriyle bulmak: pg_stat_statements kurulumu ve en pahalı sorgular.
CPU grafiği %90'da, load average çekirdek sayısının üstünde. Grafik size ne kadar yük olduğunu söyler, neyin yük olduğunu söylemez. PostgreSQL'de "neyin" sorusunun cevabı genellikle pg_stat_statements'tadır.
pg_stat_statements nedir?
PostgreSQL ile gelen bir uzantıdır. Çalıştırılan her sorguyu parametrelerinden arındırılmış hâliyle (normalize) gruplar ve kaç kez çalıştığını, toplam/ortalama süresini, döndürdüğü satır sayısını, okuduğu blokları tutar.
Kurulum
Uzantı paylaşımlı bellek kullandığı için önce ön yüklenmesi gerekir. Bu adım yeniden başlatma ister:
# postgresql.conf
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = top
Yeniden başlattıktan sonra izlemek istediğiniz veritabanında:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
En pahalı sorgular
CPU'yu en çok tüketen sorgu her zaman en yavaş sorgu değildir. Saniyede binlerce kez çalışan 5 ms'lik bir sorgu, günde bir kez çalışan 30 saniyelik raporu kolayca geçer. Bu yüzden önce toplam süreye bakın:
SELECT
round(total_exec_time::numeric / 1000, 1) AS toplam_sn,
calls AS cagri,
round(mean_exec_time::numeric, 2) AS ort_ms,
rows,
round(100 * total_exec_time / sum(total_exec_time) OVER (), 1) AS yuzde,
left(query, 120) AS sorgu
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 15;
Ardından tek tek pahalı olanları görmek için mean_exec_time'a göre sıralayın. Disk okuması şüphesi varsa shared_blks_read ve shared_blks_hit sütunları önbellek isabetini gösterir.
PostgreSQL 12 ve öncesinde sütun adları
total_timevemean_timeşeklindedir.
Zaman penceresini unutmayın
İstatistikler son sıfırlamadan bu yana birikir. Üç ay önceki bir toplu iş listenin tepesinde duruyor olabilir. Bu yüzden rakamları yorumlamadan önce pencereyi öğrenin:
-- PostgreSQL 14+
SELECT stats_reset FROM pg_stat_statements_info;
Temiz bir ölçüm için istatistikleri sıfırlayıp sorunun yaşandığı zaman aralığını bekleyin:
SELECT pg_stat_statements_reset();
Sonraki adımlar
Kaynağı bulduktan sonra tipik müdahaleler:
- Şüpheli sorguyu gerçek parametrelerle
EXPLAIN (ANALYZE, BUFFERS)ile inceleyin. - Eksik indeks, gereksiz
SELECT *, N+1 sorgu deseni ve sık çalışan ama önbelleklenebilecek sorguları arayın. - Değişiklikten sonra istatistikleri sıfırlayıp aynı pencerede yeniden ölçün.
Ders
Sunucu grafiği semptomdur; sorgu istatistiği teşhistir. Donanım eklemeden önce önce bir bakalım: yükü hangi sorgu üretiyor?