DBCC CHECKDB integrity scan finding a corrupted page in a SQL Server database

SQL Server’da DBCC CHECKDB: Neyi Kontrol Eder, Ne Sıklıkla Çalıştırılmalı, Hata Bulursa Ne Yapmalı?

DBCC CHECKDB neyi kontrol eder, production’ı bloklamadan nasıl çalıştırılır, ne sıklıkla çalıştırılmalı ve bozulma bulduğunda ne yapılmalı, ne yapılmamalı?

Nisan 23, 2023

Veritabanı bozulması nadiren kendini belli eder. Bir disk denetleyicisi bir sayfayı hatalı yazar, bir depolama sürücüsünde hata vardır ya da bir elektrik kesintisi yazma işlemini yarıda keser, ama ortada bir sorun görünmez. Kullanıcılar çalışmaya devam eder, backup’lar başarıyla alınır. Hasarlı sayfa ise bir sorgu onu okuyana kadar veri dosyasında sessizce bekler. O ana kadar aynı hasar elinizdeki bütün backup’lara geçmiş olabilir.

DBCC CHECKDB, SQL Server’ın bu tür hasarı siz fark etmeden önce bulmak için sunduğu araçtır. Bu yazıda CHECKDB’nin gerçekte neyi kontrol ettiğini, production’ı yormadan nasıl çalıştırılacağını, ne sıklıkla çalıştırılması gerektiğini ve hata bulduğunda ne yapılması (ve ne yapılmaması) gerektiğini anlatıyoruz.

DBCC CHECKDB Neyi Kontrol Eder?

DBCC CHECKDB, bir veritabanındaki bütün nesnelerin mantıksal ve fiziksel bütünlüğünü kontrol eder. Microsoft dokümantasyonuna göre tek bir çalıştırma şunları yapar:

  • Disk alanı tahsis (allocation) yapılarının tutarlılığını kontrol eden DBCC CHECKALLOC‘u çalıştırır.
  • Her tablo ve view üzerinde DBCC CHECKTABLE‘ı çalıştırarak sayfaları, satırları ve indeksler ile veri arasındaki bağlantıları kontrol eder.
  • Sistem kataloğunun (metadata) tutarlılığını kontrol eden DBCC CHECKCATALOG‘u çalıştırır.
  • Her indexed view’ın içeriğini doğrular.
  • FILESTREAM verisinde tablo metadata’sı ile dosya sistemi arasındaki bağlantı tutarlılığını doğrular.
  • Veritabanındaki Service Broker verisini doğrular.

Yani CHECKALLOC, CHECKTABLE ya da CHECKCATALOG’u ayrıca çalıştırmanıza gerek yoktur; CHECKDB hepsini kapsar. CHECKDB varsayılan olarak sütun değeri (data purity) kontrollerini de yapar: veri tipinin geçerli aralığı dışında kalan değerleri, örneğin imkânsız bir datetime değerini bulur. Tek istisna şudur: çok eski sürümlerden yükseltilmiş veritabanlarında bu kontroller, DBCC CHECKDB WITH DATA_PURITY bir kez hatasız tamamlandıktan sonra devreye girer.

SQL Server Danışmanlığı

SQL Server için Uzman Desteğine mi İhtiyacınız Var?

Kıdemli veritabanı ekibimiz SQL Server performans ayarlama, sağlık kontrolleri, migrasyonlar, Remote DBA hizmetleri ve acil operasyonel sorunlarda destek sağlar.

Hizmetlerimizi İnceleyin

DBCC CHECKDB Neden Önemli? Backup Bozulmayı da Kopyalar

En sık duyduğumuz varsayım “backup’ımız var, güvendeyiz” cümlesidir. Ama full backup veri sayfalarını olduğu gibi kopyalar. Bir sayfa zaten hasarlıysa backup’ta da hasarlı haliyle yer alır. WITH CHECKSUM ile alınan backup’lar sayfaları okurken checksum’larını doğrular ve bu değerlidir, ama CHECKDB’nin yaptığı yapısal ve mantıksal kontrolleri yapmaz.

Uyarı

Bu da bu yazının en önemli kuralını ortaya çıkarır: başarılı iki CHECKDB arasındaki süre, backup saklama sürenizden kısa olmalıdır. Backup’ları 14 gün sakladığınızı ama CHECKDB’yi ayda bir çalıştırdığınızı düşünün. Bozulma 1. gün oluşur ve CHECKDB onu 30. gün bulursa, elinizde kalan bütün backup’lar bozulmadan sonra alınmış olur. Dönülecek temiz bir kopya kalmaz ve geriye tek seçenek olarak veri kaybettirebilecek bir onarım kalır.

CHECKDB’yi yeterince sık çalıştırırsanız, bir sorun bulduğunda elinizde hâlâ hasardan önce alınmış bir backup ve onu ileri sarmak için gereken log backup’ları olur.

DBCC CHECKDB Nasıl Çalıştırılır?

En sade haliyle, belirtilen veritabanını kontrol eden ve yalnızca hataları gösteren komut şudur:

DBCC CHECKDB (N'SalesDB') WITH NO_INFOMSGS, ALL_ERRORMSGS;

Veritabanı sağlıklıysa komut yalnızca “The command(s) completed successfully.” mesajını döndürür. NO_INFOMSGS kullanmazsanız her nesne için satır ve sayfa sayıları listelenir ve gerçek hatalar bu kalabalığın içinde kaybolur. ALL_ERRORMSGS güncel sürümlerde zaten varsayılandır; script’lerinizde kalmasının zararı yoktur. CHECKDB çalıştırmak için sysadmin sunucu rolüne ya da db_owner veritabanı rolüne üye olmak gerekir.

Önemli seçenekler

Seçenek Ne yapar?
NO_INFOMSGS Bilgi mesajlarını gizler, yalnızca hatalar görünür.
PHYSICAL_ONLY Yalnızca sayfa ve kayıt başlıklarını, allocation tutarlılığını ve checksum’ları kontrol eder. Büyük veritabanlarında çok daha hızlıdır ve torn page’leri, checksum hatalarını ve yaygın donanım arızalarını yine yakalar. Mantıksal, data purity ve FILESTREAM kontrollerini atlar.
EXTENDED_LOGICAL_CHECKS Indexed view’lar, XML ve spatial indeksler ve (SQL Server 2016’dan itibaren) persisted computed column’lar, UDT sütunları ve filtered indeksler için mantıksal kontroller ekler. Maliyetlidir; indeks sorunundan şüphelendiğinizde kullanın.
TABLOCK İç snapshot yerine lock kullanır; buna kısa süreli exclusive bir veritabanı lock’u da dahildir. Yoğun yük altında daha hızlıdır ama eşzamanlılığı düşürür ve katalog ile Service Broker kontrollerini atlar.
MAXDOP = n CHECKDB’nin kullanabileceği CPU sayısını sınırlar ve sunucu ayarını geçersiz kılar (SQL Server 2014 SP2 ve sonrası).
ESTIMATEONLY Kontrolü çalıştırmaz; yalnızca gereken tempdb alanını tahmin eder.

CHECKDB Çalışırken Production Sunucuda Ne Olur?

Not

Yaygın bir yanlış inanış, CHECKDB çalışırken kullanıcıların işlerini durdurması gerektiğidir. Bu doğru değildir. DBCC CHECKDB varsayılan olarak bir iç veritabanı snapshot’ı oluşturur ve kontrollerini bu snapshot üzerinde yapar; Microsoft’a göre bu, blocking ve eşzamanlılık sorunlarını önler. Çalıştırmadan önce backup almanız da gerekmez: onarım seçeneği olmadan CHECKDB yalnızca okur, hiçbir şeyi değiştirmez.

Yine de bedelsiz değildir. Şu etkileri hesaba katın:

  • Yoğun I/O ve CPU: CHECKDB veritabanındaki tahsis edilmiş her sayfayı okur. Yoğun bir sunucuda düşük aktiviteli bir zaman aralığında çalıştırın, gerekirse MAXDOP ile sınırlayın.
  • Veri diskinde snapshot dosyaları: snapshot, veri dosyalarının yanında oluşturulan sparse dosyalardan (<dosya>_MSSQL_DBCC<id> adıyla) kurulur. Kontrol sürerken kaynak veritabanında değişen veri arttıkça bu dosyalar büyür; yoğun yazma aktivitesi veri diskini doldurabilir. Kontrol sırasında sunucu beklenmedik şekilde kapanırsa bu dosyalar geride kalabilir ve temizlenmeleri gerekir.
  • tempdb kullanımı: büyük veritabanları ciddi miktarda tempdb alanına ihtiyaç duyabilir. Ne kadar gerektiğini ESTIMATEONLY ile görebilirsiniz.
  • Paralellik sürüme bağlıdır: paralel kontrol her SQL Server sürümünde (edition) yoktur, bu yüzden aynı veritabanı Standard sürümde belirgin şekilde daha uzun sürebilir.

Snapshot oluşturulamazsa ya da TABLOCK kullanılırsa CHECKDB lock’lara geçer: allocation kontrolleri için exclusive bir veritabanı lock’u, tablo kontrolleri için shared tablo lock’ları alır. Bu durumda kullanıcıları bloklar.

DBCC CHECKDB Ne Sıklıkla Çalıştırılmalı?

Microsoft tek bir sıklık belirlemez; bu, işin ve ortamın ihtiyaçlarına bağlıdır. Pratikte şu ilkeler işe yarar:

  1. Backup saklama sürenizin içinde kalın. Yukarıda anlattığımız gibi en önemli kural budur. 14 günlük saklama süresinde haftalık bir kontrol, dönebileceğiniz en az bir temiz backup’ınız olmasını sağlar.
  2. Büyük veritabanlarında iki modu birleştirin. Microsoft, production sistemlerde sık kullanım için PHYSICAL_ONLY‘yi ve periyodik olarak seçeneksiz tam bir CHECKDB’yi önerir. Tipik bir plan, her gece PHYSICAL_ONLY ve hafta sonu tam kontroldür.
  3. Çok büyük veritabanlarını bölün. Hafta sonu bile yetmiyorsa farklı tablolar için DBCC CHECKTABLE çalıştırmalarını gecelere yayabilir ya da DBCC CHECKFILEGROUP ile her seferinde bir filegroup’u kontrol edebilirsiniz. Bu durumda CHECKTABLE kapsamadığı için DBCC CHECKALLOC ve DBCC CHECKCATALOG‘u ayrıca çalıştırın.
  4. Restore edilmiş bir kopyaya taşımayı düşünün. Son full backup’ı lisansı uygun başka bir sunucuya restore edip CHECKDB’yi orada çalıştırmak hem production’ın yükünü alır hem de aynı adımda backup’ın restore edilebildiğini kanıtlar. Şunu unutmayın: bu yöntem yalnızca backup’ın temiz olduğunu söyler; backup alındıktan sonra production’da oluşan hasar burada görünmez. Bu yüzden production’da en azından PHYSICAL_ONLY kontrollerini sürdürün.

Sistem veritabanlarını da unutmayın. master, model ve msdb da kontrol edilmelidir; master üzerinde CHECKDB çalıştırmak gizli Resource veritabanını da kontrol eder. Zamanlamayı SQL Server Agent job’ları ya da bakım planlarıyla kurabilirsiniz. Ayrıntılar için SQL Server Bakım Planları yazımıza bakabilirsiniz.

CHECKDB En Son Ne Zaman Başarılı Oldu? Her Veritabanını Kontrol Edin

Zamanlanmış bir job’ın var olması çalıştığı anlamına gelmez. Job’lar devre dışı kalır, sessizce hata alır ya da yeni eklenen veritabanlarını atlar. SQL Server 2016 SP2, 2017 CU9, 2019 ve sonraki sürümlerde son başarılı kontrolün zamanı doğrudan alınabilir:

SELECT d.name,
       CAST(DATABASEPROPERTYEX(d.name, 'LastGoodCheckDbTime') AS datetime) AS last_good_checkdb,
       DATEDIFF(DAY, CAST(DATABASEPROPERTYEX(d.name, 'LastGoodCheckDbTime') AS datetime), GETDATE()) AS days_ago
FROM sys.databases AS d
WHERE d.state_desc = N'ONLINE'
  AND d.database_id <> 2   -- tempdb
ORDER BY last_good_checkdb;

1900-01-01 değeri, o veritabanında CHECKDB’nin hiç başarıyla tamamlanmadığı anlamına gelir. days_ago değerini backup saklama sürenizle karşılaştırın; bu süreyi aşan her veritabanı risk altındadır. Availability group’larda bu değer, primary replica’daki son başarılı kontrolü gösterir. SQL Server bir veritabanı açılırken son temiz kontrolü error log’a da yazar: “CHECKDB for database ‘…’ finished without errors on …”. Error log’u nasıl okuyacağınızı SQL Server Error Log rehberimizde anlattık.

İki CHECKDB Arasında Erken Uyarı

CHECKDB zamanlanmış aralıklarla çalışır, ama bozulma her an oluşabilir. Şu ayarlar, SQL Server hasarlı bir sayfayı okuduğu anda bunu bildirmesini sağlar:

  • PAGE_VERIFY CHECKSUM: yeni veritabanlarında varsayılandır, ama çok eski sürümlerden taşınan veritabanlarında hâlâ TORN_PAGE_DETECTION ya da NONE görebilirsiniz. SELECT name, page_verify_option_desc FROM sys.databases; ile kontrol edin. CHECKSUM’a geçtikten sonra bir sayfa checksum’ını ancak bir sonraki yazılışında alır.
  • 823, 824 ve 825 hataları için alert: 823 işletim sistemi seviyesinde bir I/O hatasıdır, 824 checksum uyuşmazlığı gibi bir mantıksal tutarlılık hatasıdır, 825 ise bir okumanın ancak tekrar denendikten sonra başarılı olduğunu gösterir ve bozulmakta olan bir diskin erken işaretidir. Bu üç mesaj numarası için SQL Server Agent alert’leri oluşturup bir operator’e yönlendirin.
  • msdb.dbo.suspect_pages: SQL Server, 823 ya da 824 hatası veren sayfaları bu tabloya kaydeder. Tablo 1.000 satırla sınırlıdır; düzenli olarak inceleyip temizleyin.
  • BACKUP … WITH CHECKSUM: backup alınırken sayfa checksum’larını doğrular; hasarlı bir sayfaya denk gelirse backup hata verir.

DBCC CHECKDB Hata Buldu: Ne Yapmalı, Ne Yapmamalı?

İlk refleks çoğu zaman REPAIR_ALLOW_DATA_LOSS çalıştırmaktır. Yapmayın. Adından da anlaşılacağı gibi bu seçenek veritabanını tutarlı hale getirmek için veri silebilir ve Microsoft, son sağlam backup’tan restore etmeye göre daha fazla veri kaybettirebileceğini açıkça belirtir. Bunun yerine şu sırayı izleyin:

  1. Çıktının tamamını kaydedin. Her hata mesajını, object ID ve index ID’leri ve sondaki “minimum repair level” satırını not edin. Sonraki adımı bunlar belirler.
  2. Hasarın nerede olduğuna bakın. Bütün hatalar nonclustered bir indeksteyse (index ID 1’den büyük), asıl veri sağlamdır; indeksi silip yeniden oluşturmak ya da rebuild etmek sorunu genellikle veri kaybı olmadan çözer. Ardından CHECKDB’yi tekrar çalıştırarak doğrulayın.
  3. Sebebi bulun. Bozulmanın sebebi neredeyse her zaman I/O yoludur: disk, denetleyici, firmware, sürücü ya da depolama. Windows sistem log’unu, depolama log’larını ve SQL Server error log’undaki 823/824/825 hatalarını inceleyin. Sebebi gidermeden veritabanını düzeltirseniz hasar geri gelir.
  4. Backup’tan restore edin. Microsoft’un birincil önerisi budur. Full recovery model’de yalnızca birkaç sayfa hasarlıysa sadece o sayfaları backup’tan restore edip (page restore) ardından log backup’larını uygulayabilirsiniz; Enterprise sürümde bu işlem online bile yapılabilir. Ayrıntılar için SQL Server Restore rehberimize bakabilirsiniz.
  5. Onarımı yalnızca son çare olarak kullanın. Kullanılabilir bir backup yoksa:
    • Önce bütün veritabanı dosyalarının (.mdf, .ndf, .ldf, full-text kataloglar, FILESTREAM klasörleri) fiziksel kopyalarını alın.
    • Veritabanını single-user moda alın; bütün onarım seçenekleri bunu gerektirir.
    • Onarımı bir transaction içinde (BEGIN TRANSACTION) çalıştırın; böylece sonucu inceleyip commit ya da rollback edebilirsiniz.
    • Onarımdan sonra DBCC CHECKCONSTRAINTS çalıştırın, çünkü onarım foreign key’leri ve diğer constraint’leri dikkate almaz. Ardından hemen full backup alın.

Bozulma veritabanının hiç açılamamasına kadar ilerlediyse SQL Server Veritabanı RECOVERY PENDING veya SUSPECT’te mi Kaldı? yazımıza bakın. Bozulmanın sebeplerine daha geniş bir bakış için SQL Server Corruption yazımızı okuyabilirsiniz.

Sık Sorulan Sorular

Varsayılan olarak hayır. CHECKDB iç bir veritabanı snapshot’ı üzerinde çalışır, bu yüzden kullanıcıları bloklamaz. Yine de ciddi I/O ve CPU yükü oluşturur; bu nedenle düşük aktiviteli bir zaman aralığı doğru tercihtir. Snapshot oluşturulamazsa ya da TABLOCK kullanırsanız lock alır ve bloklayabilir.
Normal bir kontrol için hayır. Onarım seçeneği olmadan CHECKDB yalnızca okur, hiçbir şeyi değiştirmez. Backup ve veritabanı dosyalarının fiziksel kopyaları yalnızca REPAIR_ALLOW_DATA_LOSS ile çalıştırmadan önce gereklidir.
Veritabanı boyutuna, depolama hızına, CPU sayısına, sürüme ve sunucunun yoğunluğuna bağlıdır. Güvenilir bir formül yoktur; en iyi rehber kendi geçmişinizdir. Her çalıştırmanın süresini Agent job geçmişinden takip edin ve bakım pencerelerini buna göre planlayın. PHYSICAL_ONLY büyük veritabanlarında çok daha hızlıdır.
Hayır. Torn page ve checksum hataları gibi donanım kaynaklı hasarı yakalar, ama mantıksal, data purity ve FILESTREAM kontrollerini atlar. Microsoft onu sık kullanmayı ve yine de periyodik olarak tam bir CHECKDB çalıştırmayı önerir.
Evet. WITH CHECKSUM backup okunurken sayfa checksum’larını doğrular ve iyi bir erken uyarıdır, ama allocation yapılarını, indeks-veri tutarlılığını ya da sistem kataloğunu kontrol etmez. İkisi birbirini tamamlar.
Her replica’nın kendi depolaması vardır, bu yüzden bir replica’nın diskindeki bozulma diğerlerinde olmayabilir. Primary’yi kontrol etmek secondary’lerin temiz olduğunu kanıtlamaz. Primary olabilecek her secondary’yi bütünlük kontrolü planınıza dahil edin.

SQL Server Sağlık Kontrolü

Bozulmayı Son Temiz Backup’ınıza Ulaşmadan Bulun

Aryasoft’un kıdemli DBA ekibi bütünlük kontrollerinizi, backup saklama sürenizi, sayfa doğrulama ve alert ayarlarınızı uçtan uca inceler; veritabanlarınıza ve bakım pencerelerinize uygun bir CHECKDB planı kurar.

4.7/5