MVCC ve Kilitler — Eski Satır Sürümleri Nerede Yaşar?
Önce şunu oku: İzolasyon Seviyeleri — Aynı İsim, Üç Farklı Davranış
30 saniyede özet
Biri bir satırı okurken başkası onu değiştiriyorsa iki yol var: ya okuyan bekler, ya da ona eski kopya gösterilir. Motorlar bu eski kopyaları farklı yerlerde saklar; uzun süren işler de her birinde başka bir sorun çıkarır.
Gece çalışan rapor bir gün dört saat sürdü. PostgreSQL’de ertesi sabah tablo diskte iki katına çıkmıştı. Oracle’daki kopyası ise raporu üçüncü saatte “snapshot too old” hatasıyla düşürmüştü.
-
Bayt: Gece raporu bir gün dört saat sürdü. Ertesi sabah tablo diskte iki katına çıkmıştı!
-
Sen: Rapor yalnızca okuyordu, değil mi?
-
Bayt: Evet, sadece okuyordu. Okumak nasıl disk doldurur ki?
-
Bayt: Biri belgeyi okurken başkası düzeltirse okuyan bekler mi, yoksa eski bir kopya mı alır?
Beklemek mi, eski kopya mı?
Bir transaction satırı güncelledi, henüz commit etmedi. Aynı satırı okumak isteyen sorgu SQL Server'ın varsayılan ayarında ve PostgreSQL'de ne yapar? Cevabı göster
SQL Server’da bekler, PostgreSQL’de beklemez. SQL Server’ın varsayılan READ COMMITTED’ı kilitle çalışır. PostgreSQL okuyana satırın commit edilmiş eski sürümünü gösterir.
Adım adım oku
- Kilit tabanlı modelde satır düzeltilirken okuyan, düzeltme commit edilene kadar bekler.
- MVCC'de okuyana satırın bir önceki sürümü hemen verilir; kimse beklemez.
- Eski sürümler, onları görebilecek bir okuma sürdükçe saklanmak zorundadır. Saatlerce açık kalan rapor, yığının büyümesine yol açar.
- Okuma bitince artık kimsenin görmediği sürümler temizlenir ve yer açılır.
Kilit modelinde veritabanı eski sürüm tutmaz; bedeli bekleme ve kilit zinciridir. Sürüm modelinde okuyan ve yazan birbirini beklemez; bedeli, eski sürümleri saklamak ve temizlemektir.
Kafam karıştı, daha basit anlat
Biri defteri güncelliyorken sen okumak istiyorsun. Kilit modelinde yazmasının bitmesini beklersin. Sürüm modelinde ise sana defterin bir önceki fotokopisini verirler.
Kilit tabanlı ve sürüm tabanlı (MVCC) eşzamanlılık arasındaki temel takas nedir?
Eski kopyalar nerede durur?
| Eski sürüm nerede | Kim temizler | Uzun sorgunun bedeli | |
|---|---|---|---|
| PostgreSQL | Tablonun içinde, ölü satır olarak | VACUUM | Tablo ve indeks şişer |
| Oracle | Undo | Süresi dolunca yeniden kullanılır | ORA-01555 snapshot too old |
| SQL Server (RCSI) | tempdb version store | Arka plan temizliği | tempdb büyür |
| SQL Server (varsayılan) | Tutulmaz | — | Okuyucular bekler |
PostgreSQL’de bir UPDATE, satırı yerinde değiştirmez; yeni bir sürüm yazar. Eskisini VACUUMPostgreSQL'in, hiçbir sorgunun artık göremeyeceği eski satır sürümlerini temizleyip alanı yeniden kullanılabilir yapan işlemi. Çoğunlukla autovacuum yürütür.Sözlükte gör → ancak hiçbir sorgu artık onu göremeyecekse siler.
Oracle satırı yerinde günceller ve eski değeri undoOracle'ın, güncellenen satırların eski değerlerini tuttuğu alan. Geri alma ve tutarlı okuma buradan yapılır; süresi dolan undo yeniden kullanılır.Sözlükte gör →’ya yazar. Uzun bir sorgu, çoktan başka işe verilmiş undo’ya ihtiyaç duyarsa hata alır.
Kafam karıştı, daha basit anlat
Eski fotokopiler bir yerde birikir. Kimse onlara bakmayacağı zaman temizlenirler. Uzun süre açık kalan bir iş, temizliği de bekletir.
PostgreSQL'de sık güncellenen bir tablonun boyutu, satır sayısı değişmediği hâlde sürekli büyüyor. En olası sebep hangisi?
Oracle'da üç saat süren bir rapor sonunda `ORA-01555: snapshot too old` veriyor. Ne oldu?
Kendin gör
Eski satır sürümleri nerede yaşar, bedelini kim öder?
Tohum 434438Oynat ya da adımla.
Saklanan eski sürümler
yok
Şu an ne oldu?
PostgreSQL: sıcak bir satır, iki güncelleme, bir okuyucu
Okuyucu, yazanı bekleyecek mi, eski bir sürümü mü görecek? Eski sürüm nerede duruyor?
Görevler0/3
Bir okuyucunun yazanı beklemesini sağlaaçık
İpucu
Eski sürüm tutmayan kurulum.
Uzun bir raporu ORA-01555 ile düşüraçık
İpucu
Undo, rapordan kısa ömürlü olsun.
PostgreSQL'de VACUUM'un eski sürümleri temizleyememesine yol açaçık
İpucu
Birinin hâlâ eski görüntüye ihtiyacı olsun.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. PostgreSQL, uzun rapor: rapor tutarlı, ama VACUUM iki sürümü temizleyemedi.
- Okuyanı “kısa” yap. Temizlik geride kalmadı.
- Oracle seç, undo’yu “kısa” yap. Rapor en sonda ORA-01555 ile düştü.
- SQL Server (varsayılan) seç. Okuyucu bekledi; uzun rapor iki farklı anı karıştırdı.
- RCSI’yi aç. Bekleme bitti, eski sürümler tempdb’ye taşındı.
Simülatörde SQL Server'ın varsayılan ayarında uzun rapor 'karışık zamanlı' oldu. Bu ne demek?
Uzun transaction’ı bul
Üç motorda da asıl düşman, açık kalan transaction’dır. Uygulama transaction açıp bir HTTP çağrısını beklerse, veritabanında idle in transaction bir oturum kalır.
- PostgreSQL:
pg_stat_activityiçindexact_starteski olan oturumlar;idle_in_transaction_session_timeoutayarı. - SQL Server:
sys.dm_exec_requestsiçindekiblocking_session_id; RCSI açıksasys.dm_tran_active_snapshot_database_transactions. - Oracle:
V$TRANSACTIONveV$UNDOSTAT.
Gel, bunu bir bankanın havale servisinde görelim. Her transferden önce dış bir servise “bu işlem şüpheli mi?” diye soruluyor; tek fark, bu soruyu transaction’dan önce mi sonra mı sorduğumuz.
Derinleş · Havale servisi: kısa transaction 4 dosya · ~69 satır · ilk okumada atlayabilirsin
Veritabanında sürekli 'idle in transaction' oturumlar görünüyor ve autovacuum geride kalıyor. Hatalı satır hangisi?
Tuzaklar
Transaction içinde dış çağrı. @Transactional metodun içinden ödeme servisini çağırmak, çağrı süresince bağlantıyı ve eski sürümleri rehin tutar.
Autovacuum’u kapatmak. Şişme durmaz, yalnızca temizlik durur.
Replikada uzun rapor. PostgreSQL’de hot_standby_feedback açıksa replikadaki uzun sorgu, ana sunucudaki VACUUM’u da geride tutar.
lock escalationSQL Server'ın, tek bir işlemin tuttuğu çok sayıda satır ya da sayfa kilidini daha az sayıda tablo kilidine çevirmesi. Bellek kazandırır, eşzamanlılığı azaltır.Sözlükte gör →. SQL Server çok sayıda satır kilidini tablo kilidine yükseltebilir; büyük bir toplu güncelleme bütün tabloyu kilitleyebilir.
PostgreSQL'de raporlar ana sunucuyu yormasın diye bir okuma replikasına taşındı ve `hot_standby_feedback` açıldı. Ana sunucuda şişme arttı. Neden?
SQL Server'da bir gece işi milyonlarca satırı tek bir UPDATE ile güncellerken tüm tablo diğer kullanıcılara kilitleniyor. Olası sebep ve tipik çözüm?
Kendini sına
MVCC'de okuyanlar yazanları, yazanlar da okuyanları beklemez.
Her belirtiyi ait olduğu motora yerleştir.
Aklında kalacak üç şey
- 1 Kilit modelinde okuyan yazanı bekler; sürüm modelinde okuyan eski bir kopyayı görür ve kimse beklemez. Sürüm modeli beklemek yerine yer ve temizlikle öder.
- 2 PostgreSQL eski kopyaları tabloda tutar ve VACUUM ile temizler; Oracle undo alanında tutar; RCSI açık SQL Server tempdb'de tutar.
- 3 Uzun süren transaction'lar sürüm modelinde temizliği durdurur, Oracle'da 'snapshot too old' hatasına, kilit modelinde bekleme zincirlerine yol açar.
5 kart sonraki derste seni bekliyor
Bu dersin üstüne kurulanlar
Bunlar bu dersi temel alıyor; hazır olduğunda devam edebilirsin.
- VeritabanlarıReplikasyon ve Okuma Replikaları — Yazdım Ama GöremiyorumProfilini güncelledin, sayfayı yeniledin ve eski hâli karşına çıktı. Hangi kopyaya baktın?Derse git
- VeritabanlarıKesintisiz Şema Değişikliği — Genişlet, Taşı, DaraltSütunun adını değiştirdin; yeni sürüm yayılırken eski pod'lar hata vermeye başladı. Neden?Derse git
- VeritabanlarıBağlantı Havuzu — Büyük Havuz Hızlı Havuz DeğildirBağlantı havuzunu büyüttün ve sistem daha da yavaşladı. Nasıl olur?Derse git
- VeritabanlarıTablo Bölümleme — Eski Yılı Silmek Neden Bütün Geceyi Aldı?Saklama süresi dolan bir yıllık hareketi silmek için gece bir DELETE çalıştırıldı. Sabah iş hâlâ bitmemişti ve tablo küçülmemişti. Ne oldu?Derse git