MSSQL Server’da PAGELATCH Bekleme Tipi

SQL Server performans tuning dünyasında PAGELATCH, en çok karıştırılan ama çözümü en standart olan bekleme tiplerinden biridir. Sorunu çözmek için önce “Latch” kavramını bir “Trafik Polisi” gibi düşünerek anlamak gerekir.

Latch, SQL Server’ın bellekteki (Memory/Buffer Pool) veri yapılarını korumak için kullandığı çok kısa süreli, hafif bir kilitleme mekanizmasıdır.

  • Lock (Kilit) ile Farkı: Lock’lar (X, S kilitleri gibi) veritabanındaki veriyi (satır, tablo) korur ve işlem (transaction) bitene kadar sürebilir. Latch ise sadece bellekteki sayfanın fiziksel bütünlüğünü korur ve milisaniyeler hatta mikro saniyeler sürer.
  • Örnek: İki kişi aynı anda bir kağıda (Data Page) yazı yazmaya çalışırsa kağıt yırtılır. Latch, bir kişi yazarken diğerinin elini tutmasını sağlar. Yazma bitince elini bırakır.

PAGELATCH, diskteki veride değil, belleğe (Buffer Pool) çekilmiş olan bir veri sayfasında çekişme (contention) olduğunu gösterir.

Önemli Ayrım:

  • PAGEIOLATCH: Veri diskten belleğe okunurken bekliyorsanız (Sorun Disktedir).
  • PAGELATCH: Veri zaten bellektedir ama o sayfaya aynı anda çok fazla thread erişmeye çalışıyordur (Sorun Bellek İçi Çekişmedir).

Bu bekleme tipi genellikle 3 ana senaryoda karşımıza çıkar. Çözüm, hangi alt tipin (Sub-type) baskın olduğuna göre değişir:

A. PAGELATCH_EX (Exclusive – Yazma Çekişmesi)

En yaygın görülen durumdur. Genellikle “Last-Page Insert” sorunudur.

  • Tablonuzda IDENTITY veya Sequential (sıralı) bir Primary Key varsa, tüm yeni kayıtlar tablonun en sonundaki sayfaya yazılmaya çalışılır. 100 tane thread aynı anda son sayfaya veri eklemek isteyince birbirlerini beklerler.
  • Çözüm:
    • In-Memory OLTP: Eğer SQL sürümünüz uygunsa tabloyu In-Memory’ye taşıyın (Latch mekanizması yoktur).
    • Hash Index: Primary Key’i sıralı olmayan (Non-sequential) bir GUID veya Hash tabanlı bir yapıya çevirin (Veriyi farklı sayfalara dağıtır).
    • Sürüm Güncelleme: SQL Server 2019+ kullanıyorsanız, OPTIMIZE_FOR_SEQUENTIAL_KEY = ON seçeneğini index tanımına ekleyin.

B. PAGELATCH_SH (Shared – Okuma Çekişmesi)

Çok fazla thread aynı sayfayı okumaya çalışıyordur.

  • Genellikle çok sık erişilen “Hot Page” (Sıcak Sayfa) durumudur. Örneğin, sürekli sorgulanan çok küçük bir referans tablosu.
  • Sorguları optimize ederek sayfa okuma sayısını (Logical Reads) düşürün veya tabloyu partition’lara bölerek yükü dağıtın.

C. TempDB Üzerindeki PAGELATCH (Sistem Sayfası Çekişmesi)

Eğer beklenen kaynak 2:1:1 veya 2:1:2 gibi (Database ID 2 olan TempDB) görünüyorsa:

  • Çok fazla geçici tablo (#temp) oluşturuluyordur ve SQL Server bu tabloları oluşturmak için sistem sayfalarına (PFS, GAM, SGAM) yazmaya çalışırken takılıyordur.
  • Çözüm:
    • Data File Sayısı: TempDB veri dosyası sayısını işlemci çekirdek sayısına (maksimum 8’e kadar) eşitleyin.
    • Trace Flag: Eski sürümlerde TF 1118 ve TF 1117’yi aktif edin (SQL 2016+ sürümlerinde bu default gelir).

Özet

Bekleme TipiLokasyonOlası Nedenİlk Müdahale
PAGELATCH_EXKullanıcı TablosuIDENTITY sütunu çekişmesi.OPTIMIZE_FOR_SEQUENTIAL_KEY
PAGELATCH_UPKullanıcı TablosuSayfa bölünmesi (Page Split).Fill Factor ayarını kontrol et.
PAGELATCH_XXDatabase ID: 2TempDB sistem sayfası yükü.TempDB dosya sayısını artır.

PFS (Page Free Space), GAM (Global Allocation Map) ve SGAM (Shared Global Allocation Map) gibi sistem sayfaları sadece TempDB’de değil, tüm kullanıcı veritabanlarında mevcuttur.

Ancak, kullanıcı veritabanlarında PAGELATCH (sistem sayfası bazlı) beklemesini TempDB kadar sık görmememizin temel nedeni, TempDB’nin saniyede binlerce kez nesne yaratıp sildiği (Temp table, Worktable vb.) çok daha dinamik bir yapı olmasıdır.

Yine de yoğun INSERT/UPDATE alan bir kullanıcı veritabanında bu sistem sayfaları üzerinde bir darboğaz oluşabilir.

Bir veritabanında yeni bir alan tahsis edileceği (allocation) zaman SQL Server şu dosyalara bakmak zorundadır:

  • PFS: Hangi sayfalarda boş yer var?
  • GAM/SGAM: Hangi “extent”ler boşta?

Eğer yüzlerce session aynı anda yeni satırlar eklemeye çalışıyorsa, hepsi aynı PFS sayfasına “Benim için boş yer bul ve orayı dolu olarak işaretle” diye saldırır. Bu da PAGELATCH beklemesine neden olur.

Eğer çekişme (contention) kullanıcı veritabanındaki sistem sayfalarındaysa (örneğin 5:1:1 -> DB_ID 5, File 1, Page 1 olan PFS sayfası), şu stratejiler izlenir:

A. Veri Dosyası Sayısını Artırın (File Group Expansion)

TempDB’de yaptığımız çözümün aynısıdır.

  • SQL Server her veri dosyası için ayrı bir PFS, GAM ve SGAM sayfası oluşturur.
  • Mevcut PRIMARY veya ilgili Filegroup içine çekirdek sayınıza uygun (genellikle 4 veya 8) eşit boyutta yeni veri dosyaları (NDF) ekleyin. Bu sayede “Round Robin” algoritması ile yük farklı dosyalardaki farklı sistem sayfalarına dağılır.

B. Otomatik Büyüme (Autogrow) Ayarlarını Kontrol Edin

  • Eğer dosyalarınız çok küçükse ve sık sık otomatik büyüme tetikleniyorsa, SQL Server sürekli yeni alan tahsis etmek zorunda kalır.
  • Çözüm: Dosyaları önceden yeterli büyüklükte (Pre-allocate) açın ve büyüme oranlarını (Growth) sabit bir MB değerine (örneğin 256MB veya 512MB) ayarlayın.

C. Delayed Durability (Gecikmeli Dayanıklılık)

Eğer sisteminiz çok yüksek trafikli ama veri kaybı (birkaç milisaniyelik) kabul edilebilir durumdaysa:

  • SET DELAYED_DURABILITY = FORCED; komutu ile sistem sayfalarındaki yükü ve log yazma baskısını bir miktar hafifletebilirsiniz.

D. Tablo Tasarımı (Page Splits)

  • Rastgele (GUID) anahtarlar kullanılıyorsa, veriler sayfanın ortasına girmeye çalışır ve “Page Split” (Sayfa Bölünmesi) yaratır. Bu da sürekli yeni sayfa tahsisi demektir.
  • FILLFACTOR değerini %80-%90 civarına çekerek sayfalarda boş yer bırakın. Böylece sistem sayfalarıyla olan iletişim sıklığı azalır.

Darboğazın hangi sayfada olduğu nasıl anlaşılır:

Bekleme yapan kaynağı (Resource Description) kontrol ettiğinizde sayfa numaraları size suçluyu söyler:

Sayfa NumarasıSayfa TipiGörevi
1 (örn: 5:1:1)PFSBoş alan yönetimi. En sık çekişme buradadır.
2 (örn: 5:1:2)GAMExtent bazlı boş alan yönetimi.
3 (örn: 5:1:3)SGAMKarma (Mixed) extent yönetimi.

Eğer kullanıcı veritabanınızda sistem sayfaları üzerinde PAGELATCH görüyorsanız, dosya sayısını artırmak ve dosya büyüme ayarlarını optimize etmek en etkili ilaçtır.

Not: SQL Server’da her bir data file (MDF/NDF) kendi içerisinde File Header Page, PFS (Page Free Space), GAM (Global Allocation Map), SGAM (Shared Global Allocation Map), IAM (Index Allocation Map), Differential Change Map ve Bulk Changed Map gibi sistem sayfalarını barındırır. Buffer Pool üzerinde bulunan data page’ler üzerinde herhangi bir INSERT, UPDATE veya DELETE işlemi yapıldığında, bu işlemlere bağlı olarak sayfa ve extent tahsis bilgileri değiştiği için ilgili data file içerisinde bulunan PFS, GAM ve SGAM sayfalarının da güncellenmesi gerekir. Bu durum, özellikle yoğun insert işlemlerinin olduğu senaryolarda aynı allocation sayfalarına eş zamanlı erişim nedeniyle çekişmelere (contention) sebep olur. Bu çekişmeler genellikle PAGELATCH_UP veya PAGELATCH_EX beklemeleri olarak görülür ve hata veya bekleme mesajlarında veritabanı ismi yer alıyorsa, problemin ilgili veritabanındaki allocation yapılarından kaynaklandığı anlaşılır. Her ne kadar bu durum insert işlemlerinin başarısız olmasına sebep olmasa da, allocation sayfaları üzerindeki çekişme nedeniyle insert işlemlerinde beklemeler oluşur. Bu sebeple, yüksek eş zamanlı veri ekleme yapılan sistemlerde veritabanının tek bir data file üzerinde büyümesi önerilmez; birden fazla data file kullanılarak allocation yükü dağıtılmalı ve çekişmelerin önüne geçilmelidir. PFS / GAM / SGAM / IAM / DCM / BCM her data file’ın kendi içinde vardır. Bu yüzden çekişme (contention) file bazlıdır, database bazlı değil. DCM ve BCM → insert sırasında değil, backup ve bulk operation senaryolarında daha aktiftir Insert contention’ın asıl suçluları: PFS + GAM + SGAM

Başka makalede görüşmek dileğiyle..

…Olur ki (bazen) hoşunuza gitmeyen bir şey sizin için hayırlı olur ve hoşunuza giden bir şey de sizin için şer olur. (Hayırlı ve doğru olanı) Allah bilir, siz bilemezsiniz.” Bakara Suresi; 216. Ayet

Author: Yunus YÜCEL

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir