SQL Server’da bir sayfa (page), veritabanı depolama yapısının temel birimidir. SQL Server, verileri disk üzerinde sayfalar halinde düzenler ve yönetir. Her sayfa, 8 KB (8192 bayt) boyutundadır ve belirli bir türde veri içerir. Sayfalar, veritabanı dosyaları içinde düzenlenir ve bu dosyalar, veritabanının fiziksel depolama yapısını oluşturur. Her sayfanın başında 96 baytlık bir başlık bulunur. Bu başlık, sayfa türü, sayfa kimliği, LSN (Log Sequence Number),kendinden önce ve sonraki page numaraları, sayfadaki boş alan miktarı gibi meta verileri içerir. Örneğin, sayfanın bir veri sayfası mı yoksa bir indeks sayfası mı olduğu bu başlıkta belirtilir.
Veri Alanı (Data Rows): Sayfanın geri kalan kısmı (8192 – 96 = 8096 bayt), veri satırlarını veya diğer bilgileri depolamak için kullanılır. Veri satırları, tablo satırlarını veya indeks girişlerini içerebilir. Her satırın boyutu, depolanan veri türüne ve yapısına bağlıdır.
Slot Dizisi (Slot Array veya Offset Table): Sayfanın sonunda, sayfadaki her satırın başlangıç ofsetini (konumunu) gösteren bir dizi bulunur. (2 Byte’lık)Bu dizi, sayfadaki satırların fiziksel düzenini yönetir ve SQL Server’ın satırlara hızlı erişim sağlamasına yardımcı olur.
Page Header ile Row Offset Array arasında kalan bölümde verilerimiz bulunmaktadır.
SQL Server’da farklı türde sayfalar bulunur. Her sayfa türü, belirli bir amaç için kullanılır:
1. Veri Sayfaları (Data Pages):
Tablo satırlarını depolamak için kullanılır.
Her satır, bir tablodaki bir kaydı temsil eder.
2. İndeks Sayfaları (Index Pages):
İndeks yapılarını depolamak için kullanılır.
İndeks sayfaları, Btree yapısında düzenlenir ve verilere hızlı erişim sağlar.
3. LOB (Large Object) Sayfaları:
Büyük nesneleri (örneğin, varchar(max), nvarchar(max), varbinary(max)) depolamak için kullanılır.
Bu tür veriler, normal veri sayfalarına sığmayacak kadar büyük olabilir.
4. GAM, SGAM, PFS Sayfaları:
GAM (Global Allocation Map): Hangi uzantıların (extents) boş olduğunu takip eder.
SGAM (Shared Global Allocation Map): Paylaşılan uzantıların durumunu takip eder.
PFS (Page Free Space): Her sayfadaki boş alan miktarını takip eder.
5. IAM (Index Allocation Map) Sayfaları:
Bir tablo veya indeksin hangi uzantıları kullandığını takip eder.
6. Boot Sayfası (Boot Page):
Veritabanının başlangıç bilgilerini içerir.
Veritabanı açıldığında ilk okunan sayfadır.
SQL Server, veritabanı dosyalarını uzantılar (extents) halinde düzenler. Her uzantı, 8 sayfadan (64 KB) oluşur. Uzantılar, aşağıdaki türlerde olabilir:
Tekil Uzantı (Uniform Extent): Tek bir nesneye (tablo veya indeks) ait sayfalar içerir.
Karışık Uzantı (Mixed Extent): Birden fazla nesneye ait sayfalar içerir.
Bu yapı sayesinde Sayfalar, SQL Server’ın verilere hızlı erişim sağlamasına yardımcı olur. Örneğin, indeks sayfaları, verilere daha hızlı erişim sağlamak için kullanılır. Veritabanı depolama alanının verimli bir şekilde yönetilmesini sağlar. Sayfaların içeriğini incelemek (örneğin, DBCC PAGE komutu ile), veritabanı sorunlarını gidermek için kullanılabilir.
DBCC PAGE komutu, SQL Server’da bir veritabanı sayfasının içeriğini görüntülemek için kullanılan bir komuttur. Bu komut, genellikle veritabanı yöneticileri ve geliştiriciler tarafından veritabanı sayfalarının içeriğini incelemek ve sorun gidermek amacıyla kullanılır. DBCC PAGE komutu, bir sayfanın ham içeriğini gösterir ve bu sayfanın nasıl yapılandırıldığını anlamak için kullanılır.
DBCC PAGE komutunu kullanmak için SQL Server’da sysadmin rolüne sahip olmanız veya yeterli izinlere sahip olmanız gerekir. Ayrıca, bu komut genellikle sorun giderme ve analiz amaçlı kullanıldığından, üretim ortamlarında dikkatli kullanılmalıdır.
Bu komutu çalıştırabilmek için Trace Flag 3604‘ü etkinleştirmelisiniz.
DBCC TRACEON (3604); -- Çıktıyı SSMS'e yönlendirir
DBCC PAGE komutunun temel sözdizimi aşağıdaki gibidir:
DBCC PAGE ( {'databasename' | databaseid}, fileid, pageid, print_option )
databasename | databaseid: İncelemek istediğiniz veritabanının adı veya kimliği (ID).
file_id: Sayfanın bulunduğu dosyanın ID’si (sys.master_files tablosundan bulunabilir). Genellikle 1’dir (birincil veri dosyası).
page_id: İncelenecek sayfanın ID’si (DBCC IND ile bulunabilir
print_option: Sayfa içeriğinin nasıl görüntüleneceğini belirler. Genellikle 0, 1, 2 veya 3 değerlerini alır:
0: Genel özet verir.
1: Sayfanın başlık bilgilerini gösterir.
2: Veri satırlarını detaylı şekilde gösterir.
3: Veri satırlarının hexadecimal (hex) görünümünü gösterir.
Öncelikle, incelenecek tabloya ait sayfaları bulmalıyız. Bunun için DBCC IND komutunu kullanabiliriz.
DBCC IND ('AdventureWorks2014', '[Person].[Address]', -1);

Bu komut, tabloya ait sayfa bilgilerini listeler. Çıktıda aşağıdaki önemli sütunlar bulunur:
PagePID → Sayfa ID’si
IndexID → İlgili index’in ID’si
IAMFID ve IAMPID → Allocation bilgileri
Diyelim ki, DBCC IND çıktısında PagePID = 12345 olarak göründü. Bu sayfanın içeriğini görüntülemek için:
DBCC TRACEON (3604);
DBCC PAGE ('AdventureWorks2014', 1, 12345, 3);

Yukarıdaki ekran resminin detaylı açıklamaları MSSQL Server DBCC Page Header İçeriği makalesinde bulunabilir. Kısaca yukarıdaki kodun açıklamasını yapmak gerekirse:
FileID = 1 → Genellikle birincil veri dosyasıdır (MDF).
PageID = 12345 → İncelenecek sayfanın ID’si.
Seviye 3 → Ham veriyi hexadecimal formatta gösterir.
DBCC IND komutunu kullandık sorunun nerden olduğunu NextPagePID veya PreviousPagePID sırasının bozuk olması yani sıralı olmaması ilgi page yapısının bozuk olduğu görülmektedir.
Belirli bir PageID eksikse : Örneğin, NextPagePID olarak 12347 beklenirken 12349 geliyorsa, eksik sayfa olabilir.
IndexLevel yanlışsa :Eğer index seviyeleri beklenenden farklıysa, index bozulmuş olabilir. Bu durumda ne yapılmalıdır. Kısaca açıklamak gerekirse:
Çözüm Yöntemi:
1-DBCC IND ile sayfa listesini al.
2-DBCC CHECKDB ile bozuk sayfaları tespit et.
DBCC CHECKDB ('VeritabanıAdı') WITH NO_INFO_MSGS, ALL_ERROR_MSGS;
Bu komut çalıştırıldığında bozuk sayfa ID’leri hakkında bilgi içeren hata mesajları alabilirsin.
Msg 824, Level 24, State 2, Line 1
SQL Server detected a logical consistency-based I/O error: incorrect checksum. It occurred during a read of page (1:12346) in database ID 5.
Bu, sayfanın bozuk olduğunu doğrular.
3-DBCC PAGE ile bozuk sayfaları detaylı incele.
DBCC TRACEON (3604);
DBCC PAGE ('VeritabanıAdı', 1, 12346, 3);
Bu komut ile sayfanın detaylı içeriğini görebilir ve şu durumları kontrol edebilirsin:
m_type değeri: Eğer mtype değeri: Eğer mtype = 1 olmalı fakat farklı bir değer görünüyorsa, sayfa bozulmuş olabilir.
m_freeCnt (Boş Alan): Normalden fazla boş alan varsa, eksik veri olabilir.
m_slotCnt (Satır Sayısı): Beklenenden az satır varsa, veri kaybı yaşanmış olabilir.
Satır verileri eksik veya bozuk görünüyorsa, sayfa hatalı olabilir.
Eğer hex veriler tamamen 0x00 gibiyse, sayfa büyük ihtimalle bozulmuş.
Eğer kayıtlar eksikse veya anlamsız veriler varsa, veri kaybı olabilir.
4-SELECT %%physloc%% ile bozuk kaydın hangi sayfada olduğunu bul. Yukarıdaki DBCC CHECKDB hata mesajına istinaden
SELECT %%physloc%%, * FROM Personel WHERE ID = 5;
Bu sorgu, fiziksel sayfa konumunu ((fileid:pageid:slot_id)) döndürür. Örneğin:
(1:12346:2)
Bu, kaydın FileID=1, PageID=12346, Slot=2 konumunda olduğunu gösterir.
5-Sayfa bağlantıları (NextPagePID / PreviousPagePID) eksik veya hatalı mı kontrol et.
Eğer sorunlu bir sayfa tespit edersen:
Küçük tablolar için verileri yedekleyip, tabloyu tekrar oluşturabilirsin.
Büyük tablolar için, bozuk sayfaları kurtarmak için
DBCC CHECKDB(‘VeritabanıAdı’, REPAIR_ALLOW_DATA_LOSS); komutunu deneyebilirsin. (Dikkat: Veri kaybı olabilir!)
Not: Eğer sayfa bozuk ama tamamen kaybolmamışsa, verileri yeni bir tabloya taşıyabilirsin
Yukarıdaki adımları takip ettikten sonra REPAIR_ALLOW_DATA_LOSS kullanarak veri kaybına tahammülümüz yoksa hatalı olan page’ler restore işlemine tabi tutulur. Genellikle verinin pek bir öneme sahip olmadığı yapılarda yukarıdaki yapı kullanılmaktadır.
Sadece Page bazında Restore yapmak için Full backup işlemini yapmadan önce sadece bozuk sayfaları kurtarmak için kullanılan bir başka yöntem Page Restore yöntemidir.
DBCC IND veya DBCC PAGE komutları ile hangi sayfaların bozulduğunu bulabilirsiniz. Daha sonra DBCC CHECKDB komutuyla bu pageler teyit edilmektdir.
DBCC IND ('VeritabaniAdi', 'TabloAdi', -1);
Bir sayfanın içeriğini görmek için:
DBCC TRACEON (3604);
DBCC PAGE ('VeritabaniAdi', 1, SayfaID, 3);
DBCC TRACEOFF (3604);
Not: DBCC IND komutunu kullanmadan suspect olmuş pageleri görmek için aşağıdaki komut kullanılır.
select * from msdb..suspect_pages
Bulduğunuz bozuk sayfayı, mevcut tam yedekten geri yüklemek için aşağıdaki komutu kullanabilirsiniz. Full backupdan restore işlemi yapmadan son log backupdan sonra olan backup dosyasını almak için tail log backup komutu çalıştırılır. Tail log backup alındıktan sonra veritabanı restoring moda düşer ve restore işlemi başlamış olur.
BACKUP LOG VeritabaniAdi
TO DISK = 'C:\Backup\VeritabaniTailLogYedek.trn'
WITH NO_TRUNCATE, COMPRESSION, STATS = 1
No_Truncate hasar görmüş veritabanlarında kullanılır.
RESTORE DATABASE VeritabaniAdi
PAGE = (1, 12345) -- (FileID, PageID) şeklinde bozuk sayfanın bilgisini girin
FROM DISK = 'C:\Backup\Veritabani_Yedek.bak'
WITH NORECOVERY;
Burada:
1=>File ID (Genellikle 1 olur, ancak farklı olabilir)
12345=>Page ID (DBCC CHECKDB veya DBCC IND ile tespit edilen bozuk sayfa)
Eğer birden fazla bozuk sayfa varsa, şu şekilde birden fazla sayfa belirtebilirsiniz:
RESTORE DATABASE VeritabaniAdi
PAGE = (1, 12345), (1, 67890) -- -- '1:12345, 1:67890' bu şekildede yapılabilir.
FROM DISK = 'C:\Backup\Veritabani_Yedek.bak'
WITH NORECOVERY;
Tam yedekten gelen sayfa, yedeğin alındığı andaki durumuna geri döner. Sonrasında alınan log yedeklerini de geri yükleyerek en güncel haline getirmemiz gerekiyor.
Eğer log yedeğiniz varsa, şu komutları çalıştırarak log yedeğini de uygularsınız:
RESTORE LOG VeritabaniAdi
FROM DISK = 'C:\Backup\VeritabaniLogYedek.trn'
WITH NORECOVERY;
Tüm log yedeklerini uyguladıktan sonra veritabanını online duruma getirin: Tabi bu işlem için tail log backup olmaması gerekmektedir.
RESTORE DATABASE VeritabaniAdi WITH RECOVERY;
Eğer elimizde tail log backup varsa son log dosyası norecovery modda log dosyası yüklendikten sonra tail log backup recovery modda restore edildiğinde veritabanımız suspect moddan kurtulmuş olacaktır.
RESTORE LOG VeritabaniAdi FROM DISK=N'C:\Backup\VeritabaniTailLogYedek.trn'
WITH RECOVERY;
Sonuç olarak kısaca özetlemek gerekirse neler yapmak gerekir.
1. DBCC CHECKDB veya DBCC IND ile bozuk sayfaları tespit edin.
2. Bozuk sayfanın File ID ve Page ID bilgilerini öğrenin.
3. Full backup’tan sadece bozuk sayfayı geri yükleyin.
4. Log backup‘ları uygularak veriyi en güncel haline getirin.
5. Veritabanını RECOVERY moduna alarak tekrar erişime açın.
Önemli Notlar
Page Restore işlemi, Simple Recovery Model’inde çalışmaz. Full veya Bulk-Logged Recovery Mode aktif olmalıdır. Eğer yedeğiniz yoksa ve sayfa ciddi şekilde bozulduysa,
DBCC CHECKDB (‘VeritabaniAdi’, REPAIR_ALLOW_DATA_LOSS) komutunu deneyebilirsiniz. Ancak veri kaybına yol açabilir.
Transaction Log’ları güncellenmediği sürece, yedekten gelen sayfa eski bir veri içerebilir. Bu yüzden log yedeklerini uygulamak önemlidir.
Alternatif Çözümler:
Eğer yedek yoksa ve sayfa ciddi şekilde bozulduysa:
DBCC CHECKDB ('VeritabaniAdi', REPAIR_REBUILD);
veya
DBCC CHECKDB ('VeritabaniAdi', REPAIR_ALLOW_DATA_LOSS)
kullanabilirsiniz. Ancak REPAIR_ALLOW_DATA_LOSS, bazı verilerin silinmesine neden olabilir.
Bu yüzden öncelikle tam bir yedek alıp, ardından müdahale etmek en güvenli yöntemdir.
Ayrıca SSMS üzerinden veritabanına sağ tıklayıp Task>Restore>Page dedikten sonra yukarıdaki yapmış olduğumuz işlemleri yapabiliriz.

Gelen ekranda sorunlu olan page bilgileri girildikten sonra Check Database Pages komutuyla kontrol edilmektedir.

Yukarıdaki resimde backup sets kısmında gözüken backup’ların o path’lerde duruyor olması gerekir. Verify diyerek restore işlemi yapmadan önce o dosyaların doğruluğunu teyit edebilirsiniz.

Veritabanınız herhangi bir High Availability seçeneğinde ise çıkartılması gerekmektedir.
DBCC PAGE komutu, SQL Server’da veritabanı sayfalarının iç yapısını incelemek için güçlü bir araçtır. Bu komut, veritabanı yöneticilerinin ve geliştiricilerin sayfaların nasıl yapılandırıldığını anlamalarına ve performans sorunlarını gidermelerine yardımcı olur. Ancak, bu komutun kullanımı genellikle ileri düzey kullanıcılar içindir ve dikkatli kullanılmalıdır. Page Restore işlemi ise dbcc page komutuyla belirlediğimiz ifade üzerinde işlem yapmamızdır.
Başka bir makalede görüşmek dileğiyle.
“Biz Kur’an’ı Kadir gecesinde indirdik.”Kadir-1