AWS Türkçe Blog

Uygulama geliştiricileri için PostgreSQL mimarisi konuları: 1. Bölüm

Orijinal makale: Link (Peter Celentano ve Tracy Jenkins)

Uygulama katmanı, birçok bulut mimarisi için dünyanın eriştiği kısım olsa da, görünüşe göre uygulamamızı kullandığımız veritabanı için nasıl optimize edebileceğimizi nadiren düşünüyoruz. Herhangi bir ilişkisel veritabanı motorunu kullanırken, uygulamanın yönetilebilir, ölçeklenebilir ve performanslı olmasını sağlamak için yalnızca şema tasarımını değil, veritabanlarının depolama sistemlerine nasıl veri okuyup yazdığını anlamak da önemlidir. Bir dizinin 1. Bölümü olan bu gönderide, önemli PostgreSQL terimlerini ele alıyoruz, ardından PostgreSQL için Amazon Aurora PostgreSQL-Compatible Edition veya Amazon Relational Database Service (Amazon RDS) kullanırken “autocommit”, “autovacuum” ve “idle in transaction” konularını biraz daha derinlemesine inceliyoruz.

PostgreSQL parametre değişiklikleri yapmak: Nerede, ne zaman ve neden

Parametreler, temel özelliklerini tanımlamak için veritabanlarında ve PostgreSQL’de kullanılır. PostgreSQL, yeni veritabanları oluşturulurken ayarlanan varsayılan parametrelere sahiptir ve birçok sistem için normalde varsayılan parametreler iyi performans sağlar ve ayarlamaya gerek yoktur. Sistemler büyüdükçe, ölçeklendikçe ve daha fazla strese maruz kaldıkça, optimum performans için bazı parametrelerin ayarlanması gerekebilir.

Kendi yönettiğiniz veya AWS tarafından yönetilen bir veritabanı kullanıp kullanmadığınıza bağlı olarak farklı parametre değerlerinin değiştirilmesi gerekecektir. Kendi yönettiğiniz veritabanları için postgresql.conf dosyasında parametre değişiklikleri yapılır. AWS tarafından yönetilen veritabanlarında, postgresql.conf dosyasına erişim kısıtlanmıştır, bu nedenle temel veritabanınız veya küme parametre gruplarınızda (cluster parameter groups) yalnızca AWS Management Console, AWS Komut Satırı Arabirimi (AWS CLI), SDK veya AWS CloudFormation aracılığıyla değişiklikler yapılabilir.

postgresql.conf (kendi yönettiğiniz)

Kendi yönettiğiniz veritabanları için, parametrelerin PostgreSQL kümenizde genel olarak ayarlanması amaçlandığında bu dosyada (PostgreSQL veri dizininizde) değişiklikler yapılır. Daha fazla bilgi için, PostgreSQL topluluk belgelerindeki Parametre Ayarlama‘ya bakın.

RDS DB parametre grubu (AWS tarafından yönetilen)

Amazon RDS küme düzeyi ve veritabanı düzeyi parametre grupları, bulut sunucusu sınıfına ve boyutuna bağlı olarak varsayılan ayarlara sahiptir. Daha iyi performans için farklı değerler gerekiyorsa konsol, AWS CLI, SDK veya AWS CloudFormation aracılığıyla yeni bir parametre grubu oluşturabilirsiniz. Daha fazla bilgi için bkz. Veritabanı parametre grubu oluşturma.

Oturum düzeyi (kendi yönettiğiniz veya AWS tarafından yönetilen)

Birçok PostgreSQL parametresi oturum düzeyinde değiştirilebilir (bir veya daha fazla işlemden oluşur), çünkü bu parametreler pano genelinde değil, yalnızca iş yükünüz içindeki belirli sorgular için istenir. Bu parametreler SET komutu kullanılarak değiştirilebilir. Daha fazla bilgi için, PostgreSQL topluluk belgelerindeki SET‘e bakın.

PostgreSQL kavramları

Bu bölümde, PostgreSQL veritabanlarının çalışması için hayati önem taşıyan temel PostgreSQL kavramlarını tartışıyoruz.

İşlemler (Transactions)

PostgreSQL’de bir işlem, tek bir işlem olarak çalıştırılan bir SQL ifadeleri dizisidir. Bu işlem modeli, bir işlemdeki tüm ifadelerin veritabanına başarıyla kaydedilmesini veya bir ifade başarısız olursa (veya bir hata oluşursa) geri alınmasını sağlar. PostgreSQL, veritabanı işlemlerinde atomiklik, tutarlılık, yalıtım ve dayanıklılığın her zaman korunmasını sağlayan bir dizi veritabanı özelliği olan ACID uyumludur:

  • Atomiklik (Atomicity) – Veritabanı atomitesi, işlem tamamlanana kadar açık işlemlerin diğer işlemler tarafından görülmemesini sağlar, ardından tüm değişiklikler aynı anda tek bir birim olarak görünür hale gelir.
  • Tutarlılık (Consistency) – Tutarlılık, verilerde taahhüt edilen bir değişiklik olması durumunda, yeni bir işlemin değişikliği günler, saatler veya saniyeler önce yapılsa da görmesini sağlar; ve bir sunucu çökmesinden sonra veriler hatasız bir şekilde kurtarılabilir.
  • İzolasyon (Isolation) – PostgreSQL, veri değişikliklerinin diğer eşzamanlı işlemlerde görünürlüğünü kontrol etmek için çeşitli izolasyon seviyeleri sağlar. Varsayılan olarak, işlemlerin yalnızca diğer işlemler tarafından taahhüt edildikten sonra değişiklikleri görmesine izin veren bir okuma taahhüt düzeyi kullanılır.
  • Dayanıklılık (Durability) – Dayanıklılık, veritabanının taahhüt edilen tüm değişiklikleri takip edeceğinin garantisidir, bu nedenle anormal bir iptal olması durumunda veritabanı orijinal durumuna geri dönebilir veya işlem günlüklerini yeniden oynatarak kaldığı yerden devam edebilir.

İşlemler hakkında daha fazla bilgi için İşlemler bölümüne bakın. ACID uyumluluğu hakkında daha fazla bilgi için PostgreSQL topluluk belgelerindeki sözlüğe bakın.

Kilitleme (Locking)

PostgreSQL, birden çok işlemde çakışmaları önlemek amacıyla verilere eşzamanlı erişimi yönetmek için kilitleme mekanizmalarını kullanır. PostgreSQL iki tür kilit sağlar:

  • Paylaşılan kilitler (Shared locks) – Bunlar, birden fazla işlemin belirli bir veri nesnesini aynı anda okumasına izin verir.
  • Özel kilitler (Exclusive locks) – Bunlar, kilit serbest bırakılana kadar diğer işlemlerin veri nesnelerine erişmesini engeller.

PostgreSQL, kilitlerin belirli bir sırayla alındığı ve serbest bırakıldığı bir kilitleme protokolü kullanır. Bu, veritabanını, kaynak erişimi için kilitleri serbest bırakmak için birbirini beklerken iki veya daha fazla işlemin engellendiği bir durum olan kilitlenmelere karşı korumaya yardımcı olur. PostgreSQL aynı zamanda, tüm tablolar yerine tek tek satırlarda kilitlere izin veren ve eşzamanlı erişim üzerinde ayrıntılı kontrol sağlayan satır düzeyinde kilitlemeyi de destekler. Son olarak PostgreSQL, genel kilit yükünü azaltmak için tek bir nesnedeki çok sayıda kilidin tek bir üst düzey kilitle değiştirilebildiği kilit yükseltmeyi uygular.

Kilitleme hakkında daha fazla bilgi için Açık Kilitleme‘ye bakın.

VACUUM

PostgreSQL, veri satırlarını demet (tuple) olarak bilinen bir yapıda depolar. Demetler mantıksal olarak güncellendiğinde veya silindiğinde, görünmez bir sürüm hala veritabanındadır. Demetler, silme veya güncelleme komutuyla eşzamanlı olarak çalışan işlemlerin, işlemin başladığı andan itibaren veritabanının bir anlık görüntüsüyle tamamlanabilmesini sağlamak için korunur. PostgreSQL, eski görünmez demet sürümleri tarafından kullanılan alanı boşaltmak ve depolamayı geri kazanmak için bir VACUUM işlemi kullanır. Bu güncellenen ve silinen satırlar, daha sonra VACUUM işlemi tarafından temizlenmek üzere ölü demetler olarak işaretlenir. Hemen temizlenmezler çünkü farklı işlemler aynı grupla aynı anda çalışabilir ve Çoklu Sürüm Eşzamanlılık Denetimi (Multi-Version Concurrency Control – MVCC) aracılığıyla doğruluk sağlar. Örneğin, orijinal sürüm hemen kaldırılırsa, aynı anda çalışan işlemler doğru şekilde geri alınmaz. Basitçe VACCUUM’u çalıştırmak ölü demetleri kaldırsa da, VACCUUM komutunun anlaşılması gereken ve bu bölümde tartışacağımız başka varyasyonları da vardır.

VACUUM ANALYZE

Bu komut ölü satırları kaldırır ve o tablonun içeriği hakkında veri tabanı istatistiklerini toplar (bu istatistikleri pg_statistic sistem kataloğunda saklar). Bu veriler daha sonra, sorgu çalışma zamanında en verimli sorgu çalıştırma planlarının belirlenmesine yardımcı olmak için PostgreSQL sorgu iyileştirici tarafından kullanılır.

VACUUM FREEZE

Ölü satırları temizlemeye ek olarak, bu seçenek demetleri agresif bir şekilde dondurur. Bunu VACUUM’un eski satırları dondurmak, tüm kullanıcılara görünür kılmak veya silmek için karar vermek için kullandığı kesim yaşını (XID işlemlerinde) belirterek yapar. Bu, VACUUM işlemi sırasında eski etkin demetlerin veri kaybını ve işlem “wraparound” bozulmasını önler. İşlemler, benzersiz XID’leri tarafından izlenir ve sabit bir sayı olduğu için tükenebilir. Düzgün izlenmezse, bir üretim veri tabanının XID numaraları kaydedilebilecek üst sınıra ulaşabilir ve geçmiş TID numaralarının artık mevcut olduğu ve yeniden kullanılabileceği yerlerde “wraparound” gerçekleşir. Bu kapsamlı bozulma, veri bütünlüğünü korumak için veritabanının kapanmasına neden olabilir.

VACUUM FULL

Bu seçenek, içeriğini tamamen yeniden yazarak bir tablodan (veya veritabanından) ölü demetleri kaldırır. Verileri fiziksel olarak yeniden düzenleyerek daha kapsamlı bir temizlik gerçekleştirerek silinen ve güncellenen demetlerden disk alanını geri kazanır, bu da daha fazla sıkıştırılmış depolama ve iyileştirilmiş sorgu performansı sağlar. Bu seçenek, tabloya karşı özel bir kilit oluşturarak işlem tamamlanana kadar diğer tüm erişimi engellediğinden, olağan üretim koşullarında kullanılmamalıdır.

PostgreSQL zaman aşımı ile ilgili parametreler

Zaman aşımı ayarları bir zorunluluktur çünkü kıyaslama sırasında iş yüklerinin nasıl davranacağını tahmin edebilsek de, üretim iş yükleri bazen beklenmedik şekilde davranır. Zaman aşımı ayarlarının düzgün şekilde yapılandırılması, kümenizi iş yükünüzün akışındaki anormalliklerden korumak için bir önlem görevi görür. Bu ayarlar, veritabanı yaşam döngünüz boyunca değiştirilebilir ve değiştirilmelidir. Bağlantı için ayarlara sahip olmak ve zaman aşımları talep etmek iyi bir uygulamadır. PostgreSQL için RDS veritabanları yararlı varsayılan ayarlara sahiptir; ancak farklı ayarların performansı artıracağını belirlerseniz, üretime uygulamadan önce ayarları birer birer değiştirin ve test edin.

PostgreSQL veritabanı zaman aşımı ayarları, ifade, kullanıcı veya veritabanı düzeyinde olabilir. Uygulama geliştiricisinin bu zaman aşımı parametrelerini ve zaman aşımı hatalarını önlemek için nasıl çalıştıklarını anlaması yararlıdır. Aşağıda, uygulama performansının ve kullanıcı deneyiminin zaman aşımı hatalarından olumsuz etkilenmemesi için ayarlayabileceğiniz zaman aşımlarıyla ilgili bazı parametreler verilmiştir:

  • statement_timeout – Bir sorgudaki ifadenin zaman aşımına uğramasından önceki milisaniye sayısı. Varsayılan, zaman aşımı olmamasıdır.
  • idle_in_transaction_session_timeout – Bu parametre, belirtilen süreden daha uzun süre boşta kalan açık bir işlemle herhangi bir oturumu kapatır. Bu, bağlantı yuvasının yeniden kullanılabilmesi için o oturum tarafından tutulan tüm kilitleri serbest bırakır; ayrıca şişkinliği azaltmak için yalnızca bu işlem tarafından görülebilen demetlerin vakumlanmasına izin verir. Varsayılan değer (0) devre dışıdır.
  • idle_session_timeout – PostgreSQL 14 ve sonraki sürümlerinde, idle_session_timeout parametresini kullanabilirsiniz. Belirtilen süreden daha uzun süre boşta kalan ancak açık bir işlemin dışında kalan tüm oturumlar kapatılır. Varsayılan değer (0ms) devre dışıdır. 13 ve önceki sürümler için idle_in_transaction_session_timeout parametresi kullanıldı ancak açık bir oturumdaki tüm işlemleri durdururdu.
  • client_connection_check_interval – PostgreSQL sürüm 14 ve sonrasında client_connection_check_interval parametresini kullanabilirsiniz. Bu parametre ile, sorguları çalıştırırken istemci bağlantıları için isteğe bağlı kontroller arasındaki zaman aralığını ayarlayabilirsiniz. Bu kontrol, çekirdek bağlantının kapatıldığını bildirirse, uzun süren sorguların daha erken sona ermesini sağlar. Varsayılan değer (0ms) devre dışıdır. 13 ve önceki sürümler için, sunucu, sorgu tamamlanana kadar ölü bağlantıları algılamazdı ve bu, bağlantı beklenmedik bir şekilde kapanırsa sonuçların istemciye geri gönderilememesine neden olurdu.

Veritabanı davranışı ve en iyi uygulamaları etrafında PostgreSQL özellikleri

PostgreSQL, kanıtlanmış veri bütünlüğü, güvenilirliği ve genişletilebilirliği ile güçlü, nesne-ilişkisel bir veritabanı sistemidir. Performanslı ve yenilikçi veritabanı çözümleri sunabilen güçlü bir mimariye sahiptir. PostgreSQL, uygulama geliştiricinin ücretsiz, açık kaynaklı, genişletilebilir bir ortamda operasyonel hataya dayanıklı uygulamalar oluşturmasına yardımcı olacak birçok özelliğe sahiptir. Geliştiriciler, veritabanını yeniden derlemek zorunda kalmadan özel işlevler oluşturabilir ve farklı programlama dillerinden kod kullanabilir. Bu bölümde, veritabanı davranışıyla ilgili birkaç özelliği ve bazı en iyi uygulamaları tartışacağız.

AUTOCOMMIT

PostgreSQL, ACID uyumluluğu nedeniyle işlemlerin açıkça taahhüt edilmesini gerektirir. Bu konuda yardımcı olacak özelliklerden biri, işlemleri otomatik olarak veritabanına kaydeden AUTOCOMMIT‘tir. AUTOCOMMIT, her ifadenin bir işlemde çalıştığı ve her ifadenin otomatik olarak kaydedildiği yerdir. Varsayılan değeri ON‘dur (açık), yani onu çalıştırmak için özellikle BEGIN veya COMMIT komutunu vermeniz gerekmez. İşlemler BEGIN ile başlar ve bir COMMIT komutuyla biter ve taahhüt, kullanıcı değişikliklerini kaydeder. AUTOCOMMIT OFF (kapalı) olarak ayarlandığında, BEGIN komutu gerekmez, ancak değişikliklerin veritabanında geçerli olması için COMMIT komutunun ifadenin sonunda açıkça yazılması gerekir.

AUTOCOMMIT varsayılan ayarı çoğu ortamda kullanışlıdır ve değiştirilmesi gerekmez. Örneğin, satırları toplu yüklemek için \COPY komutu kullanılırken AUTOCOMMIT‘in devre dışı bırakılması gerekmez. 100 satırlık bir AUTOCOMMIT toplu girişi ile daha iyi performans elde edebilirsiniz (örneğin, INSERTVALUES (...), (...), (...), (...), 100 ayrı INSERT deyiminden oluşan tek bir COMMIT ile karşılaştırıldığında BEGIN; INSERTINSERTINSERT …), çünkü bireysel BEGIN ve COMMIT komutları önemli disk etkinliği ve CPU kullanır. Ancak, belirli koşullar altında ayarın kapatılması daha iyi bir çalışma deneyimi sağlayabilir. Bir ekleme başarısız olursa, iş gereksinimlerine bağlı olarak sorunlu olabilecek istenmeyen kısmi veri yüklemelerini önlemek için tüm satırlar geri alınır.

Bu özellik, kazara WHERE yan tümcesi olmadan DELETE deyimi çalıştırmak gibi hatalardan hızlı bir şekilde kurtulmaya olanak sağladığı için uygulama geliştiricileri için faydalı olabilir. AUTOCOMMIT‘i kapalı bırakmak istiyorsanız, iş yükünüzün belirli yönleri için bu ayarı oturum seviyesinde değiştirmek en iyisidir. AUTOCOMMIT kapalıyken bir ifade verilirse ve bir COMMIT komutu verilmezse, bu gönderide daha önce açıklandığı gibi, PostgreSQL bir COMMIT verilene kadar kilitleri tuttuğu için sonraki ifade kilitlenir.

Aşağıdakiler, AUTOCOMMIT‘i kullanmak için en iyi uygulamalardır:

  • AUTOCOMMIT‘i genel olarak açık bırakın ve yalnızca bunu yapmak için ticari nedenleriniz varsa devre dışı bırakın. Aşağıdakilere dikkat edin:
    • AUTOCOMMIT açıkken, sorgular birlikte gruplandırılmaz.
    • AUTOCOMMIT dolaylı olarak yayınlandığı için, hangi sorgunun işlendiği veya geri alındığı konusunda herhangi bir belirsizlik yoktur.
    • PostgreSQL’deki AUTOCOMMIT‘in etrafında üstü kapalı bir BEGIN ve COMMIT vardır, çoğu zaman işlem bloğu olarak adlandırılır ve COMMIT komutu gereksizdir.
    • AUTOCOMMIT‘in açık olması, her SQL ifadesinin otomatik olarak kaydedildiğini ve AUTOCOMMIT off (kapalı) olmadığı sürece geri almanın mümkün olmadığını garanti eder.
  • AUTOCOMMIT‘i devre dışı bırakırken bunu yalnızca oturum düzeyinde yapın. Aşağıdakilere dikkat edin:
    • Devre dışı bırakıldığında, veritabanı her zaman işlem modundadır ve açıkça bir COMMIT veya ROLLBACK komutuyla bitmelidir.
    • AUTOCOMMIT kapalıyken, bir hata yapılırsa, geri alma yapmak kolaydır ve her şey geri alınır. Bu, değişiklikler veritabanında kalıcı olmadığı için hatalardan hızlı ve kolay bir şekilde kurtulmanıza olanak tanır.

AUTOVACUUM

VACUUM ölü demetleri temizleyen manuel bir işlemdir, AUTOVACUUM ise silinmiş ve daha eski güncellenmiş demetlerin kaldırılmasını otomatikleştiren periyodik bir arka plan yardımcı programıdır. Autovacuum varsayılan olarak etkindir ve veritabanına verilen çok sayıda UPDATE ve DELETE komutu varsa parametrelerinin test edilmesi ve ayarlanması gerekir. PostgreSQL, MVCC modelini kullanır ve eşzamanlı okuma isteklerinin tamamlanmasına izin vermek için eski satır sürümlerini tutar. Bu ifadeler sırasında satırlar silinmez ve işlem bitene kadar eski hali korunur. Bir COMMIT komutu verilmezse, işlem teknik olarak hala devam ettiği için AUTOVACUUM bu satırları silemez ve satıra hala ihtiyaç duyulabilir. Otomatik taahhüdün devre dışı bırakılmasından kaynaklanan bazı örnek sorunlar, veritabanındaki kilitler ve AUTOVACUUM bakım engelidir.

AUTOVACUUM’u devre dışı bırakmanın bir sonucu, tablo şişmesine yol açan ölü demetlerin çıkarılmamasıdır. Bu istenmeyen bir durumdur çünkü veritabanı şişkinliği, tablolarınız ve dizinleriniz tarafından genel disk kullanımında bir artışa yol açarak, sorgu çalışma sürelerinin artmasına neden olarak ölü demetlere ve tablolarınızdan veya dizinlerinizden sorguları çalıştırmak için okunacak etkin görünür satırlara yol açar. AUTOVACUUM’un ölü demetleri otomatik olarak kaldırması yerine, özellikle VACUUM FULL komutu çağrılarak fiziksel olarak kaldırılmaları gerekebilir.

Aşağıdakiler AUTOVACUUM için en iyi uygulamalardır:

  • Tuple düzeyinde istatistikler için pgstattuple uzantısını kullanarak düzenli olarak şişkinlik tahmini raporları gerçekleştirerek AUTOVACUUM’un çalıştığından emin olun. Aşağıdakilere dikkat edin:
    • Şişme, artan disk tüketimine ve performans kaybına neden olur ve düzenli olarak yönetilip azaltılmazsa, ilgili verilerin sorgularının iki kat daha uzun (veya daha uzun) sürmesine neden olur. AUTOVACUUM, düzgün bir şekilde yapılandırıldığında, zaman içinde veritabanı şişmesini en aza indirmeye yardımcı olabilir.
    • Veritabanı şişkinliğinin çoğalmasını önlemek amacıyla AUTOVACUUM’un yeterince sık çalışmasını sağlamak için autovacuum_naptime parametresini uygun şekilde ayarlayın.
    • Yazma ağırlıklı iş yüklerinin yanında çalışan uzun süreli sorgulardan kaçının. AUTOVACUUM tablo üzerinde zayıf kilitler oluşturduğundan, sunucuda çalışan iş yüklerini tam olarak anladığınızdan emin olun. INSERT, UPDATE ve DELETE gibi normal veritabanı işlemleri devam edebilir, ancak dizinler ve tablonun kırpılması üzerinde etkisi vardır.
  • AUTOVACUUM ayarlarını tablo kullanımına ve erişim modellerine göre yapın. Aşağıdakilere dikkat edin:
    • Ağır DELETE ve INSERT ifadeleri içeren tablolarda belirtilen VACUUM parametrelerinden tablo AUTOVACUUM eşiklerini test edin ve ayarlayın.
    • Veritabanı üzerinde çok az etki yaratmak için AUTOVACUUM’u yoğun olmayan zamanlarda nasıl ve ne zaman çalıştıracağınıza ilişkin en iyi stratejileri planlayın ve test edin. Ayrıca kilitlerle üretim sistemi iş yüklerini aksatmamak için yoğun zamanlarda nasıl çalıştırılacağını belirleyin.
    • AUTOVACUUM’u düzenli kullanmamaya dikkat edin; sistemlerin vakum çalışmaları arasında çok meşgul olma ve yetişmek zorunda kalma veya VACUUM FULL kullanmak zorunda kalma riskiyle karşı karşıya kalabilirsiniz.

Idle in transaction

PostgreSQL bağlantılarını izlemek önemli bir görevdir çünkü bağlantı durumundaki değişiklikler bir hatanın nasıl giderileceği konusunda bir başlangıç noktası olabilir. PostgreSQL, bir işlemin veya ifadenin içinde olabileceği dört ana duruma sahiptir:

  • active – Açık olan ve sorguları çalıştıran bir bağlantı
  • idle – Boşta olan ve sorguları çalıştırmayan, ancak bellek ve CPU gibi sunucu kaynaklarını tüketen ve kötü performansın yaygın nedeni olan bir bağlantı
  • idle_in_transaction – Arka ucu işlemde olan ancak boşta olan ve şu anda girdi bekleyen bir bağlantı
  • idle_in_transaction (aborted)idle_in_transaction‘a benzer, ancak işlemdeki ifade bir hataya neden olmuştur

Açık işlemler kilitleri tutabilir, diğer sorguları bloke edebilir ve AUTOVACUUM ve VACUUM performansını engelleyerek tabloların şişmesine neden olabilir. Performans sorunlarına neden olan ve genellikle tanımlanması zor olan önemli bir durum da idle_in_transaction‘dır. Veritabanı bir BEGIN komutu yayınladığında, bir tablo veya tablolar üzerinde kilitler aldığında ve kullanıcı girdisini beklediğinde ancak herhangi bir nedenle COMMIT veya ROLLBACK komutunu yayınlamadığında sorgu idle_in_transaction‘dır. İşlemde boşta olan bağlantılar askıya alınır ve bu durumda sonsuza kadar kalabilir çünkü PostgreSQL neden beklediğini bilmez ve işlem dizisini tüketirken işlemi otomatik olarak durdurmaz. Sürecin beklemesine neden olabilecek iyi iş nedenleri olabileceğinden, bu durum otomatik olarak çözümlenmeyecektir. Örneğin, bir belgenin okunması zaman alıyor veya e-posta gönderip almak için belirli bir iş günü beklemek gerekiyordur. idle_in_transaction‘ı ortadan kaldırmak için, neden verildiklerini belirlemek üzere veritabanı kilitlerinin anlaşılması gerekir ve uygulama, karşılaşıldığında bununla nasıl başa çıkacağını bilmelidir.

idle_in_transaction‘ın çoğaltılması kolaydır. İlk olarak, bir tablo oluşturun ve verileri ekleyin. Ardından BEGIN girerek bir ifade başlatın. İfade başladıktan sonra, bir taahhüt veya geri alma ile bitirmeden başka bir sütun ekleyerek tabloyu değiştirin. Bu eylem, işlem kilidinde bir boşta kalmaya neden olacaktır çünkü birinci bitiş olmadan ikinci bir ifade başlamıştır.

idle_in_transaction‘ı bir psql oturumunda çoğaltmak için aşağıdaki kodu çalıştırın:

CREATE TABLE mydbtable (
id int GENERATED BY DEFAULT AS IDENTITY,
username varchar (50),
password varchar (50)
);
BEGIN;
alter table mytable add column last_update timestamp;
SQL

Başka bir psql sekmesi açın ve aşağıdaki kodu çalıştırın:

SELECT * FROM mydbtable;
SQL

Tabloda kilit olduğu için hiçbir şey olmuyordur. Kilidi serbest bırakmak için ilk oturuma geri dönün ve bir taahhüt veya geri alma çalıştırın:

COMMIT;
SQL

Komut çalıştırıldıktan sonra ikinci oturum hemen tamamlanır. Kilitler, bir taahhüt veya geri alma gerçekleşene kadar her zaman tutulur.

Aşağıda, idle_in_transaction oturumlarını yönetmek için en iyi uygulamalar yer almaktadır:

  • Şu anda idle_in_transaction olan sorguları bulmak için pg_stat_activity tablosunu sorgulayın. Bu tablo ve kullanımı hakkında daha fazla bilgi için pg_stat_activity‘ye bakın.
  • idle_in_transaction‘dan kaçınmak için işlemleri daha küçük ve daha yönetilebilir parçalara bölün. Aşağıdakilere dikkat edin:
    • Sorguları, oturum başına veya veritabanı başına ayarda belirli bir süreden daha uzun süre çalışmayacak şekilde hazırlayın.
    • Uzun süren işlemleri tespit etmek için zaman aşımı günlüklerini düzenli olarak kontrol edin.
    • Uzun süren işlemlerin iptal edilebilmesi için idle_in_transaction_session_timeout parametresini ayarlamayı düşünün. Varsayılan değer 0’dır, yani zaman aşımı yoktur.
    • Uzun süredir devam eden sorguları ve ne kadar süredir bu durumda olduğunu kontrol etmek için pg_stat_activity kullanın.
  • Uzun süre çalışan saklı yordamları veya işlevleri veritabanı katmanından uygulama katmanına taşıyın. Aşağıdakilere dikkat edin:
    • Hatalar, uygulamada kodlanmış hata işleme mantığı ile işlenebilir.
    • Sorgu sonuçlarını işlemeden önce işlemleri kapatmak için uygulamaları kodlayın.
    • Gereksiz hatalardan kaçınmak için uygulama ve veritabanı katmanında AUTOCOMMIT‘in açık olduğundan emin olun.
    • idle_in_transaction işlemleri için pg_stat_activity parametresini kullanarak tabloları izleyerek, idle_in_transaction oturumlarının VACUUM ve diğer sorguların tablolara erişmesini engellemediğinden emin olun. Bu, tüm açık işlemleri ve durumlarını listeleyecektir.

Sonuç

Bu gönderide, uygulama mimarinize rehberlik etmeye yardımcı olacak en iyi uygulamalarla birlikte, PostgreSQL motorunun temel PostgreSQL işlevlerini ve ayrıntılı belirli özelliklerini tanımladık. Amazon RDS for PostgreSQL ve Aurora PostgreSQL-Compatible için uygulama tasarımı sırasında veritabanı tasarımı ve parametre ayarlarını göz önünde bulundurmak, veri tabanı performansındaki maliyetli ve elverişsiz kesintilerin önlenmesine yardımcı olurken aşağı yöndeki yük kesintilerini azaltır. Bu gönderi, bu konularda kapsamlı bir kaynak olmasa da, uygulama geliştiricisi için ek PostgreSQL mimarisini ve ayarlama hususlarını tartışan takip gönderileri için bir başlangıç niteliğindedir.