11 Mart 2014 Salı

Index'lerden Corrupt kayıtları kurtarma

Aynen öyle! Şahsen, bilmiyordum. Yeni öğrendim ben de. Bu yazıda bunun nasıl olduğunu anlatmayacağım, pek vaktim yok. Fakat yine de nasıl olduğundan özetle ve teoride bahsetmek istedim. Sonra vaktim olursa belki ayrıntılı şekilde açıklama şansım da olur.

Şöyle ki, örneğin toplamda 3500 kayıt olan, alan1 alanı Clustered Index, alan2 alanı da Nonclustered Index olan bir tablonuzun 306 isimli Data Page'i Corrupt oldu diyelim. Bu Data Page de 180 tane kayıt içeriyordu diyelim. DBCC CHECKDB'yi çalıştırdığınızda, hata alan Page ID'sini göreceksiniz zaten. Daha sonra sorun yaşanan tablodaki kayıtları sorgulayın örneğin

SELECT alan1, alan2 FROM tablo ORDER BY id ASC

Bu şekilde Corrupt olan sayfaya kadar olan kayıtlar sorgulanacak ve Corrupt sayfaya gelindiğinde bağlantı kesilecektir. Fakat SSMS'teki Results penceresinde hangi kaydın id'sine kadar gelindiğini göreceksiniz, bu kayıt sayısı da 2500 olsun. Daha sonra da bu sorgunun ters yönlüsünü çalıştırın

SELECT * FROM tablo ORDER BY id DESC

Bu sorgu da 820 kayıt getirdi diyelim. Toplamda tablomuzda 3500 kayıt vardı, ilk sorgu 2500 kayıt getirdi, ikinci sorgu da 820 kayıt getirdi, böylece Corrupt olan Data Page'imizde ne kadar kayıt sayısı olduğunu bulabiliriz.

Ayrıca eğer ilgili kayıtlar belli bir değere göre ilerliyorsa, örneğin bir Identity'ye göre yine DBCC IND ('veritabanı adı', 'tablo adı', 1) komutu ile (Undocumented bir komuttur) Root Page'i bulup, oradan da hata alınan Corrupt Page'ten sonraki Page'in içine DBCC PAGE('veritabanı adı', 1, , 3) komutuyla (Undocumented bir komuttur) bakıp Corrupt olmuş Page'in içindeki kaydın nerede sonlandığını bulabiliriz. Tabii ki aynı yöntem ile Corruption'ın başladığı kaydı da bulabiliriz.

sp_helpindex 'tablo' komutuyla tablodaki Index'lerin hangi alanları kapsadığına bakarız. Bu komut INCLUDED alanları göstermeyeceği için, Index'lerin Script'lerine bakmak iyi olacaktır. Gerçek bir senaryoda böyle bir durumda ne kadar çok Index'imiz varsa, o kadar çok kaydı kurtarabileceğiz anlamına gelir. Tabii ki uygun bir yedek alma stratejimiz yoksa, en son başvuracağımız yöntemlerden biridir bu...

Bu noktada tablo isimli tablonun Schema olarak bir kopyası oluşturulmalı ve aşağıdakine benzer komutlarla Index'lerden (eğer onlar da Corrupt olmadılarsa tabii, bizim senaryomuzda sadece veri Corrupt oldu) veriler kurtarılmalıdır:

SELECT alan1, alan2 FROM tablo WITH (Index=3) ORDER BY id ASC

Nonclustered Index'ler her zaman Clustered Index Key'lerini de barındırdığı için, sadece Nonclustered Index bile böyle bir senaryoda yetecektir...

Harika değil mi?

Ekrem Önsoy

Hiç yorum yok: