DBAtlas · Veritabanı operasyon atlası

Uzun süren / açık kalan transaction

Uzun süren ya da açık kalan bir transaction lock, undo ve bloat biriktiriyor. Suçlu transaction'ı bulup türünü (idle-in-transaction, uzun batch, etki) belirleyip güvenle çözüyoruz.

En eski açık transaction hangisi?

Açık transaction'ları başlangıç zamanına göre listele. En eski olan genellikle sorunun kaynağıdır. Durumuna bak: aktif mi çalışıyor, yoksa 'idle in transaction' olarak commit bekliyor mu?

SELECT s.sid, s.serial#, s.username, s.status, t.start_time, t.used_ublk*8/1024 AS undo_mb
FROM v$transaction t JOIN v$session s ON s.taddr=t.addr
ORDER BY t.start_time;
  • idle-in-transaction (commit unutulmuş, boşta bekliyor)
  • Aktif ama çok uzun süren batch/DML
  • Transaction devam ederken lock/bloat/undo biriktiriyor

idle-in-transaction neden oluşuyor?

Oturum bir transaction açmış ama sorgu çalıştırmadan boşta bekliyor; yani commit/rollback unutulmuş. Bu, lock'ları ve undo'yu gereksiz yere tutar. Uygulama düzeltmesi mi yeterli, yoksa acilen sonlandırmak mı gerekiyor?

SELECT pid, now()-state_change AS idle_age, left(query,80) AS last_query
FROM pg_stat_activity WHERE state='idle in transaction' ORDER BY state_change;
  • Uygulama/bağlantı havuzu commit yapmıyor (kalıcı düzeltme)
  • Hemen sonlandırmam gerekiyor

Aktif uzun işlem ne yapıyor?

Oturum gerçekten çalışıyor (aktif). Tek devasa bir DML/rapor mu, yoksa başka oturumları bekleten ve acil kesilmesi gereken bir bloklayıcı mı?

SELECT s.sid, s.serial#, sq.sql_text, s.last_call_et AS running_secs
FROM v$session s JOIN v$sql sq ON sq.sql_id=s.sql_id
WHERE s.status='ACTIVE' AND s.type='USER' ORDER BY s.last_call_et DESC;
  • Tek dev DML/rapor — parçalamak gerek
  • Başkalarını bekletiyor, acil sonlandır

Uzun işlem neyi biriktiriyor?

Uzun transaction'ın yan etkisini belirle: başka oturumları bekleten lock birikimi mi baskın, yoksa eski satır sürümlerini tutup temizliği (VACUUM/undo) engelleyen bloat mı?

SELECT pid, pg_blocking_pids(pid) AS blocked_by FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid))>0;
SELECT max(age(backend_xmin)) AS max_xmin_age FROM pg_stat_activity WHERE backend_xmin IS NOT NULL;
  • Lock birikimi diğer oturumları bekletiyor
  • Eski sürüm birikimi temizliği engelliyor (undo/bloat)

Kök neden: Uygulama commit yapmıyor (idle-in-transaction)

Bağlantı havuzu ya da uygulama, transaction'ı açtıktan sonra commit/rollback yapmadan bağlantıyı boşta tutuyor. Bu lock'ları ve undo'yu gereksiz tutar.

Çözüm: Suçlu oturumu güvenle sonlandır

Engelleyici/uzun oturum başkalarını bekletiyorsa kontrollü biçimde sonlandırmak gerekir. Sonlandırma rollback tetikler; bu da alan/zaman gerektirebilir, dikkatli ol.

Kök neden: Tek dev DML/rapor

Milyonlarca satırı tek transaction'da işleyen bir DML ya da çok uzun rapor, süresi boyunca lock ve undo/bloat biriktirir.

Kök neden: Lock birikimi kuyruğu

Uzun transaction tuttuğu lock'lar yüzünden arkasında bir bekleme kuyruğu oluşturmuş; birçok oturum aynı kaynağı bekliyor.

Kök neden: Eski sürüm birikimi (undo/bloat)

Uzun süren işlem, kendisinden önceki eski satır sürümlerinin temizlenmesini engelliyor. Postgres'te bu tablo/index bloat'ı, Oracle'da undo baskısı olarak görünür.

DBAtlas'ta aç →