Corrupted SQL Server storage being repaired with clean pages restored from backup

SQL Server Veritabanı Bozulması (Corruption): Nedenleri, Belirtileri ve Veri Kaybetmeden Kurtarma

SQL Server veritabanı bozulmasına ne sebep olur, 823, 824 ve 825 uyarı işaretleri nelerdir ve page restore, backup ya da onarımla en az veri kaybıyla nasıl kurtarılır?

Mart 31, 2023

“Sorgu 824 hatası veriyor.” “Gece alınan backup checksum hatasıyla durdu.” “CHECKDB bir sayfa dolusu kırmızı yazı döndürdü.” SQL Server’da veritabanı bozulması (corruption) genellikle bu yollardan biriyle ortaya çıkar ve ilk bir saatte verilen kararlar çoğu zaman ne kadar veri kaybedeceğinizi belirler.

Bu yazıda SQL Server corruption’ın ne olduğunu (ve ne olmadığını), neden oluştuğunu, nasıl erken fark edileceğini ve neyin hasar gördüğüne göre en az veri kaybıyla nasıl kurtarılacağını anlatıyoruz.

SQL Server Corruption (Veritabanı Bozulması) Nedir?

SQL Server veriyi veri dosyalarının içinde 8 KB’lık sayfalarda saklar. Bozulma, bu sayfalardan birinin ya da birkaçının artık SQL Server’ın yazdığı içeriği taşımaması demektir: checksum tutmaz, sayfa başlığı bozulmuştur, sayfa ID’si yanlıştır ya da sayfalar arasındaki bağlantılar kopmuştur. Bozulma veri sayfalarında, indeks sayfalarında, allocation sayfalarında, sistem metadata’sında, transaction log’da ya da backup dosyalarının kendisinde olabilir.

Bozulmayı sık karıştırıldığı iki durumdan ayırmak gerekir:

  • Yanlışlıkla silinen ya da değiştirilen veri bozulma değildir. Biri WHERE koşulu olmadan DELETE çalıştırdıysa sayfalar tamamen sağlıklıdır. Bunun çözümü CHECKDB değil, point-in-time restore’dur.
  • RECOVERY PENDING’deki bir veritabanı bozuk olmak zorunda değildir. Eksik bir dosya, dolu bir disk ya da yetki sorunu da aynı duruma yol açabilir. Bunu ayrıca SQL Server Veritabanı RECOVERY PENDING veya SUSPECT’te mi Kaldı? yazımızda anlattık.
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

Bozulmaya Ne Sebep Olur?

SQL Server’ın kendisi çok nadiren hatalı bir sayfa yazar. Vakaların büyük çoğunluğunda hasar SQL Server ile disk arasında bir yerde, yani I/O yolunda oluşur:

  • Diskler ve depolama: arızalanan diskler, SAN ya da depolama dizisi firmware hataları, arızalı denetleyiciler ya da kablolar.
  • Sürücüler ve filter driver’lar: güncel olmayan depolama sürücüleri ve I/O yoluna giren yazılımlar; örneğin backup ajanları, şifreleme ya da antivirüs filter driver’ları. Veritabanı dosyaları antivirüs taramasının dışında tutulmalıdır.
  • Elektrik kesintisi ve yazma önbelleği: bir yazma işlemi sürerken elektriğin kesilmesi bir sayfanın yarım yazılmasına (“torn page”) yol açabilir; özellikle disk ya da denetleyici yazma önbelleği pil veya flash ile korunmuyorsa.
  • Bellek hataları: bir sayfa diske yazılmadan önce bellekte bozulabilir.
  • Güvensiz dosya işlemleri: SQL Server çalışırken veritabanı dosyalarını SQL Server’ın desteklediği bir yöntem kullanmadan kopyalamak ya da snapshot’ını almak.
  • Yazılım hataları: nadir ama gerçek; SQL Server’da, işletim sisteminde ya da depolama yazılımında olabilir. Cumulative update’leri güncel tutmanın sebeplerinden biri de budur.

Uyarı

Pratik ders şudur: sebebi gidermeden veritabanını düzeltirseniz bozulma geri gelir.

Uyarı İşaretleri: Bilmeniz Gereken Hata Mesajları

Hata Anlamı
823 SQL Server bir sayfayı okurken ya da yazarken işletim sistemi bir I/O hatası bildirdi. Sorun işletim sistemi seviyesinde ya da altındadır.
824 Okuma başarılı oldu ama sayfanın içeriği yanlış: hatalı checksum, torn page ya da yanlış sayfa ID’si. En sık görülen bozulma hatasıdır.
825 Bir okuma önce başarısız oldu, ancak tekrar denendikten sonra başarılı oldu. Henüz bir şey bozulmadı, ama depolamanın arızalanmaya başladığının erken uyarısıdır.
829 Sayfa “restore pending” olarak işaretlendi; restore ya da onarım yapılana kadar okunamaz.
CHECKDB hataları “CHECKDB found X allocation errors and Y consistency errors” mesajı ve hasarlı her nesne için ayrıntılar.
Backup hatası WITH CHECKSUM ile alınan bir backup, checksum’ı tutmayan bir sayfayı okuduğunda durur.

Bu mesajlar SQL Server error log’unda görünür ve bakılacak ilk yer orasıdır; SQL Server Error Log rehberimize göz atabilirsiniz.

Bozulmayı Erken Fark Etmek

Bozulma ne kadar erken bulunursa, aralarından seçim yapabileceğiniz temiz backup sayısı o kadar fazla olur. Birlikte çalışan üç mekanizma vardır.

1. msdb.dbo.suspect_pages tablosunu kontrol edin

SQL Server, 823 ya da 824 hatası veren her sayfayı hata tipiyle birlikte bu tabloya kaydeder:

SELECT DB_NAME(database_id) AS database_name,
       file_id,
       page_id,
       CASE event_type
            WHEN 1 THEN '823 / 824 (other)'
            WHEN 2 THEN 'Bad checksum'
            WHEN 3 THEN 'Torn page'
            WHEN 4 THEN 'Restored'
            WHEN 5 THEN 'Repaired by DBCC'
            WHEN 7 THEN 'Deallocated by DBCC'
       END AS event_desc,
       error_count,
       last_update_date
FROM msdb.dbo.suspect_pages
ORDER BY last_update_date DESC;

Event type’ı 1, 2 ya da 3 olan satırlar ilgi bekler. Tablo 1.000 satırla sınırlıdır; sorunlar çözüldükten sonra eski kayıtları temizleyin.

2. 823, 824 ve 825 hataları için alert

Bu hatalar yalnızca bir sorgu hasarlı sayfaya dokunduğunda ortaya çıkar. Alert yoksa sorunu ilk fark eden bir kullanıcı olabilir. Bir SQL Server Agent alert’i ve DBA ekibine giden bir e-posta birkaç dakikada kurulur:

-- Database Mail ve tanımlı bir operator gerektirir (burada: 'DBA Team')
DECLARE @msg int, @name sysname;
DECLARE c CURSOR LOCAL FAST_FORWARD FOR SELECT v FROM (VALUES (823), (824), (825)) AS t(v);
OPEN c; FETCH NEXT FROM c INTO @msg;
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @name = N'Error ' + CAST(@msg AS nvarchar(10));
    EXEC msdb.dbo.sp_add_alert
         @name = @name, @message_id = @msg, @severity = 0,
         @delay_between_responses = 900, @include_event_description_in = 1;
    EXEC msdb.dbo.sp_add_notification
         @alert_name = @name, @operator_name = N'DBA Team', @notification_method = 1;
    FETCH NEXT FROM c INTO @msg;
END
CLOSE c; DEALLOCATE c;

3. Düzenli DBCC CHECKDB ve sayfa checksum’ları

Alert’ler yalnızca okunan sayfalar için tetiklenir. Nadiren kullanılan tablolar ve indeksler aylarca hasarlı kalabilir. Bu yüzden düzenli bir DBCC CHECKDB şarttır ve başarılı iki çalıştırma arasındaki süre backup saklama sürenizden kısa olmalıdır. Ayrıca her veritabanının PAGE_VERIFY CHECKSUM kullandığından ve backup’ların WITH CHECKSUM ile alındığından emin olun. Sıklığı, seçenekleri ve production’a etkisini SQL Server’da DBCC CHECKDB yazımızda ayrıntılı anlattık.

Bozulma Bulundu: İlk Bir Saat

Sakin ve sıralı adımlar hızdan daha önemlidir. Yapılmaması gerekenler:

  • İlk adım olarak REPAIR_ALLOW_DATA_LOSS çalıştırmayın. Veri silebilir ve Microsoft’a göre son sağlam backup’tan restore etmeye kıyasla daha fazla veri kaybettirebilir.
  • “Kendiliğinden düzelir mi” diye veritabanını detach etmeyin ya da SQL Server’ı tekrar tekrar yeniden başlatmayın. Hasarlı bir veritabanı yeniden attach edilemeyebilir ya da recovery’yi tamamlayamayabilir.
  • Eski backup’ların üzerine yazmayın, silmeyin. İhtiyacınız olan, hasardan önceki backup olabilir.

Yapılması gerekenler:

  1. Kanıtları toplayın: hata mesajları, error log kayıtları, suspect_pages satırları ve sorunun ilk görüldüğü zaman.
  2. Mümkünse bir log backup alın (full recovery model). Son log backup’tan bu yana yapılan işi korur ve her page ya da veritabanı restore’unun ilk adımıdır.
  3. Hasarın tamamını görmek için DBCC CHECKDB çalıştırın: DBCC CHECKDB (N'SalesDB') WITH NO_INFOMSGS, ALL_ERRORMSGS; Sondaki “minimum repair level” satırı dahil çıktının tamamını kaydedin.
  4. Depolamayı incelemeye başlayın: Windows sistem log’u, depolama ve denetleyici log’ları ve donanım üreticisinin tanılama araçları. Disk arızalanıyorsa restore’u farklı bir diske yapmak daha güvenli olabilir.

Kurtarma Yöntemini Seçmek: Ne Hasar Gördü?

Doğru kurtarma yöntemi, CHECKDB çıktısının neyin hasar gördüğünü söylediğine bağlıdır:

Durum Önerilen yöntem
Yalnızca nonclustered indeksler hasarlı (index ID 1’den büyük) İndeksi silip yeniden oluşturun ya da rebuild edin. Verinin kendisi sağlam olduğu için veri kaybı olmaz.
Birkaç veri sayfası hasarlı Backup’tan page restore, ardından log backup’larının uygulanması (full recovery model gerekir).
Çok sayıda sayfa ya da bir dosyaya yayılmış hasar Dosya ya da tam veritabanı restore’u, gerekirse farklı bir diske.
Allocation sayfaları (GAM, SGAM, PFS), dosya başlığı ya da boot sayfası hasarlı Bunlar sayfa seviyesinde restore edilemez; tam veritabanı restore’u gerekir.
Veritabanı bir Always On availability group’ta Automatic page repair sorunu zaten çözmüş olabilir (aşağıya bakın). Diğer replica’ları da kontrol edin.
Kullanılabilir backup yok Dosyaların kopyası alındıktan sonra, son çare olarak REPAIR_ALLOW_DATA_LOSS.

Page restore: bütün veritabanını restore etmeden birkaç sayfayı düzeltmek

Yalnızca birkaç sayfa hasarlıysa ve veritabanı full recovery model kullanıyorsa, sadece o sayfaları backup’tan restore edebilirsiniz. Bütün sürümler bunu offline olarak destekler; Enterprise sürümde veritabanı online kalırken yapılabilir. Dosya ve sayfa ID’leri suspect_pages tablosundan, hata mesajından ya da CHECKDB çıktısından alınır:

-- 1. Hasarlı sayfaları son full backup'tan restore edin
RESTORE DATABASE [SalesDB] PAGE = '1:57, 1:202'
FROM DISK = N'E:\Backup\SalesDB_FULL.bak'
WITH NORECOVERY;

-- 2. Varsa differential'ı ve sonrasındaki bütün log backup'ları sırayla uygulayın
RESTORE LOG [SalesDB] FROM DISK = N'E:\Backup\SalesDB_LOG_01.trn' WITH NORECOVERY;
RESTORE LOG [SalesDB] FROM DISK = N'E:\Backup\SalesDB_LOG_02.trn' WITH NORECOVERY;

-- 3. Yeni bir log backup alıp restore ederek sayfaları güncel hale getirin
BACKUP LOG [SalesDB] TO DISK = N'E:\Backup\SalesDB_LOG_tail.trn';
RESTORE LOG [SalesDB] FROM DISK = N'E:\Backup\SalesDB_LOG_tail.trn' WITH RECOVERY;

-- 4. Doğrulayın
DBCC CHECKDB (N'SalesDB') WITH NO_INFOMSGS;

Not

Page restore; transaction log, allocation sayfaları (GAM, SGAM, PFS), her veri dosyasının 0 numaralı sayfası, veritabanı boot sayfası (1:9) ve full-text kataloglar için kullanılamaz. Bir dosyada çok sayıda sayfa hasarlıysa bütün dosyayı restore etmek genellikle daha verimlidir. Restore sürecinin tamamı için SQL Server Restore rehberimize bakabilirsiniz.

Always On availability group’larda automatic page repair

Bir availability group’ta bir replica, 823 (CRC hatası), 824 ya da 829 hatası yüzünden bir sayfayı okuyamazsa, o sayfanın temiz bir kopyasını otomatik olarak başka bir replica’dan ister ve hasarlı sayfayı değiştirir. Veri kaybı olmaz. Dosya başlığı sayfaları, boot sayfası ve allocation sayfaları bu yolla onarılamaz. Son denemeleri sys.dm_hadr_auto_page_repair ile görebilirsiniz. Otomatik onarım belirtiyi giderir, sebebi değil; sürekli hata üreten bir disk yine ilgilenilmeyi bekler. Availability group’lar hakkında daha fazlası için SQL Server Always On Nedir? yazımıza bakabilirsiniz.

Backup yoksa: son çare olarak onarım

Kullanılabilir bir backup yoksa geriye REPAIR_ALLOW_DATA_LOSS ile DBCC CHECKDB kalır. Çalıştırmadan önce bütün veritabanı dosyalarını kopyalayın, veritabanını single-user moda alın, sonucu inceleyebilmek için onarımı bir transaction içinde çalıştırın; ardından DBCC CHECKCONSTRAINTS çalıştırıp full backup alın. Onarım sayfaları tümüyle serbest bırakabilir ve bu sayfalardaki veri geri getirilemez.

Kurtarmadan Sonra: Tekrar Yaşanmamasını Sağlayın

  • Kök nedeni bulun ve giderin: depolama ve sistem ekipleriyle birlikte donanımı değiştirin, firmware ve sürücüleri güncelleyin, antivirüs istisnalarını gözden geçirin.
  • DBCC CHECKDB’yi tekrar çalıştırın ve veritabanının temiz olduğunu doğrulayın.
  • Hemen bir full backup alın ve restore ederek test edin.
  • Backup stratejisini gözden geçirin: saklama süresi yeterli mi, CHECKDB backup’ların süresi dolmadan daha sık çalışıyor mu? En İyi Backup Planı Nasıl Kurulur? yazımıza bakabilirsiniz.
  • Alert’leri ve CHECKDB zamanlamasını yerinde tutun; özellikle 825 hatalarını izleyin, çoğu zaman bir disk arızalanmadan önce görünürler.

Sık Sorulan Sorular

Çoğu zaman evet. Yalnızca nonclustered indeksler hasarlıysa, onları yeniden oluşturmak hiçbir şey kaybettirmez. Veri sayfaları hasarlıysa ve elinizde full backup ile kesintisiz bir log backup zinciri varsa, page ya da veritabanı restore’u veritabanını arıza anına kadar geri getirebilir. Veri kaybı genellikle temiz bir backup olmadığında ve onarım kullanılmak zorunda kalındığında yaşanır.
823, işletim sisteminin bir I/O hatası bildirdiği anlamına gelir. 824, okumanın başarılı olduğunu ama sayfa içeriğinin yanlış olduğunu gösterir; örneğin hatalı checksum ya da torn page. 825 ise bir okumanın ancak tekrar denendikten sonra başarılı olduğunu gösterir; depolamanın arızalanmaya başladığına dair bir uyarıdır.
Hayır. Bozulma diskte olduğu için yeniden başlatma onu düzeltmez. Durumu kötüleştirebilir de: hasarlı bir veritabanı recovery’yi tamamlayamayıp SUSPECT ya da RECOVERY PENDING durumuna düşebilir.
Evet. Backup sayfaları olduğu gibi kopyalar; hasardan sonra alınan bir backup hasarı da içerir. Backup dosyasının kendisi de depolamada bozulabilir. Backup’ları WITH CHECKSUM ile almak, düzenli olarak test restore yapmak ve restore edilen kopyalarda CHECKDB çalıştırmak bu riski azaltır.
Kısmen. Her replica’nın kendi depolaması vardır, bu yüzden bir replica’daki hasar genellikle diğerlerinde olmaz ve automatic page repair bazı hasarlı sayfaları başka bir replica’dan düzeltebilir. Ama her sayfa tipini onaramaz ve backup ile CHECKDB’nin yerini tutmaz.
Önce SQL Server’ın desteklenen yöntemlerini kullanın: backup’tan restore, page restore ve gerekirse DBCC onarımı. Bunların hiçbiri mümkün değilse ve veri kritikse deneyimli bir ekiple çalışın; her zaman dosyaların kopyaları üzerinde çalışın, asla orijinalleri üzerinde değil.

SQL Server Acil Kurtarma

Veritabanı Bozulması mı Yaşıyorsunuz? İlk Adımı Yalnız Atmayın

Aryasoft’un kıdemli DBA ekibi hasarı değerlendirmenize, en az veri kaybıyla kurtarma yolunu seçmenize ve sorunun tekrar etmemesi için kök nedeni bulmanıza yardımcı olur.

4.7/5