9 Eylül 2020 Çarşamba

PostgreSQL High Memory Utilization var mı nasıl kontrol edilir?

 PostgreSQL memory kullanımı fazla ise neler kontrol edilmesi gerekir?

Memoryden okumak her zaman diskten okumadan daha ölçülebilirdir, yani bütün database teknolojileri için kullanabildiğiniz kadar memory kullanmak isteyebilirsiniz.

Yaptığınız ayarlardan emin değil veya bir hatanız varsa, bu high memory utilization veya out-of-memory bile oluşturur.


Burada, nasıl PostgreSQL memory kullanımını kontrol edebileceğimize ve hangi parametreleri dikkate almanız gerektiğine bakacağız.

PostgreSQL mimarisi ile başlayalım.


PostgreSQL mimarisi

PostgreSQL mimarisi 3 temel parça üzerine kurulmuştur.

Processler, Memory ve Disk.


Memory iki sınıfa kategori edilebilir:


Local Memory: Her arka plan process’i tarafından kendi querileri işlemek için yüklenir ve alt alanlara ayrılmıştır.


*Work mem: Work mem ORDER BY ve DISTINCT işlemlerine göre tuple’ları sıralamak ve tabloları birleştirmek için kullanılır.


*Maintenance work mem: Bu alan bazı bakım işlemlerinde kullanılır.Örneğin, VACUUM, eğer "autovacuum_work_mem" belirtilmemişse.


*Temp buffers: Geçici tabloları depolamak için kullanılır.


Shared Memory: PostgreSQL server başlatıldığında PostgreSQL tarafından ayrılır ve onun işlemlerinde kullanılır. Alt alanlara ayrılmıştır.


*Shared buffer pool: PostgreSQL direkt memoryden çalışmak ve diske erişimi azaltmak için sayfalarla tabloları ve indexleri diskten yükler.


*WAL buffer:  The WAL data databasedeki işlem günlüğüdür ve değişiklikleri içerir. WAL buffer WAL data nın diske verilerini yazmadan önce verileri geçici olarak tuttuğu alandır.

Bu, kontrol noktası adı verilen önceden tanımlanmış bazı zamanlarda yapılır. Bir sunucu arızası durumunda bilgi kaybını önlemek için bu çok önemlidir.


* Commit log: Eşzamanlılık için bütün işlemleri kaydeder.


Ne olduğunu nasıl anlarsınız?

Eğer yüksek miktarda memory kullanımı varsa önce bu tüketimi yapan processin hangisi olduğunu belirleyiniz.

"Top" linux komutunu kullanın.


Muhtemelen buradaki en iyi seçenek "top" komutu ("htop" komutu da aynı işlevi görmektedir.)

Top komutu ile memory tüketen her bir processi ve processleri görebilirsiniz.

Yüksek miktarda memory kullanımından PostgreSQL sorumlu olduğundan emin olduktan sonra neden olduğunu kontrol edelim.


PostgreSQL Log'u kullanmak

Loglara baktığımızda aşağıdaki gibi bir mesaj ile karşılaşabiliriz:

"Resource temporarily unavailable

 

Out of memory: Kill process 1161 (postgres) score 366 or sacrifice child"


Eğer yeterli memory yoksa veya birden fazla hata varsa bunun gibi:

"FATAL:  password authentication failed for user "username"

 

ERROR:  duplicate key value violates unique constraint "sbtest21_pkey"

 

ERROR:  deadlock detected"


Beklenmedik davranışlar ile karşılaştığınızda database tarafında bu yüzden loglar kullanışlıdır bir sorunu belirlemede ve daha fazlasında.

Aslında bu logları parse edip alarmlar da oluşturabilirsiniz (“FATAL”, “ERROR” veya “Kill”).


Pg_top Kullanımı


Eğer bir PostgreSQL process’in yüksek memory kullandığını biliyor, ama bunu log dosyaları size yardımcı olmuyorsa, pg_top size yardımcı olacak kullanışlı bir araçtır.

Bu araç Linux Top ile benzerdir, ama özellikle PostgreSQL içindir. Yani, onu kullandığınızda database’niz üzerinde daha detaylı bilgi sahibi olursunuz, ve querileri kill edebilir, veya çalışan bir job’ın üzerinde yanlış bir şey var ise bunları tespit edebilirsiniz.


Ama database üzerinde bir error tespit edemediniz ve hala yüksek miktarda memory tüketiyorsa. O zaman muhtemelen database’inizin konfigürasyonuna bakmanız gerekecek.


Hangi konfigürasyon parametrelerini dikkate almak gerekir

Eğer herşey iyi gözüküyor ama hala yüksek memory kullanımı sorunu varsa,

konfigürasyonu kontrol etmeli ve doğru olduğundan emin olmalısınız.

Yani aşağıdaki parametreleri dikkate almalısınız.


Shared_buffers

Bu database sunucusunun kullandığı shared memory de kullandığı memory miktarıdır. Eğer bu çok az olursa, database daha fazla diski kullanır ve daha fazla yavaş olmasına sebep olur. Ama çok fazla olursa yüksek memory kullanımı oluşur.Dökümana göre, eğer database sunucusuna 1GB veya üzerinde RAM atanırsa, başlangıç olarak shared_buffer sistemdeki memory’nin %25’ni kullanır.


work_mem

Diskteki geçici dosyaya yazmadan önce ORDER BY, DISTINCT ve JOIN özel olarak kullandığı memory miktarıdır. Shared_buffers da olduğu gibi, bu parametreyi çok düşük miktarda verilirse, bir çok işlemimiz disk’e gider, ama fazlası memory kullanımı için tehlikeli olabilir. Varsayılan değeri 4 MB'dır.


max_connections

work_mem ayrıca  max_connecitons değeriyle el ele gider, çünkü her bağlantıda bu işlemleri aynı anda yürütür ve her işlemin geçici dosyalara veri yazmadan önce bu değerle belirtilen kadar memory kullanmasına izin verilecektir.

Bu parametre database bağlanan max eş zamanlı bağlantı sayısını belirler, eğer bağlantı sayısını yüksek ayarlarsak bu bize kaynak yetersizliği sorunları oluşturacaktır. Varsayılan değeri 100’dür.


temp_buffers

temp_buffers her oturumda geçici tabloları tutmak için kullanılır.

Bu parametre bu iş için en fazla memory alanını ayarlar. Varsayılan değeri 8 MB’dir.


maintenance_work_mem

Bu bir işlemin Vacuuming, adding indexes veya foreign keys tüketebileceği en fazla memory miktarıdır. İyi tarafı bu tip bir işlem bir oturum içinde bir işlem olarak çalışır ve çok yaygın bir şey değildir bir oturum içinde birden fazla işlem çalıştırması.Varsayılan değeri 64 MB’dır.

autovacuum_work_mem

Vacuum maintenance_work_mem’i kullanırım varsayılan olarak, ama onu bu parametre yardımıyla ayırabiliriz.  Her bir autovacuum worker için max memory kullanımını belirleyebiliriz.


wal_buffers

Diske henüz yazılmamış WAL data için kullanılan shared memory miktarıdır.

Varsayılan olarak shared_buffers’ın %3’dür, ama 64kb az olamaz ve WAL bölümünden de çok olamaz, tipik olarak 16 MB’dır.



Sonuç

Birden fazla sebebi olabilir yüksek memory kullanımının.
Biz burada sorunu bulmak için bakmanız gereken noktaları işaret etmeye çalıştık.