Sql Server Veritabanı Bozulmaları Tespit ve Önleme Yöntemleri

Giriş

Birçoğumuzun başına gelen ya da en azından hakkında hikayeler dinlediği Database Corruption, veritabanına ait dosyaların bozulması, veya veritanana ait schema olarak adlandırılan sistem tablo ve yapı şemasının hasar görmesidir. Bu makalede database corruption’ı detaylı olarak tanımlayıp, tespit edilmesi için gereken adımları, engelleme yöntemlerini ve database corruption hakkındaki yanlış bilinenleri anlatmaya çalışacağız.

Makale boyunca veritabanı bozulmasına Database Corruption diyeceğiz. Sql Server içindeki terimleri kullanacağız; Örn: transaction log, backup gibi. Bu makalede anlatılan komutlar Sql Server 2005 ve sonrası için geçerlidir, daha önceki sürümlerde anlatılan işlemlerin bazıları için geçerli olmayabilir.

6428.SQL12_v_rgb

         Database Corruption’ı önlemek neden önemlidir?

Çoğumuz database corruption’ı farkettiğimizde çok geç kalmışızdır. Erken farkettiğimizde de, hemen en erken dönülebilecek yedeğimizden geri döneriz.

Database Corruption olduğunda, çoğu sistemci veya database yöneticisi ne yapacağını bilemez. Bu bilinmezlik süresinin artması demek, daha fazla veri kaybı, kesinti, para kaybı ve hatta iş kaybına neden olabilir. Büyük bir yapıda, her saniye girilen verinin önemli olduğu bir ortamda, Database Corruption meydana geldiğinde eğer panik yaşanıyor ise, işler daha da kötü bir hal alabilir. Panik halindeyken ilk aklınıza gelen RESTART kelimesidir J. Şimdi restart kelimesini aklımıza getirmeden, neler yapabiliriz bunları göreceğiz.

         Corruption Oluştuğu Sırasında Yapılan Hatalar

Sql Serverı yeniden başlatmak – Bu sık yapılan bir hatadır, restart edince düzelir mantığı corruption esnasında işe yaramıyor. Akisen zaman kaybına yol açıyor, serverın hızlı şekilde online olmasını engellemiş oluyorsunuz.

Anında ilk backuptan geri dönmek – hemen en son alınan backuptan geri dönülüp, sorun çözülmek istenir. Tabi artık çok geç kalınmıştır, arada geçen zamanda veri kaybı yaşanmıştır. Ya da SQL sunucusunu  durdurup transaction logları temizleyip, tekrardan sql server’ı başlatmakta bir sürü veri kaybı yaşanması olasıdır.  Detaylı inceleme yapılmadan bu hataya da düşmemek gerekmektedir.

Hasar görmüş database’i Deatach etmek – Hasar görmüş veritabanını zorla deatach etmek istenir. Ama o veritabanı bir daha attach olmayabilir. Kesinlikle tavsiye edilmeyen bir durumdur bu.

Test Ortamında Denemeler Yapılması

Başınıza bir Database Corruption gelmeden kendinize bir test ortamı oluşturmalısınız. Corruption sırasında ne yapacağınızı bilmelisiniz. Antremanlı olmalısınız, yani daha önce gerekli tatbikatları yapıp, hazır olmalısınız. Disaster Recovery (Felaket Senaryosu) hazırlayıp, herhangi bir hata yapmadan, geri dönüşü sağlamalısınız.

Tutarlılık kontrollerini (Consistency Checks) yapmadan önce, mutlaka SQL Server yardım dokümantasyonunu okumalı, konu ile ilgili yayınlanmış olan Microsoft’un yayınlanmış olduğu diğer belgeleri incelemeli veya bir Database uzmanından destek almalısınız.

         Temel Analizlerin Yapılması

Database Corruption meydana geldiğinde, nasıl bir yöntemle kurtarma yapılacağına karar verilmelidir. Sorun donanımsal bir sebepten dolayı olmuş olabilir. Elektrik kesintisi veya serverın fiziksel arızalanması örnek olabilir.

İlk etapta, Sql Server loglarına ve windows event loglarına bakılmalıdır. Disk ile ilgili I/O sorunu veya memory (Ram) tanılama (diagnostics) işlemi yapmanız gerekebilir. Disk veya memory de donanımsal bir sorun var ise, Sql Server düzgün kayıt yapamayacaktır ve bu yüzden corruption’a sebep olan donanımsal problem çözülmediği için aynı corruption’ın tekrarlanması kuvvetle muhtemeldir.

Donanımlarınızın firmware güncellemelerini yapmalısınız. Donanımlarınızdaki basit hatalar, ufak bir firmware güncellemesi ile giderilebilir, çoğu kez atlanan bir durumdur. Firmware’in sadece donanımsal güncelleme olduğunu düşünmek yanlıştır, donanımların daha kararlı çalışması için firmware güncellemeleri, üretici firmalar tarafından yayınlanır.

         1 – Database Corruption Oluşma Sebepleri

Genel kanı olarak, veri tabanı bozulmalarının sebebi disk altyapısı olarak bilinir. Özetle corruption; hafızada canlı şekilde işlenmiş ve fakat diske doğru şekilde aktarılmamış veritabanı değişiklikleri olarak özetlenebilir. Hafıza ve disk arasındaki bu farklılık, SQL Server’ın transactional mimarisi içerisinde çoğu zaman denet altındadır ve corruption olarak adlandırabilecek durumlar en aza indirilmiştir. Corruption SQL Server gibi bir “user mode application” tarafından kontrol edilemeyen bir alt sistemdeki hatanın bubble up (ortaya çıkmai, belirme) etmesi sonucu ortaya çıkar.

Çoğu zaman corruption  I/O hatalarından oluşur, I/O yu yanlızca harddisk üzerindeki bozulma olarak görmek yanlış olur. Alt kıvrımlarına da (alt sistemler) bakmak gerekir;

–          Windows İşletim Sistemi

–          Güvenlik yazılımları (antivirüs)

–          Disk birleştiriciler

–          Disk Encryption (şifreleme)

–          Network kartları, switchler

–          San Controller (Storage Area Network)

–          Raid Controller

–          Harddisk

Bir sürü hareketli parçanın olduğu bir ortamda, bir sürü de kod vardır, kodun olduğu yerde de olası yazılım hatası sayısı artar. Bu konuda değişik teoriler ve görüşler olması ile birlikte Steve McConnell tarafından yazılmış olan “Code Complete” kitabını daha fazla bilgi için inceleyebilirsiniz. Bu kitapta McConnell, her 1000 satırlık kod içerisinde 15 ilâ 50 arasında yazılım hatası ya da bug olabileceğini vurgular.

Server diskleri için üreticiler, 1,5 milyon saat çalışma ömrü biçmişlerdir. Bu da takriben 150-200 seneye denk geliyor. Tabi ki şaşırtıcı rakamlar, bu kadar uzun süre çalışan disk görmek çok zor. Diskleri etkileyen, sıcaklık, mekanik titreşim ve güç kesintileri bu süreyi oldukça aşağıya çekmektedir. Burada bizi ilgilendiren, disklerde bozulmalar oluştuğunda Database Corruption’nın ortaya çıkmasıdır.

Dakikada 15000 devire sahip mekanik bir disk, 1200km/saat gibi hızlara, normal kullanım sırasında erişebilir. Mekanik mikroskobik bir hata bu hızda hareket eden bir yüzey ve onda okuma yazma yapan kafa arasında ciddi hasara sebep olabilir. Bu da verilerimizin kaybolmasına, zarar görmesine neden olmaktadır. Fiziksel olarak disklerin çok ideal seviyelere geldiği söylenemez, böyle bir ortamda corruption yaşanması veya beklenmesi olasıdır. Bu noktada solid state disk olarak bilinen ve son kullanıcı sistemleri ve sunucu sistemlerinde sık kullanılmaya başlanmış olan bu yeni disk teknolojisi tavsiye edilen çözümlerden birisi olarak görülebilir. Ssd diskler ile ilgili de, disklerin ömürleri açısından kesin bir tecrübe yoktur.

Diğer corruption sebeplerine bakarsak; Memory’deki bozulmalar, Sql Server bugları ve bireysel hatalar diyebiliriz. Ram üzerindeki çiplerin bozulması, düzgün veri işleyememesi, buffer (tampon) bölgesinde verileri doğru yazamaması, Sql Server 2000 ve 2005 teki bugları da dahil etmek gerekir, ayrıca veritabanına manuel müdahalelerde bulunmak, bu gibi sebeplerde Database Corruption’a sebep olabilecek nedenlerdir.

         2 – Donanımsal Olarak Alınması Gereken Önlemler

İlk akla gelen diskleri RAID yapmaktır. Raid’in açılımı; Redundant Array of Independent/Inexpensive Disk, Wikipediaya göre tercümesi “Bağımsız/Ucuz Disklerin Artıklı Dizisi”. Çok pahalı server diskleri ile de, çok uygun fiyatlı normal pc diskleri ile de Raid yapabilmek mümkündür.

Raid yapılarını inceleyelim;

–          RAID 0: En az iki disk, veri her iki diske bölünerek yazılır, disklerin bir tanesi bozulduğunda, veriye ulaşılamaz, önerilmeyen bir yapıdır.

–           RAID 5: Bir disk parity disk oluyor, en az 3 diskten yapılıyor. En az bir disk bozulma töleransı var, bozulduğu zaman diski değiştirip, veri kaybı olmadan devam edebiliryorsunuz.

–          RAID 1: Mirroring, aynalamada diyebiliriz, raid1 yapılan diskleri birebir karşılığındaki disklere de aynı verileri yazıyor.

–          RAID 10: Hem Raid 1 hem de Raid 0 yapısını içerir. Raid 1 ile, iki tane Raid 0 yapılmış disk, diğer küme içinde aynı şekilde yapılandırılıp, hem performans hem de riski azaltan bir çözümdür.

Bu Raid uygulamalarını SSD (Solid State Disk) Diskler ile de yapmak mümkündür, çok daha fazla performans alınabilir.

         Yanlış Bilinenler (Örnek Senaryo)

Corruption hakkında bir yanlış anlaşılmadan bahsetmek istiyorum. Senaryoya göre her gece consistency check (tutarlılık testi) yapıyorsunuz. Bu görevin hata verip durduğunu gördünüz, hemen bir consistency check daha yaptınız ama hiçbir hata almadınız. Şimdi ikilemde kalındı değil mi, acaba hangisi doğru, gece hata veren consistency check mi yoksa, sabah sizin çalıştırdığınız mı?

Aslında Sql Server tarafında şunlar yaşandı;

–          Consistency check, indekslemede birkaç bölümün bozulduğunu bildirdi.

–          Bir database admini sadece consistency check kontrolü yapmayacağı için, arkasında hemen index maintenance görevi çalışacağından, bir önceki Database Maintenance Planları makalemizde sırasıyla bu bakımların nasıl çalışacağını belirtmiştik.

–          Index maintenance görevi de, bozulan bölümleri düzeltti, ve indeksleri yeni sayfalara yazmaya başladı. Eski indeksleri de ayırdı.

–          Bu işlemlerden sonra siz geldiniz ve kendiniz bir consistency check görevini çalıştırdınız. Haliyle database corruption ile ilgili hiçbir hata almadınız.

Asıl gece görevi durduran ve hata alınan yer, sabah geldiğinizde gözükmüyor, ve sizde hiçbir sorun yok deyip, bu problemin üzerine daha fazla gitmiyorsunuz. Index bakımlarından dolayı, corruption olan kısımları şimdilik Sql atladı, fakat daha sonra olmayacağı garanti değil. O yüzden bir Consistency check (tutarlılık testi) niz hata veriyor ise, mutlaka tüm ilgili noktaları kontrol etmeye başlamalısınız.

3 – Page Corruption Tespit Edilmesi

Sql Server’ın mekanizmaları, bir I/O  corruption tespit ettiğinde size otomatik olarak bunu bildirebilecek kabiliyete sahiptir. Corruption tespiti için aşağıdaki konulara sırasıyla bakacağız;

–          Torn_Page_Detection (Torn: yırtık veya kopuk)

–          Page CHECKSUM

–          I/O Hataları

–          I/O Hatalarını İzleme

İlk önce Sql Serverdaki “Page” terimi nedir bunu açıklayalaım. Sql Server’ın disk üzerindeki en temel birimine page denir. Disk üzerinde veritabanı dosyları .mdf’ler page bölümlelerine ayrılarak tutulurlar. Sql Server’da page boyutu 8kb’tır. Yani 1 mb’ta 128 tane page var demektir. Her page 96 bitlik header (başlık) bilgisi ile başlar. Başlık bilgisinini içerisinden, page’in numarası, tipi, disk üzerindeki boyutu ve unit ID’si bulunur.

         Page Corruption Korunma Yöntemleri

Sql Server page’leri disk üzerinde korumalı olarak saklar. Bunun faydası, memory tarafından okunmak istenen page’te bir corruption var ise bunu hemen tespit eder.

Bunun sağlamasını aşağıdaki kodlar ile yapabiliriz;

ALTER DATABASE ADVENTURWORKS2012 SET PAGE_VERIFY <…>

TORN_PAGE_DETECTION

CHECKSUM

 

Torn Page Detection

Bir page dosyasının 8kb olduğunu ve 16*512bitten oluştuğunu söylemiştk. Eğer bir güç kesintisi olduğunda veya Sql Serverınızında bulunduğu server beklemedik bir şekilde kapandığında, bu page dosyaları disk üzerine kısmen yazılır. Torn page detection bu eksik dataları tespit etmeye yarar. Diskin üzerindeki fiziksel bozulmaları tespit etmez. Bu özellik sadece page’lerin header (başlık) kısmında ana özelliklere bakarak bozulmayı tespit eder.

 

Page Checksum

Bu özelllik İlk olarak Sql Server 2005’te duyuruldu. Sql Server 2005 ve sonrasındaki tüm sürümlerde desteklenmektedir. Arabellek üzerinde çalışır, buffer pool da denmektedir.

Sql Server’ın disk üzerine yazdığı page’in bilgilerinin son kısmını, page header’daki 4 bytelık değerden hesaplayarak kontrol eder. Aynı şekilde tekrardan hesaplama yaparak ilk header bilgilerini kontrol ederek diske yazıp yazmadığını onaylar. Eğer yazılmada sorun var ise hata olarak geri döner.

Upgrade edilmiş veritabanlarında mutlaka Checksum özelliği aktif edilmelidir. Sql versiyon upgradeleri sonrasında veritabanlarını da yükseltiyoruz. Bu geçişler sırasında checksum kontrollerinin yapılması önem kazanmaktadır.

Page Checksum adımlarına göz atalım;

–          Page dosyası okunabilir durumda mı

–          Consistency Check (tutarlılık) sırasında page okunabilir durumda mı

–          Yedekleme WITH CHECKSUM ile yapılıyor ise, page dosyası okunabilir durumda mı

–          Checksum ile alınan yedek okunabilir durumda mı

Şimdi Sql Management Studio ile Page Corruption korunma ile ilgili ayarları nasıl yapacağımıza bakalım.

Boş bir Query sayfası açıyoruz.

Yeni bir veritabanı oluşturuyoruz. İstersek Object Explorer – Databases’ın üzerinde sağ tıklayarak “New Database” diyebiliriz. Yeni bir veritabanı oluşturmayı T-Sql kodları ile yapmayı görelim.

Aşağıdaki kodu yazıyoruz, F5 veya Execute e basarak çalıştıyoruz.

Sql_Cor_1

Veritabanımız oluştu, kontrol etmek için, Object Explorer menüsünün altında, Databases kısmına geliyoruz. Görüldüğü gibi TICARET veritabanımız oluşmuş.

Sql_Cor_2

 

Veritabanını oluşturduktan sonra, Page Protection ayarlarına bakacağız. Bu sefer ilk önce Onject Explorer üzerinden bakalım.

TICARET veritabanımıza sağ tıklayıp Properties (özellikler) kısmına geliyoruz. Soldaki menüde Options’ı seçtikten sonra, sağ taraftaki menüde Recovery kısmına kadar inelim. Page verify varsayılan olarak CHECKSUM seçili olarak gelmektedir.

Checksum’ın değiştirilmesi pek önerilmez, Torn_Page_Detection, yukarda da anlattıldığı gibi, sadece headerlara baktığından varsayılan olarak Page Verify olarak gelmemektedir.

Sql_Cor_3

 

Bu kontrolü kod tarafında nasıl yapıyoruz; TICARET veritabanının page_verify_option sonucu için aşağıdaki kodu yazıp execute ediyoruz.

Sql_Cor_4

 

Page verify seçeneğini kod tarafında değiştirmek istersek eğer;

Sql_Cor_5

 

Değişip değişmediğini, yukarıdaki kodumuz ile kontrol edebiliriz.

İlave olarak belirtmek istediğim, sistem veritabanlarından biri olan model veritabanında page verify seçeneğini Torn_Page_Detection yapar iseniz, bundan sonra oluşturacağınız tüm veritabanlarında bu şekilde  kalacaktır.

 

I/O Hataları (Input-Output)

Üç farklı I/O  hatasından bahsedeceğiz. Bunlar 823, 824 ve 825 nolu hatalar.

–          823: Hard diye tabir edilen hatadır. Windows sistem logları ve Sql logları bu hatayı geri döner. Okuma ve yazma fonksiyonlarının çalışmadığını belirtir. Sql serverda büyük bir sorun olduğunu belirtir. Mantıksal tutarlılık problemi olarakta adlandırılır. Donanımsal bir sorundur. Input-Output dediğimiz girdi-çıktıların transfer yapılamadığını ve donanımların (harddisk v.b.) değiştikten sonra hemen Consistency  Check (tutarlılık testi) yapılmasını ön gören bir hatadır..

–          824: Bu hata 823’e göre daha soft (daha hafif) kalıyor diyebiliriz. Sql Server bu sefer disk üzerinden okuma yapabiliyor ama page tarafında bir hata olduğunu belirtiyor. Bu da Checksum’lar ile kontrol edilmektedir. I/O subsystemlerin (alt sistemlerinin, makalenin başında bahsetmiştik) yol açabileceği bir hatadır. Donanımlarla ilgili testler yapılmalı, gerekli görülen donanımlar değiştirilmelidir.

–          825: RetryRead yani tekrardan okuma ihtiyacı duyulduğunu belirten hatadır. Sql disk üzerinden verilerinizi okuduğunu ama diskinizi değiştirmez iseniz Corruption yaşayabileceğinizi bildiren bir hatadır. Disklerinizi, disk controllerlarınızı kontrol etmenizi belirten uyarıcı bir hatadır.

823 ve 824 nolu hataların kayıtları, msdb  veritabanındaki suspect_pages tablosuna kayıt edilir. Suspect yani şüpheli kayıtlar olarakta aklımızda tutabiliriz. 1000 satıra kadar 824 kod nolu hataları tutar. Suspect_pages tablosunda hata kayıt tipleri aşağıdaki gibidir.

Error description – Hata açıklaması event_type value
823 error caused by an operating system CRC error or 824 error other than a bad checksum or a torn page (for example, a bad page ID) (Başlık bilgisi hatalı olan kayıtlar gibi…) 1
Bad checksum – Checksumları tutmayan hata veren kayıtlar 2
Torn page – Bozuk pageleri belirtir 3
Restored (The page was restored after it was marked bad) – Geri yüklenmiş 4
Repaired (DBCC repaired the page) – Tamir edilmiş pageleri belirtir 5
Deallocated by DBCC – Consistency Check ile birleştirilmiş kayıtlar 7

En fazla 1000 satır kayıt saklanabildiğinden, 4, 5 ve 7 nolu hatalara ait kayıtlar silinebilir. Bunun için belirli periyodlarda çalışabilecek bir Agent job yazılabilir.

Detayları verdikten sonra 824 nolu hatayı Sql Management Studio ortamında oluşturmaya çalışıp, gösterelim. 823 nolu hata donanımsal olduğundan dolayı bu makalede örnek göstermek zor olacaktır. 824 nolu hatanın oluşması daha olasıdır. Bu hatayı Sql Server üzerinde nasıl görebiliriz buna bakalım.

İlk önce yeni bir veritabanı oluşturalım, adına MUHASEBE diyorum

CREATE DATABASE [MUHASEBE] ON PRIMARY (NAME = N'MUHASEBE',
					 FILENAME = N'C:\DATA\MUHASEBE.mdf')
LOG ON
		( NAME = N'MUHASEBE_LOG', 
		  FILENAME = N'C:\DATA\MUHASEBE_LOG.ldf');
GO

Execute veya F5 ile kodu çalıştırdıktan sonra MUHASEBE isimli veritabanımız oluştrulmuş oldu.

Veritabanımıza basit bir tablo ve tablonun içinede iki tane alan ekleyelim.

USE [MUHASEBE];
GO

CREATE TABLE muhdata
		( [c1] INT IDENTITY,
		  [c2] CHAR (7000) DEFAULT 'ccc');
GO

--Rastgele 100 kayıt girelim.
INSERT INTO [dbo].[muhdata] DEFAULT VALUES;
GO	100

--Bakalım 100 adet kayıt oluşmuş mu;
DBCC IND (N'MUHASEBE',N'muhdata', -1);
GO

<a href="http://www.yavuzfilizlibay.com/wp-content/uploads/2014/02/Sql_Cor_6.jpg"><img class="alignnone size-full wp-image-15294" alt="Sql_Cor_6" src="http://www.yavuzfilizlibay.com/wp-content/uploads/2014/02/Sql_Cor_6.jpg" width="1155" height="431" /></a>

Görüldüğü üzere 100 adet satır kaydım oluşmuş.

Şimdi bir kaydı bozmak için seçelim, 7. satırdaki PagePID’si 145 olanı seçiyorum, üzerine yazacak queryi aşağıdaki gibi hazırlayıp execute diyoruz,

ALTER DATABASE [MUHASEBE] SET SINGLE_USER;
GO
DBCC WRITEPAGE (N'MUHASEBE', 1, 145, 0, 2, 0x0000, 1);
GO
ALTER DATABASE [MUHASEBE] SET MULTI_USER;
GO

Msdb altındaki hata loglarını ve suspect_pages (kararsız pageler) i temizleyelim, , senaryomuza göre hata logları yok elimizde, normal zamanda da hata loglarında bir şey olmayabilir

DELETE FROM [msdb].[dbo].[suspect_pages];
EXEC sp_cycle_errorlog;
GO

Bakalım veritabanımız bozulmuş mu, tüm verileri sorgulayalım
SELECT * FROM [MUHASEBE].dbo.muhdata

Sorgulama sonucu aşağıdaki gibi geldi, yukarda da bahsettiğimiz 824 nolu hatayı aldık.

Sql_Cor_7

Bu hatayı error loglarda görebiliyor muyuz, kontrol edelim.

Management – Sql Server Logs – Current ile başlayan logumuzu açalım. Hata en üstte karşımıza çıktı.

Sql_Cor_8

824 No’lu I/O hatamız Windows Application loglarına da gelmektedir. Aşağıdaki gibi kontrolünü yapabilirsiniz.

Sql_Cor_9

Application logları kontrol ettikten sonra, msdb deki suspect_pages’lere göz atalım.

Seçmiş olduğumuz page_id 145 geldi, evetn type 2 (Bad checksum), error_count “1” kaç kere bu hatanın alındığını gösteriyor, last_update_date’te bozulmamnın ne zaman gerçekleştiğini gösteriyor.

Sql_Cor_10

825 Hatası Read – Retry

825 hatası ilk Sql 2000’de, kısıtlı şartlar olarak karşımıza çıktı. Sql 2005’te veri dosyaları page’lerinde detaylı olarak kullanıldı. Read – Retry hatası, veri okuma başarısız olursa 4 kere denenir, sonuncusunda da veri okunamaz ise 825 nolu hatayı verir. 825 no’lu hata I/O hatası gibi loglara yazmaz. Aslında erken haberci gibidir, 823 ve 824 nolu I/O hatalarının ön habercisi de diyebiliriz. Bu hatayı bir dahaki sefere aldığınızda iş işten geçmiş olabilir, bu yüzden hemen tedbirler alınmalı ve gerekli kontroller yapılmalıdır.

Page hatalarını engellemenin diğer bir yoluda, Database mirroring yapmaktır. Bazı veritabanı bozulmalarının bazılarını otomatik olarak düzeltebiliyor. İkincil replika denilen, mirror Sql sunucu üzerindeki pageler düzeltmelerde kullanılıyor.

Otomatik page repair ile ilgili detaylı bilgi için: http://technet.microsoft.com/en-us/library/bb677167.aspx

Memory Hataları – Bozulmaları

Buffer pool, tampon bölge veya tampon saha da denilen bu alanda, veriler önce burada toplanır daha sonra memory’e yazılır. Buffer pool periyodik olarak pagelerin kontorlünü yapar, doğru olan pageleri onaylar.

Sql Server 2014 ile Buffer Pool Extension özelliği gelecek, detaylı bilgi için: http://msdn.microsoft.com/en-us/library/dn133176(v=sql.120).aspx

Windows Server 2012 üzerine kurulu olan Sql Server 2012, otomatik memory düzeltmelerini desteklemektedir.

I/O Hatalarını İzleme

I/O Hatalarını takip etmek veya takip etmeye çalışmak, zaman kaybıdan başka bir şey değildir. Hem vaktiniz boşa gidecektir, hem de takip edilmesi zor bir durumdur.

Otomatik olarak I/O hatalarını izleme daha bir yoldur, bunun için;

–          Sql Agent Alarmları ayarlanabilir. Hata olduğunda mail göndermesini sağlayabilirsiniz.

–          SCOM, System Center Operations Manager ile alarm ayarlayabilirsiniz.

–          3. Parti Yazılımlar, Sql server için izleme yazılımları ile yapabilirsiniz.

Alarmları oluştururken, Severity 19 ve üzeri olanları seçmeniz yeterli olacaktır.

Sql Agent Alarmları oluşturnak için, Bakım Planları makalesinden detaylı bilgi alabilirsiniz; http://www.cozumpark.com/blogs/sql/archive/2014/01/26/sql-server-2012-maintenance-planlari.aspx

4 – Tutarlılık Kontrolleri – Consistency Checks

Page protection seçenekleri ile, Sql Server’ın otomatik olarak page bozulmalarını düzeltmesini yukarıda görmüştük. Düzenli olarak Consistency Check (Tutarlılık testi) lerinin uygulanması, bozulmaların tespitinde bize yardımcı olacaktır. Böylelikle veri kayıplarımızı da en aza indirgeyebiliriz.

Sql Serverdaki tutarlılık, bir verinin kümelenmiş indeks noktalarının, tüm kümelerindeki anahtar değerlerinin birbirleri ile örtüşmesi demektir. Genelde DBCC CHECKDB komutu kullanılarak bu testler gerçekleştirilir. Bu testleri ne kadar sıklıkla yapmalıyız ya da hangi veritabanlarında bu testleri yapmalıdır, bu konulara açıklık getirmeye çalışalım.

Tüm veritabanlarının bu kontrolden geçmesi gerekir, read-only olanların ve sistem veritabanlarının da (msdb,master, model, tempdb) dahil edilmesi gerekir. Msdb veritabanı çok önemlidir, burada Sql Agent Jobs, zamanlanmış görevler, yedekleme geçmişleri ve sql serverımız ile ilgili birçok veri burada da tutulur.

Consistency Checks’leri nasıl çalıştırabiliriz. Sql Server üzerinden 3 farklı yöntem ile çalıştırabiliriz;

–          Manuel bir şekilde

–          Sql agent üzerinde bir script yazarak

–          Sql Server Maintenance Planlar kapsamında Consistency Check çalıştırabiliriz.

Bu 3 yönteme ilave olarak, bir Sql Server duayeni olan Ola Hallengren’nin Sql Server scriptlerinden de faydalanabilirsiniz.

Sql Agent üzerinde bir Consistency Check Job nasıl oluşturulur onu görelim;

SSMS üzerideki Object Explorer’dan Sql Server Agent’a geliyoruz. Burada Jobs kısmına sağ tıklayıp “New Job” diyoruz.

Sql_Cor_11

New Job ekranında, General sekmesinde, görevimize bir isim veriyoruz. Category kısmında da “Database Maintenance”i seçiyoruz.

Sql_Cor_12

Schedules sekmesine geliyoruz, burada “New” dedikten sonra karşımıza “New Job Schedule” penceresi açılacak. Bu pencerede görevimizin ne zaman çalışacağını ayarlıyoruz. Günlük olarak saat sabah 03:00’te yapılmasını aşağıdaki gibi ayarladım.

Sql_Cor_13

Zamanlayıcıyı ayarladıktan sonra “Steps” sekmesine geliyoruz. Burada görevde çalışacak komutları ayarlayacağız. “New” butonuna tıklıyoruz, karşımıza “New Job Step” ekranı açıldı. Önce step’e isim verelim. Type T-Sql olarak kalıyor, bir sorgu cümlesi çalıştıracağımızda bu şekilde kalacak. Aşağıdaki gibi Consistency Check komutumuzu yazıp “OK”e basıyoruz.

Sql_Cor_14

Bu görevimiz ile ilgili bir bildirim istiyorsak, “Notifications” sekmesine geliyoruz. Burada E-mail seçeneğinden, daha önce oluşturduğum operatörümü seçiyorum. “When the job fails” yani bu görev başarısızlıkla sonuçlandığında mail gönderecek. Windows Application (uygulama) event loglarına da yazmasını istiyorsanız, “Write to the Windows Application event log” seçeneğini işaretlemeniz gerekiyor. Operatöre mail gönderme konusu, bu makalenin kapsamı dışında olduğundan,  bu konu hakkında detaylı bilgiyi bir önceki makalemiz olan “Sql Server Maintenance Planları” makalemizden öğrenebilirsiiniz.

Sql_Cor_15

Ok diyerek görevimizin yapılandırmasını tamamlamış olduk. Her gece saat 03:00’te tutarlılık testimiz çalışacak. Sql Server Agent – Jobs kısmına gelerek, görevimizin oluştuğunu kontrol edebilirsiniz.

Sql_Cor_16

Bu Job’umuzun çalışıp çalışmadığına “History” geçmiş kısmında bakalım. Sql Server Agent – Jobs kısmında sağ tıklayalım, açılan menüde “View History”e tıklayalım.

Sql_Cor_17

Job’umuz çalışmış ve başarılı olmuş. Job name kısmında Job’umuzun üzerine tıklarsak özellikler bölümü açılır.

Sql_Cor_18

Şimdi de veritabanımız üzerinde bozulmalar oluşturalım ve sonrasında tutarlılık testimizi çalıştıracağız.

TICARET veritabanında id ve abc karakteri char (7000) olarak belirleyip, 30 kez aynı kayıttan okuşmasını sağlıyorum.

USE TICARET
GO

CREATE TABLE [VERILER]
			 ([c1] INT IDENTITY,
			  [c2] CHAR (7000) DEFAULT 'ABC');
GO

INSERT INTO [VERILER] DEFAULT VALUES;
GO 30

--Tablodaki pageleri listeliyoruz;
DBCC IND (N'TICARET', N'VERILER', -1);
GO

Sonuç aşağıdaki gibi;

Sql_Cor_19

Bir page’i seçip bozulmasını sağlayacağız, PagePID’si 144 olanı seçiyorum, aşağıdaki gibi kodu hazırlayıp Execute diyoruz;

ALTER DATABASE [TICARET] SET SINGLE_USER;
GO
DBCC WRITEPAGE (N'TICARET', 1, 144, 0, 2, 0x0000, 1);
GO
ALTER DATABASE [TICARET] SET MULTI_USER;
GO

Kod çalıştıktan sonra aşağıdaki mesajı veriyor;

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Tablomuzda bozulma işlemi tamamladık, artık bozuk bir tablomuz var, şimdi Sql Agent Job’umuza gidelim ve Tutarlılık Testimizi çalıştıralım. TutartlılıkTesti’ne sağ tıklayıp “Start Job at Step”e tıklıyorum.

Sql_Cor_20

Görevimiz hata verdi, demek ki bozulmayı tespit etti.

Sql_Cor_21

Sql Server Agent – Jobs sağ tıklayıp “View History”i açıyoruz. Görüldüğü gibi TutarlılıkTesti görevimiz hata vermiş, yanında + ile genişletip açılan satırı seçiyoruz. Detaylı olarak neden hata verdiğini aşağıdaki bölümde bize anlatıyor. PagePID’si 144 te bir bozulma olduğunu belirtmiş. Bunu deneme olarak yaptık, çalışan bir sistemde de bu bilgi çok işinize yarayacaktır. Burayı doğru okumak önemlidir.

Sql_Cor_22

TutarlılıkTesti görevimizi her gece 03:00’te çalıştıracak şekilde ayarlamıştık, bunu örnek olarak gösterdik tabiki. Tutarlılık testlerimizi ayarlacağımız sıklık yapımıza göre değişkenlik göstermektedir. Maddeler halinde sıralayacak olursak;

–          I/O Altsistemimiz (diskler, network v.b.) ne kadar stabil

–          Yedekleme stratejimiz, günlük, haftalık, aylık. Günlük veya saatlik bir strateji var ise, tutarlılık testi buna göre daha sık olmalıdır.

–          Tutarlılık testi yapılırken, çok fazla kaynak kullanır, gün içinde yapılması sunucuyu yoracaktır.

Ayrıca;

Bir veritabanı bozulması olduğunda, kabul edilebilir kapalı kalma zamanı ve veri kaybının daha önceden belirlenmesi gerekmektedir. Verilerinizin 1 gün bile telafi edilmesi zor ise, tutarlılık testlerinin sayısını arttırmanız gerekebilir. Bunun içinde uygun zaman gerekiyor, bu konuda doğru stratejiler en az sistem kapalı kalma zamanı ve en az veri kaybı demektir.

En az haftada bir kere tutarlılık testininin yapılmasının gerekli olduğunu tavsiye ediyorum.

Tutarlılık testi, çok fazla sistem kaynağı harcadığından, production yani ana serverımız üzerinde bu testi yapmak istemeyen bir çok sistemci oluyor. Veritabanlarının yedekleri alınıyor, diğer 2. Serverda bu yedekler restore ediliyor ve bu yedek server üzerinde tutarlılık testi çalıştırılıyor. Bu yanılgıdan başka bir şey vermez. Esas ana sunucuda belki de; I/O altsistemde bir sorun var, buradaki veritabanlarının tutarlılık testlerini başka bir serverda yapmak bize doğru tespitleri yapmamızda bir fayda sağlamayacaktır.

Benzer bir şekilde, tutarlılık testini replikasyon üzerindeki mirror veritabanlarında yapmak ta bize gerçek sonuçları vermeyecektir. Birincil sunucu ile ikincil sunucunun I/O alt sistemleri farklı olduğundan, 1. Ana sunucu yorulmasın diye 2. Yedek replika sunucuda tutarlılık testi yapmak, sadece replika sunucuyla ilgili doğru bilgileri verir.

Checksum ile Yedek Alma

Yedek alırken Checksum, (matematikteki sağlama yapma yöntemi de diyebiliriz) ile yedek alırksak, bir nevi tutarlılık testini yedek alma sırasında yapmış oluruz. Her zaman bu şekilde yedek almak en iyi yöntemdir. Yedek alma işlemi biraz uzun sürdüğünden genellikle bu Checksum ile yedek alma yöntemi tercih edilmez. Veritabanı geri yüklenirken de “VERIFY ONLY WITH CHECKSUM” seçenekleri ile kontrol edilerek, geri yükleme işlemi sağlanabilir. Bu işlemi Tutartlılık testi ile karıştırmamak gerekir, checksum ile yedek alınca aynı zaman da tutarlılık testini de yapılmış olur gibi yanlış bir sonuca varılmaması gerekir.

Checksum ile yedek almaya örnek yapalım;

İki tane veritabanı oluşturalım, 1. Nin ismi SATIS, 2. nin ismi de SATIS2 olsun, 2 alandan oluşan da bir tablo oluşturup, içine 30 satır veri girelim. Aşağdaki kodumuzu query sayfamıza yazıp Execute diyoruz. Bu veritabanlarını Management Studio üzerinde de oluşturabilirsiniz.

CREATE DATABASE [SATIS] ON PRIMARY (NAME = N'SATIS',
			FILENAME = N'C:\DATA\SATIS.mdf')
LOG ON
		( NAME = N'SATIS_LOG', 
		  FILENAME = N'C:\DATA\SATIS_LOG.ldf');
GO

USE SATIS;
GO

CREATE TABLE satisdata
				( [c1] INT IDENTITY,
				  [c2] CHAR (7000) DEFAULT 'ccc');
GO

INSERT INTO [dbo].[satisdata] DEFAULT VALUES;
GO	30

--2. veritabanımız içinde bu kodu kullanıyoruz;

CREATE DATABASE [SATIS2] ON PRIMARY (NAME = N'SATIS2',
			FILENAME = N'C:\DATA\SATIS2.mdf')
LOG ON
		( NAME = N'SATIS2_LOG', 
		  FILENAME = N'C:\DATA\SATIS2_LOG.ldf');
GO

USE SATIS2;
GO

CREATE TABLE SATIS2data
				( [c1] INT IDENTITY,
				  [c2] CHAR (7000) DEFAULT 'ccc');
GO

INSERT INTO [dbo].[SATIS2data] DEFAULT VALUES;
GO	30

--SATIS2 üzerinde bozulma yapacağız. Dbcc IND ile page’ler e bakalım.

DBCC IND (N'SATIS2', N'SATIS2data', -1);
GO

235 PagePID’li kaydı seçiyorum;

Sql_Cor_23

Veritabanın bozulması için aşağıdaki kodu yazalım;

ALTER DATABASE [SATIS2] SET SINGLE_USER;
GO
DBCC WRITEPAGE (N'SATIS2', 1, 235, 0, 2, 0x0000, 1);
GO
ALTER DATABASE [SATIS2] SET MULTI_USER;
GO

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

--Msdb deki Suspect_pages tablosunda da hata loglarını temizleyelim;

DELETE FROM msdb.dbo.suspect_pages;
EXEC sp_cycle_errorlog;
GO

--Bu işlemlerden sonra yedeklerimiz alalım, her iki veritabanı için yedeğimi alıyorum;

BACKUP DATABASE SATIS 
TO DISK = N'C:\DATA\SATIS.bak'
WITH INIT;
GO

BACKUP DATABASE SATIS2 
TO DISK = N'C:\DATA\SATIS2.bak'
WITH INIT;
GO

Yedekler alındı;

Processed 352 pages for database ‘SATIS’, file ‘SATIS’ on file 1.

Processed 2 pages for database ‘SATIS’, file ‘SATIS_LOG’ on file 1.

BACKUP DATABASE successfully processed 354 pages in 0.049 seconds (56.441 MB/sec).

Processed 352 pages for database ‘SATIS2’, file ‘SATIS2’ on file 1.

Processed 2 pages for database ‘SATIS2’, file ‘SATIS2_LOG’ on file 1.

BACKUP DATABASE successfully processed 354 pages in 0.039 seconds (70.725 MB/sec).

 

Yedeklerimizi CHECKSUM ile alalım, ilk veritabanımda bozukluk yoktu, ilk önce SATIS veritabanının yedeğini alıyorum;

BACKUP DATABASE SATIS 
TO DISK = N'C:\DATA\SATIS_CHECKSUM.bak'
WITH INIT, CHECKSUM;
GO

Bir sorun yok, Checksum ile yedeği aldı,

 

Processed 352 pages for database ‘SATIS’, file ‘SATIS’ on file 1.

Processed 2 pages for database ‘SATIS’, file ‘SATIS_LOG’ on file 1.

BACKUP DATABASE successfully processed 354 pages in 0.034 seconds (81.126 MB/sec).

Bozuk olan SATIS2 veritabanının CHECKSUM ile yedeğini alıyorum;

BACKUP DATABASE SATIS2 
TO DISK = N'C:\DATA\SATIS2_CHECKSUM.bak'
WITH INIT, CHECKSUM;
GO

Hatamızı alıyoruz, veritabanı bozulduğundan yedeği alamadı,

Msg 3043, Level 16, State 1, Line 1

BACKUP ‘SATIS2’ detected an error on page (1:235) in file ‘C:\DATA\SATIS2.mdf’.

Msg 3013, Level 16, State 1, Line 1

BACKUP DATABASE is terminating abnormally.

SATIS2 üzerinde yedeği zorlayarak almaya çalışalım, CONTINUE_AFTER_ERROR komutunu kullanarak, hatadan sonra devam et diyelim;

BACKUP DATABASE SATIS2 
TO DISK = N'C:\DATA\SATIS2_CHECKSUM.bak'
WITH INIT, CHECKSUM, CONTINUE_AFTER_ERROR;
GO
Yedek aldı, fakat damage database yani bozuk veritabanının yedeğini aldığını belirtti,
Processed 352 pages for database 'SATIS2', file 'SATIS2' on file 1.
Processed 2 pages for database 'SATIS2', file 'SATIS2_LOG' on file 1.
BACKUP WITH CONTINUE_AFTER_ERROR successfully generated a backup of the damaged database. Refer to the SQL Server error log for information about the errors that were encountered.
BACKUP DATABASE successfully processed 354 pages in 1.541 seconds (1.789 MB/sec).

Sql Server Error Loglarına bakalım.

Managenment – Sql Server Logs altındaki Current olan logu açıyoruz.

Sql_Cor_24

Loglara hataların geldiği görülüyor.

Sql_Cor_25

Yedek dosyamızın bütünlüğünü (Integrity) kontrol edelim;

 İlk SATIS olana bakıyoruz,

RESTORE VERIFYONLY
FROM DISK = N'C:\DATA\SATIS.bak';
GO

Bunda bir sorun yok,

The backup set on file 1 is valid.

SATIS2’ye de bakalım,

RESTORE VERIFYONLY
FROM DISK = N'C:\DATA\SATIS2.bak';
GO

Bunda da bir sorun yok,

The backup set on file 1 is valid.

Checksum ile alınan ilk SATIS yedeğine bakalım;

RESTORE VERIFYONLY
FROM DISK =  N'C:\DATA\SATIS_CHECKSUM.bak'
GO

İlk olanda sorun yok,

The backup set on file 1 is valid.

SATIS2 Checksum ile alınan yedeğe bakıyoruz,

RESTORE VERIFYONLY
FROM DISK =  N'C:\DATA\SATIS2_CHECKSUM.bak'
GO

Hata bilgisi geliyor,

The backup set was written with damaged data by a BACKUP WITH CONTINUE_AFTER_ERROR.

Tutartlık testi ile checksumlı yedek alma birbirine karıştırılmamalıdır. Checksum ile aldığınız yedek, tutartlılık testinin yerini tutmaz. Geçerli bir yöntem değildir. Pageler disk üzerine yazılırken buffer pool’u kullanır, pagelerin checksum’ı geçerli olupta içeriği bozulmuşta olabilir. Bunu sadece DBCC kullanarak tutarlılık testi kontrol edebilir.

 

5 – DBCC CHECKDB Komutları ve Kullanımı

Tutarlılık testi DBCC CHECKDB komutu ve bunun alt komutları ile yapılmaktadır. Technet’teki makalesi için: http://technet.microsoft.com/en-us/library/ms188796.aspx

Kullanım olarak oldukça basit bir koda sahiptir. DBCC CHECKDB (N’veritabaniadi’) yazıp çalıştırdığınızda, veritabanındaki tüm pageleri okur. Checkdb komutu yoğun bir şekilde işlemci, memory ve I/O kaynaklarını kullanır. Gün içinde yapılması, Sql Server’ı yavaşlatacaktır. Sql Server 2000 de çalıştırıldığında kilitlenmeler yaşanmaktaydı, Sql Server versiyonları geliştikçe Checkdb işlevi de daha da hızlandı.

Dbcc Checkdb genel olarak yaptıkları, işlemsel ilerleme raporları, veri saflığı (purity) kontrolleri, “Last known good” diye tabir edilen bilinen en iyi boot page kontrolleridir.

Diğer DBCC CHECK Komutlarına bakalım;

DBCC CHECKALLOC

Veritabanına ayrılmış veya tahsis edilmiş de diyebiliriz, yapılarında tutarlılık kontrolleri yapar. Ayrılmış yapıların veritabanlarında geçerli olması gerekmektedir. İki tablonun aynı veri dosyasındaki pagelerininin olmaması gerekir, bu şekilde olursa komut çalışmaz. Pek rastanan bir durum değildir. DBCC CHECKDB’nin fonksiyonel bir bölümüdür.

DBCC CHECKTABLE

Checktable komutu tablo ve indekslerde tutartlılık kontrolü yapar. Data dosyasındaki her page ve indeks için geçerli yapıda olup olmadığını, Cluster olmayan her bir indeksin tablodaki değeri ile eşleşmesini, İndeks anahtarlarının sıralamasını ve FILESTREAM verisinin tablo ile doğru bağlantıda olup olmadığını kontrol etmektedir.

DBCC CHECKCATALOG

Sistem katalogları arasındaki ilişkiyi kontrol eder. Kolonlardaki metadata ile tablolardaki metadataların ilişkilerine bakar.

DBCC CHECKFILEGROUP

Filegrouplarda tutartlık testi yapmaktadır. Veritabanlarında ilişkilendirilmiş kontrolleri sağlar. Tablo ve indeks bölümlerinde tutarlılık testleri yapar. Checkdb yapısına benzer bir yapıya sahiptir.

DBCC CHECKIDENT

Bu komut, tablodaki kimlik (indentity) değerini sıfırlar ve kontrol eder. Dbcc Checkdb’nin fonksiyonel bir bölümü değildir.

DBCC CHECKCONSTRAINTS

Tablolardaki dış anahtarların (foreign key) ve kısıtlamaların (constraints) geçerli olup olmadığını kontrol eder. Checkident gibi Dbcc Checkdb’nin fonksiyonel yapısından değildir.

Genel olarak kullanılan komutları özetlemiş olduk. Sql Server’ın bulunduğu sunucuyu yeniden başladığında, Windows loglarında “CHECKDB for database ‘master’ finished without errors on…..” diye loglar gelir, her veritabanı için bunu görürsünüz. Sql server her açıldığında zaten Checkdb yapıyor diye yanlış bir kanıya varırsınız, aslında böyle olmuyor. Bu loglar, en son düzgün bir şekilde çalışmış olan Checkdb görevinin sonuçlarıdır, Sql Server açıldığında otomatik olarak Checkdb yaptığını göstermez. Bu yanlışlık silsilesi daha devam eder ve replikasyon serverlarına da Checkdb komutlarının gittiği zannedilir, ama böyle bir durum olmaz.

Sunucunun yeniden başladığında en son düzgün kontrol edilen Checkdb (Last Known Good Time) ile ilgili bir örnek yapalım;

Yeni bir veritabanı oluşturuyoruz,

 -- Yeni bir veri tabanı oluşturuyoruz
CREATE DATABASE [DEPO] ON PRIMARY 
	(NAME = N'DEPO', FILENAME = N'C:\DATA\DEPO.mdf')
LOG ON 
	( NAME = N'DEPO_LOG', FILENAME = N'C:\DATA\DEPO_LOG.ldf');
GO

Yeni veritabanımızda Checkdb’yi çalıştıralım, hata almayacağız,

-- DBCC CHECKDB komutunu çalıştıralım
DBCC CHECKDB (N'DEPO') WITH NO_INFOMSGS;
GO
----------------
Command(s) completed successfully.

Dbcc ile trace log’u dbinfo ile alacağız, bu bir nevi veritabanının dump dosyası olarakta nitelendirebiliriz. Komutun çıktısında da göreceğiniz gibi (kırmızı ile işaretlendi) en son ne zaman Checkdb yapıldığı bilgisini bize veriyor.

Traceon ilgili izleme bayrakları için: http://technet.microsoft.com/tr-tr/library/ms187329.aspx

-- En iyi son zaman (Last Known Good Time) 
DBCC TRACEON (3604)
DBCC DBINFO (N'DEPO');
GO
------------------------------------------
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

DBINFO STRUCTURE:

DBINFO @0x000000000FB1D620

dbi_version = 706                   dbi_createVersion = 706             dbi_SEVersion = 0
dbi_dvSplitPoint = 0:0:0 (0x00000000:00000000:0000)                      
dbi_dbbackupLSN = 0:0:0 (0x00000000:00000000:0000)                       
dbi_LastLogBackupTime = 1900-01-01 00:00:00.000                          
dbi_nextseqnum = 1900-01-01 00:00:00.000                                 dbi_status = 0x00010000
dbi_crdate = 2014-02-18 22:09:14.337dbi_dbname = DEPO                   dbi_dbid = 14
dbi_cmptlevel = 110                 dbi_masterfixups = 0                dbi_maxDbTimestamp = 2000
dbi_dbbackupLSN = 0:0:0 (0x00000000:00000000:0000)                       dbi_RebuildLogs = 0
dbi_differentialBaseLSN = 0:0:0 (0x00000000:00000000:0000)               dbi_RestoreFlags = 0x0000
dbi_checkptLSN = 35:66:1 (0x00000023:00000042:0001)                      dbi_dbccFlags = 2
dbi_COWLastLSN = 0:0:0 (0x00000000:00000000:0000)                        
dbi_DirtyPageLSN = 35:66:1 (0x00000023:00000042:0001)                    dbi_RecoveryFlags = 0x00000000
dbi_lastxact = 0x32b                dbi_collation = 53274               dbi_relstat = 0x61000000
dbi_familyGUID = 4c21449a-0bbd-401d-9958-f30a98c3d289                    dbi_maxLogSpaceUsed = 388608

dbi_recoveryForkNameStack

entry 0

hex (dec) = 0x00000000:00000000:0000 (0:0:0)                             
m_guid = 4c21449a-0bbd-401d-9958-f30a98c3d289                            

entry 1

hex (dec) = 0x00000000:00000000:0000 (0:0:0)                             
m_guid = 00000000-0000-0000-0000-000000000000                            
dbi_differentialBaseGuid = 00000000-0000-0000-0000-000000000000          dbi_firstSysIndexes = 0001:00000014
dbi_oldestBackupXactLSN = 0:0:0 (0x00000000:00000000:0000)               
dbi_versionChangeLSN = 0:0:0 (0x00000000:00000000:0000)                  dbi_mdUpgStat = 0x0004
dbi_category = 0x0000000000000000   dbi_safetySequence = 0              
dbi_dbMirrorId = 00000000-0000-0000-0000-000000000000                    
dbi_pageUndoLsn = 0:0:0 (0x00000000:00000000:0000)                       dbi_pageUndoState = 0
dbi_disabledSequence = 0            dbi_dbmRedoLsn = 0:0:0 (0x00000000:00000000:0000)
dbi_dbmOldestXactLsn = 0:0:0 (0x00000000:00000000:0000)                  dbi_CloneCpuCount = 0
dbi_CloneMemorySize = 0             dbi_updSysCatalog = 1900-01-01 00:00:00.000
dbi_LogBackupChainOrigin = 31:80:37 (0x0000001f:00000050:0025)           
<span style="color: #ff0000;">dbi_dbccLastKnownGood = 2014-02-18 22:10:52.573 </span>                         dbi_roleSequence = 0
dbi_dbmHardenedLsn = 0:0:0 (0x00000000:00000000:0000)                    dbi_localState = 0
dbi_safety = 0                      dbi_modDate = 2014-02-18 22:09:14.337
dbi_verRDB = 184552376              dbi_lazyCommitOption = 0            
dbi_svcBrokerGUID = a342014f-f215-42f8-ae9d-253b09a5189a                 dbi_svcBrokerOptions = 0x00000001
dbi_dbmLogZeroOutstanding = 0       dbi_dbmLastGoodRoleSequence = 0     dbi_dbmRedoQueue = 0
dbi_dbmRedoQueueType = 0            dbi_rmidRegistryValueDeleted = 0    dbi_dbmConnectionTimeout = 0
dbi_fragmentId = 0                  dbi_AuIdNext = 1099511627860        
dbi_MinSkipLsn = 0:0:0 (0x00000000:00000000:0000)                        dbi_commitTsOfcheckptLSN = 0
dbi_dbEmptyVersionState = 0         dbi_CurrentGeneration = 0           
dbi_EncryptionHistory

Scan 0

hex (dec) = 0x00000000:00000000:0000 (0:0:0)                             
EncryptionScanInfo:ScanId = 0       

Scan 1

hex (dec) = 0x00000000:00000000:0000 (0:0:0)                             
EncryptionScanInfo:ScanId = 0       

Scan 2

hex (dec) = 0x00000000:00000000:0000 (0:0:0)                             
EncryptionScanInfo:ScanId = 0       
dbi_latestVersioningUpgradeLSN = 18:81:67 (0x00000012:00000051:0043)     dbi_splitAGE = 0
dbi_PendingRestoreOutcomesId = 00000000-0000-0000-0000-000000000000      dbi_ContianmentState = 0
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

DBCC KULLANIM SEÇENEKLERİ
 NO_INFOMSGS – Bilgi mesajlarını ekrana yazdırmaz, sürekli aynı bilgilerin fazlalık yapmaması iyidir.

ALL_ERRORMSGS – Tüm hata mesajlarını getirir.

NOINDEX – Cluster edilmemiş indekslerinj kontrolünü atlar. Önerilmez.

DATA_PURITY – Sutünlarda veri doğrulaması yapar. Sql Server 2005’ten sonra varsayılan olarak Checkdb’lere eklenmiştir.

ESTIMATEONLY – Checkdb işlemini yapabilmek için ne kadar boş tempdb alanının olduğunu gösterir.

TABLOCK – Veritabanı snaphotları üzerinde kilitleme yapar, master veritabanında yapılmasına izin verilmez.

EXTENDED_LOGICAL_CHECKS – Veri yapıları üzerinde (viewler, indeksler gibi) ekstradan doğrulama yapmaya yarar.

PHYSICAL_ONLY – Sadece fiziksel olarak tarama yapar. Kontrol süresini azaltacağı gibi, işlemci ve memory’i gerektiği kadar kullanır.

 Komutlarla ilgili birkaç örnek yapalım, örneklerde kullanılmak üzere AdventureWorks2012 veritabanını kullancağız. Bu örnek veritabanı buradaki linkten indrebilirsiniz http://msftdbprodsamples.codeplex.com/releases/view/55330

 Hiçbir seçenek yazmadan Checkdb’yi çalıştırıyoruz,


-- Seçeneksiz Checkdb çalıştırılması
DBCC CHECKDB (N'AdventureWorks2012');
GO
-------------------------------------------

Bir sürü işe yaramayan bilgiyi bize getirdi. Sonuç sayfası 5 sayfa geldiğinden, gereksiz yer kaplamaması için buraya sadece giriş ve son kısımlarını getirdim.

DBCC results for ‘AdventureWorks2012’.

Service Broker Msg 9675, State 1: Message Types analyzed: 14.

Service Broker Msg 9676, State 1: Service Contracts analyzed: 6.

Service Broker Msg 9667, State 1: Services analyzed: 3.

Service Broker Msg 9668, State 1: Service Queues analyzed: 3.

Service Broker Msg 9669, State 1: Conversation Endpoints analyzed: 0.

Service Broker Msg 9674, State 1: Conversation Groups analyzed: 0.

Service Broker Msg 9670, State 1: Remote Service Bindings analyzed: 0.

Service Broker Msg 9605, State 1: Conversation Priorities analyzed: 0.

DBCC results for ‘sys.sysrscols’.

There are 1791 rows in 21 pages for object “sys.sysrscols”.

DBCC results for ‘sys.sysrowsets’.

There are 327 rows in 3 pages for object “sys.sysrowsets”.

DBCC results for ‘sys.sysclones’.

There are 0 rows in 0 pages for object “sys.sysclones”.

DBCC results for ‘sys.sysallocunits’.

There are 371 rows in 5 pages for object “sys.sysallocunits”.

DBCC results for ‘sys.sysfiles1’.

There are 2 rows in 1 pages

.

.

.

.

.

There are 1764 rows in 70 pages for object “Production.vProductAndDescription”.

DBCC results for ‘sys.queue_messages_2041058307’.

There are 0 rows in 0 pages for object “sys.queue_messages_2041058307”.

DBCC results for ‘sys.filestream_tombstone_2073058421’.

There are 0 rows in 0 pages for object “sys.filestream_tombstone_2073058421”.

DBCC results for ‘sys.syscommittab’.

There are 0 rows in 0 pages for object “sys.syscommittab”.

DBCC results for ‘Sales.SalesTerritoryHistory’.

There are 17 rows in 1 pages for object “Sales.SalesTerritoryHistory”.

DBCC results for ‘sys.filetable_updates_2105058535’.

There are 0 rows in 0 pages for object “sys.filetable_updates_2105058535”.

DBCC results for ‘Person.vStateProvinceCountryRegion’.

There are 181 rows in 2 pages for object “Person.vStateProvinceCountryRegion”.

CHECKDB found 0 allocation errors and 0 consistency errors in database ‘AdventureWorks2012’.

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

 

No Infomsgs ile Checkdb yaptığımızda, hiçbir bilgi mesajını getirmiyor. Ama eğer bir hata bulsaydı, hata mesajı olarak gelecekti.

-- NO_INFOMSGS ile kullanımı
DBCC CHECKDB (N'AdventureWorks2012') WITH NO_INFOMSGS;
GO
----------------------
Command(s) completed successfully.

Estimateonly ile tempdb de ne kadar kullanılabilir alanımız var buna bakalım,

DBCC CHECKDB (N'AdventureWorks2012') WITH ESTIMATEONLY;
GO

DBCC results for ‘AdventureWorks2012’.

Estimated TEMPDB space (in KB) needed for CHECKDB on database AdventureWorks2012 = 336.

CHECKDB found 0 allocation errors and 0 consistency errors in database ‘AdventureWorks2012’.

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

 

Sadece Fiziksel Test için aşağıdaki komutları yazıyoruz, önbellek’i temizleme için dropcleanbuffers ve ne kadar sürede yapacağının bilgisi içinde statistics komutlarını kullanacağız. Dropcleanbuffer için detaylı bilgi: http://technet.microsoft.com/tr-tr/library/ms187762.aspx

Fiziksel tarama ile normal tarama arasındaki farkı görmek için, önce normal tarama yapıyoruz,

DBCC DROPCLEANBUFFERS;
GO
SET STATISTICS TIME ON;
GO
DBCC CHECKDB (N'AdventureWorks2012') WITH NO_INFOMSGS;
GO
SET STATISTICS TIME OFF;
GO
----------------------------------

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

SQL Server parse and compile time:

CPU time = 0 ms, elapsed time = 0 ms.

SQL Server Execution Times:

CPU time = 8029 ms,  elapsed time = 3448 ms.

SQL Server parse and compile time:

CPU time = 0 ms, elapsed time = 0 ms.

—————————————

İşlemci zaman 8 saniye, geçen süre 3,4 saniye

Fiziksel taramayı yapıyoruz,

DBCC DROPCLEANBUFFERS;
GO
SET STATISTICS TIME ON;
GO
DBCC CHECKDB (N'AdventureWorks2012') WITH NO_INFOMSGS, PHYSICAL_ONLY;
GO
SET STATISTICS TIME OFF;
GO
-------------------------------------

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

SQL Server parse and compile time:

CPU time = 0 ms, elapsed time = 0 ms.

SQL Server Execution Times:

CPU time = 1047 ms,  elapsed time = 657 ms.

SQL Server parse and compile time:

CPU time = 0 ms, elapsed time = 0 ms.

——————————————————-

Görüldüğü gibi işlemci zamanında ciddi bir düşüş oldu, sadece fiziksel tarama yapmanın işlemciyi ve memory daha az yoracağını belirtmiştik. Bu örnek bir veritabanı olduğundan, buradaki zamanlar size ufak gelebilir, ama ciddi seviyede büyük veritabanlarında (VLDB) bu değerlerin farkı daha da artacaktır.

DBCC CHECK Komutlarının Çevrimiçi Kullanılabilmesi

 

Bu kadar tutarlılık testinin çalışan canlı bir sistemde (production) nasıl yapıldığı. Sql Server’ımızı durdurmadan, çalışanan prosesleri etkilemeden veritabanı tutarlılık testleri yapabilmekteyiz. Bunun en temel sebebi, aynı Vmware’in snapshot yapısı gibi, Sql Server’da Checkdb yaparken veritabanlarının snaphot’ını yani görüntüsünü alıyor diyebiliriz.

Bu alınan snapshot Ntfs dosya sistemi içerisinde hidden diye tabir edilen gizli dosyalar arasında ve Sql data dosyalarımızın içinde bulunuyor. Checkdb işlemi bittiği anda da otomatik olarak diskten siliniyor.

Bazen snapshot dosyalarının gereksiz yere büyümesi ile disk üzerinde çok fazla yer kaplar, bu sebepten ötürü Checkdb işlemi hata verip yarım kalabilir. Benzer bir durumda, veritabanı snaphot dosyaları için yetkilendirmede sıkıntı olursa, gene hata verip checkdb çalışmayabilir.

DBCC CHECKDB Kontrolü Ne Kadar Zaman Sürer

Checkdb işleminin süresini ne kadar süreceğini etkileyen faktörleri sıralayalım;

–          Veritabanlarının büyüklüğü

–          Sunucudaki eşzamanlı I/O yüklemesi

–          Sunucu işlemci aktivitesi

–          Veritabanı üzerindeki eşzamanlı güncelleme aktiviteleri

–          I/O Altsisteminin yeterlilikleri

–          Sunucu üzerindeki işlemci sayısı, ne kadar çok işlemci olursa o kadar süre azalır

–          Harddisklerin hızları

–          Veritabanı şemasının karmaşıklığı

–          Checkdb komutlarının kullanımı

–          Corruptionların tipleri ve sayıları

6 – DBCC CHECKDB İşleminin Sonuçları

Checkdb işlemini nasıl ve hangi yöntemlerle yapacağımızı yukarıda örneklerle gördük. Şimdi bu kontorllerin sonuçlarında neler yapabiliriz (geri yükleme – kurtama gibi) bunlara bakacağız.

Veritabanında bozulmaların ilk sinyalleri, 823 ve 824 hataların gelmesi ile başlar. Sql Server yedek alırken checksum ile ilgili hatalar verir. Sql Agent alarmları sürekli uyarılar yayınlar, bakım görevleri çalışmaz. Tüm bunlar bir yerlerde bozulmanın başladığının işaretidir.

Bana bir şey olmaz demeyin, makalemizin başlarında da anlattığımız gibi mutlaka testler yapmalısınız. Checkdb ile ilgili bir fikriniz yok ise, tatil olan bir günde Checkdb çalıştırıp ortalama ne kadar sürdüğünü mutlaka test edin. Bir felaket durumda ne kadar vaktiniz olduğunu yaklaşık olarak tahmin edebilme şansınız olsun. Checkdb işlemi uzun sürüyor ise kesinlikle durdurmayın, bozulmanın nerede, hangi kısımda olduğunu bilemezsiniz, bu komutun işleminin bitmesini beklemelisiniz. En büyük yanılgılardan biri de sunucuyu yeniden başlatmaktır, bu size sadece zaman kaybettireceği gibi, yarım kalan transactionların roll-back yani geri sarmasını sağlarsınız.

Checkdb komutunun sonucu, Sql Server hata loglarına ve Windows Application event loglarına yazılır. Eğer bir corruption (bozulma) tespit edilir ise, Severity 16 mesajı olarak Sql Server hata loglarına kayıt olur. Sql Server Agent üzerinde Severity 16 hatasının oluşumunda kendinize mail olarak haber verdirebilirsiniz. Sql Server Management Studio ilk 1000 hata kaydını tutar, bundan önceki hata kayıtlarına erişmek için çabalar durursunuz. Bu yüzden Sql Server Agent üzerinden hataları mail olarak bildirilmesi hayati bir öneme sahiptir.

Checkdb çıktılarına birkaç örnek yapalım.

İki veritabanı oluşturup, 2 sutünlu bir tablo ekliyoruz.

-- Planlama isminde bir veritabanı oluşturuyoruz  - 1. veritabanımı
CREATE DATABASE [PLANLAMA] ON PRIMARY (NAME = N'PLANLAMA',
				FILENAME = N'C:\DATA\PLANLAMA.mdf')
LOG ON
		( NAME = N'PLANLAMA_LOG', 
		  FILENAME = N'C:\DATA\PLANLAMA_LOG.ldf');
GO

-- Planlamadata isminde bir tablo oluşturup, 2 sutün ekliyoruz, ve 30 satır veri ilave ediyoruz
USE PLANLAMA;
GO

CREATE TABLE PLANLAMAdata
				( [c1] INT IDENTITY,
				  [c2] CHAR (7000) DEFAULT 'ccc');
GO

INSERT INTO [dbo].[PLANLAMAdata] DEFAULT VALUES;
GO	30
----------------------------

İkinci veritabanımızı da oluşturalım, adı ARGE olsun;

-- ARGE isminde bir veritabanı oluşturuyoruz - 2. veritabanımız
CREATE DATABASE [ARGE] ON PRIMARY (NAME = N'ARGE',
			FILENAME = N'C:\DATA\ARGE.mdf')
LOG ON
		( NAME = N'ARGE_LOG', 
		  FILENAME = N'C:\DATA\ARGE_LOG.ldf');
GO

-- ARGEdata isminde bir tablo oluşturup, 2 sutün ekliyoruz, ve 30 satır veri ilave ediyoruz
USE ARGE;
GO

CREATE TABLE ARGEdata
				( [c1] INT IDENTITY,
				  [c2] CHAR (7000) DEFAULT 'eee');
GO

INSERT INTO [dbo].[ARGEdata] DEFAULT VALUES;
GO	30

Pageleri listeyelim;

DBCC IND (N'ARGE', N'ARGEdata', -1);
GO
--------------
<a href="http://www.yavuzfilizlibay.com/wp-content/uploads/2014/02/Sql_Cor_26.jpg"><img class="alignnone size-full wp-image-15314" alt="Sql_Cor_26" src="http://www.yavuzfilizlibay.com/wp-content/uploads/2014/02/Sql_Cor_26.jpg" width="1164" height="365" /></a>

PagePID 121’i seçelim ve üzerinde bozulma oluşturalım;

ALTER DATABASE [ARGE] SET SINGLE_USER;
GO
DBCC WRITEPAGE (N'ARGE', 1, 121, 0, 2, 0x0000, 1);
GO
ALTER DATABASE [ARGE] SET MULTI_USER;
GO
--------------

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Suspect pages’te temizleme yapalım;

DELETE FROM msdb.dbo.suspect_pages;
EXEC sp_cycle_errorlog;
GO
--------------------

(1 row(s) affected)

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Planlama veritabanında bozulma yaptırmadık. Checkdb’yi burada çalıştıralım;

DBCC CHECKDB (N'PLANLAMA');

DBCC results for ‘PLANLAMA’.

Service Broker Msg 9675, State 1: Message Types analyzed: 14.

Service Broker Msg 9676, State 1: Service Contracts analyzed: 6.

Service Broker Msg 9667, State 1: Services analyzed: 3.

Service Broker Msg 9668, State 1: Service Queues analyzed: 3.

Service Broker Msg 9669, State 1: Conversation Endpoints analyzed: 0.

Service Broker Msg 9674, State 1: Conversation Groups analyzed: 0.

Service Broker Msg 9670, State 1: Remote Service Bindings analyzed: 0.

Service Broker Msg 9605, State 1: Conversation Priorities analyzed: 0.

DBCC results for ‘sys.sysrscols’.

.

.

.

Görüldüğü gibi hata vermedi. Bozuk olan Arge veritabanında Checkdb’yi çalıştıralım;

DBCC CHECKDB (N'ARGE') WITH NO_INFOMSGS;
GO
-----------------

Msg 8939, Level 16, State 98, Line 1

Table error: Object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data), page (1:121). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 133129 and -4.

Msg 8928, Level 16, State 1, Line 1

Object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data): Page (1:121) could not be processed.  See other errors for details.

CHECKDB found 0 allocation errors and 2 consistency errors in table ‘ARGEdata’ (object ID 245575913).

CHECKDB found 0 allocation errors and 2 consistency errors in database ‘ARGE’.

repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (ARGE).

 

İki tane hata verdi, aslında ikisi de aynı PagePID’yi gösteriyor.

Management Studio – Management – Sql Server Logs’ta nasıl hata vermiş bakıyoruz.

Sql_Cor_27

 

Application loglara baktığımızda ise hata yerine info mesajı olarak vermiş. Burada dikkat etmemiz gereken bir nokta ortaya çıkıyor. Sql Server ile ilgili Sadece Windows Event Loglarına bakarsak nasıl yanılacağımıza dair güzel bir örnek.

Sql_Cor_28

DBCC CHECKDB Hata Verir İse Neler Yapılabilir

Checkdb komutu hata verip tamamlanmıyor ise, sonucu hata veriyor değil, bunu görev gibi düşünmek gerekir, Checkdb işleminin hata verip tamamlanmamasından bahsediyoruz. Bu iki konu genelde karıştırılıyor. Böyle bir durumda ya yedekten geri dönmeliyiz veya veriyi dışarı export edip almaya çalışmalıyız.

Hatalara örnek olarak 7984 ve 7988 kritik sistem tabloları hataları, bu iki hata yolun sonu gibi şey, yedekten dönmeniz gerekiyor. Detaylar için Error 7984: http://technet.microsoft.com/en-us/library/ms365268.aspx Error 7988:  http://technet.microsoft.com/en-us/library/ms365219.aspx

Error 8967: http://support.microsoft.com/kb/960791/tr

Error 8930 ise metadata bozulma olduğunu söyler ve Checkdb burada işe yaramamaktadır. http://technet.microsoft.com/en-us/library/aa226339(v=sql.80).aspx

CORRUPTION İLE İLGİLİ ÖRNEKLER

Birkaç örnek yapalım, 3 tane veritabanı oluşturuyoruz,

CREATE DATABASE [DBBOZUK] ON PRIMARY (NAME = N'DBBOZUK',
						FILENAME = N'C:\DATA\DBBOZUK.mdf')
LOG ON
		( NAME = N'DBBOZUK_LOG', 
		  FILENAME = N'C:\DATA\DBBOZUK_LOG.ldf');
GO

CREATE DATABASE [DBBOZUK1] ON PRIMARY (NAME = N'DBBOZUK1',
						FILENAME = N'C:\DATA\DBBOZUK1.mdf')
LOG ON
		( NAME = N'DBBOZUK1_LOG', 
		  FILENAME = N'C:\DATA\DBBOZUK1_LOG.ldf');
GO

CREATE DATABASE [DBBOZUK2] ON PRIMARY (NAME = N'DBBOZUK2',
						FILENAME = N'C:\DATA\DBBOZUK2.mdf')
LOG ON
		( NAME = N'DBBOZUK2_LOG', 
		  FILENAME = N'C:\DATA\DBBOZUK2_LOG.ldf');
GO

Bu üç veritabanı için page protection’ı kapatıyoruz,

ALTER DATABASE DBBOZUK SET PAGE_VERIFY NONE;
ALTER DATABASE DBBOZUK1 SET PAGE_VERIFY NONE;
ALTER DATABASE DBBOZUK2 SET PAGE_VERIFY NONE;
GO

--Veritabanlarını bozabilmek için hazırlıyoruz, single mode’a alıyoruz,
ALTER DATABASE DBBOZUK SET SINGLE_USER;
ALTER DATABASE DBBOZUK1 SET SINGLE_USER;
ALTER DATABASE DBBOZUK2 SET SINGLE_USER;
GO

--İlk veritabanımızda dosya başlığını bozuyoruz,
DBCC WRITEPAGE (N'DBBOZUK', 1, 0, 0, 4, 0x00000000, 1);
GO

İkinci veritabanımızda ise boot page’i bozuyoruz,
DBCC WRITEPAGE (N'DBBOZUK1', 1, 9, 0, 4, 0x00000000, 1);
GO

--Üçüncü veritabanımızda da, metadata’yı bozuyoruz,
DBCC WRITEPAGE (N'DBBOZUK2', 1, 20, 0, 4, 0x00000000, 1);
GO

DBCC WRITEPAGE (N'DBBOZUK2', 1, 17, 0, 4, 0x00000000, 1);
GO

--Şimdi veritabanlarımızı multi user mode’a almaya çalışalım, görüldüğü gibi hata veriyor, multi user mode a geçmiyor.
ALTER DATABASE [DBBOZUK] SET MULTI_USER;
ALTER DATABASE [DBBOZUK1] SET MULTI_USER;
ALTER DATABASE [DBBOZUK2] SET MULTI_USER;
GO
-----------------

Location:    logrec.cpp:617

Expression:  FALSE

SPID:        67

Process ID:  2400

Description: Invalid switch value

Msg 5069, Level 16, State 1, Line 2

ALTER DATABASE statement failed.

Location:    logrec.cpp:617

Expression:  FALSE

SPID:        67

Process ID:  2400

Description: Invalid switch value

Msg 3624, Level 20, State 1, Line 2

A system assertion check has failed. Check the SQL Server error log for details. Typically, an assertion failure is caused by a software bug or data corruption. To check for database corruption, consider running DBCC CHECKDB. If you agreed to send dumps to Microsoft during setup, a mini dump will be sent to Microsoft. An update might be available from Microsoft in the latest Service Pack or in a QFE from Technical Support. 

Suspect pages’ten tüm hata loglarını temizleyelim;

DELETE FROM msdb.dbo.suspect_pages;
EXEC sp_cycle_errorlog;
GO
------------

(2 row(s) affected)

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Bozulmaları sağladıktan sonra, DBBOZUK1 isimli veritabanımızda Checkdb’yi çalıştıralım,

DBCC CHECKDB (N'DBBOZUK1') WITH NO_INFOMSGS;
GO
---------------------

Msg 8921, Level 16, State 1, Line 1

Check terminated. A failure was detected while collecting facts. Possibly tempdb out of space or a system table is inconsistent. Check previous errors.

Msg 8939, Level 16, State 5, Line 1

Table error: Object ID 99, index ID 0, partition ID 0, alloc unit ID 6488064 (type System allocation data), page (1:9). Test (m_headerVersion == HEADER_7_0) failed. Values are 0 and 1.

Msg 8939, Level 16, State 6, Line 1

Table error: Object ID 99, index ID 0, partition ID 0, alloc unit ID 6488064 (type System allocation data), page (1:9). Test ((m_type >= DATA_PAGE && m_type <= UNDOFILE_HEADER_PAGE) || (m_type == UNKNOWN_PAGE && level == BASIC_HEADER)) failed. Values are 0 and 0.

CHECKDB found 2 allocation errors and 0 consistency errors in table ‘(Object ID 99)’ (object ID 99).

CHECKDB found 2 allocation errors and 0 consistency errors in database ‘DBBOZUK1’.

 

Header dosyasının geçerli olmadığıyla ilgili hatayı veriyor.

Bu hatayı aldıktan sonra TABLOCK seçeneğiyle Checkdb yapmayı deneyelim,

DBCC CHECKDB (N'DBBOZUK1') WITH NO_INFOMSGS, TABLOCK;
GO
----------------

Msg 8921, Level 16, State 1, Line 1

Check terminated. A failure was detected while collecting facts. Possibly tempdb out of space or a system table is inconsistent. Check previous errors.

Msg 8939, Level 16, State 5, Line 1

Table error: Object ID 99, index ID 0, partition ID 0, alloc unit ID 6488064 (type System allocation data), page (1:9). Test (m_headerVersion == HEADER_7_0) failed. Values are 0 and 1.

Msg 8939, Level 16, State 6, Line 1

Table error: Object ID 99, index ID 0, partition ID 0, alloc unit ID 6488064 (type System allocation data), page (1:9). Test ((m_type >= DATA_PAGE && m_type <= UNDOFILE_HEADER_PAGE) || (m_type == UNKNOWN_PAGE && level == BASIC_HEADER)) failed. Values are 0 and 0.

CHECKDB found 2 allocation errors and 0 consistency errors in table ‘(Object ID 99)’ (object ID 99).

CHECKDB found 2 allocation errors and 0 consistency errors in database ‘DBBOZUK1’.

Malesef tablock’da bir işe yaramadı, Header dosyasının geçersiz olduğunu belirtiyor. Yukarda belirtilen Object ID 99 aslında varolmayan bir nesnedir, bu hatayla birlikte bir bütün olarak düşünebilirsiniz, page verileriniz arasında boşuna bu object id’yi getirmeye çalışmayın.

 

Üçüncü veritabanımızda boot page’i bozumuştuk, Checkdb ile düzeltmeye çalışalım,

DBCC CHECKDB (N'DBBOZUK2') WITH NO_INFOMSGS;
GO
----------------

Msg 1823, Level 16, State 6, Line 1

A database snapshot cannot be created because it failed to start.

Msg 1823, Level 16, State 7, Line 1

A database snapshot cannot be created because it failed to start.

Msg 1823, Level 16, State 8, Line 1

A database snapshot cannot be created because it failed to start.

Msg 7928, Level 16, State 1, Line 1

The database snapshot for online checks could not be created. Either the reason is given in a previous error or one of the underlying volumes does not support sparse files or alternate streams. Attempting to get exclusive access to run checks offline.

Msg 7985, Level 16, State 2, Line 1

System table pre-checks: Object ID 5. Could not read and latch page (1:17) with latch type SH. Check statement terminated due to unrepairable error.

Msg 5233, Level 16, State 5, Line 1

Table error: alloc unit ID 327680, page (1:17). The test (m_headerVersion == HEADER_7_0) failed. The values are 0 and 1.

Msg 5233, Level 16, State 6, Line 1

Table error: alloc unit ID 327680, page (1:17). The test ((m_type >= DATA_PAGE && m_type <= UNDOFILE_HEADER_PAGE) || (m_type == UNKNOWN_PAGE && level == BASIC_HEADER)) failed. The values are 0 and 0.

CHECKDB found 0 allocation errors and 2 consistency errors not associated with any single object.

CHECKDB found 0 allocation errors and 2 consistency errors in database ‘DBBOZUK2’.

Bu page’i okuyamadığını belirtiyor hatada.

7 – GERİ YÜKLEME VE ONARMA

 

Veritabanı bozulması ile karşılaştığımız zaman, aklımıza iki yöntem gelmektedir. Geri yükleme (restore) veya onarma (repair). Sistemin kapalı kalma zamanın önemi fazla ve daha öncelikli bir yapıda iseniz, repair işlemi restore’a göre daha öncelikli olmaktadır. Genelde gözden kaçan bir durum ise, hasar görmüş veritabanından verileri export etmek yani dışarıya çıkarmaktır. Export yöntemi de bir başka seçenek olarak aklımızda olması gerekir.

Bir felaket durumunda, en kısayol hangisi ise bunu tercih etmeniz gerekmektedir. Geçen süre sizi her zaman daha da strese sokacağından, daha fazla hata yapmanıza sebep olcaktır. İlk önce elinizde veritabanı duruyor mu buna bakın, ne kadar zarar görmüş, ne kadar kısmı hasar görmüş durumda, sistem çalışır durumda mı yoksa herkes hata mı alıyor. Eğer cevabınız hayır ise, mutlaka restore ile veritabanını geri dönmek zorundasınız, bu noktada repair bir işe yaramayacaktır. Bu aşamada daha önceki tatbikatlarınızın önemi ortaya çıkıyor.

Senaryoyu daha da ileri seviyeye taşıyalım. Elinizde düzgün ve çalışan yedekler var mı, yedek almışsınız ama yedekten geri dönemediğinizi farz edelim. Bu durumda repair yöntemi veya veriyi yeni bir veritabanına export etme yöntemini kullanmalısınız.

Dbcc Checkdb hata veriyor ve çalışmıyor ise, restore veya export yöntemi ile veritabanını geri getirmelisiniz. Indekslerde bir hata veriyor ise, restore veya repair yerine, indeksleri rebuild (yeniden yapılandırma) seçeneğiyle onarım yoluna gitmelisiniz.

Repair ve restore’un mümkün olmadığı bir durumda, bozulan veritabanını yeni bir veritabanına export etmek gerekebilir. Bunun için, yeni bir veritabanı açılır, bozulan veritabanındaki tablolar, indeksler, stored prosedürler, fonksiyonlar v.b. hepsi yeniden yeni veritabanında oluşturulur. Ardından Select ile sorgulamaya başlarız, verilerde olası doğru olanları seçmeye çalışmak gerekmektedir, bu konu uzmanlık gerektiren bir konu olduğundan gerekli bilgiyi edinmeden bu işi yapmak çok risklidir. Elinizdeki sağlam verileride kaybetme olasılığınız vardır.

 

7 – A – GERİ YÜKLEME (RESTORE) TEKNİKLERİ

 

Bozulan bir veritabanını yedekten geri yükleme işlemi, veri kaybını önlemede en iyi yöntemdir. Tabi burada yedeklerin erişilebilir olması ve geri dönülebilir olması gerekmektedir. En hızlı sürede yedekten geri dönmek çok önemli bir konudur.

Bir örnek vermek gerekirse, hafta sonu pazar günü full backup alıyorsunuz ve her saatte bir transaction log backup’ı alıyorsunuz diyelim. Bu backup tan geri dönmek oldukça uzun sürecektir. Günlük full backup alıyorsunuz ve her saat başıda transaction log backuplarını aldığınızda ise, daha hızlı geri yükleme yapabilirsiniz. Yedekleme stratejilerinin mutlaka belirlenmesi gerekmektedir. Ayrıca alınan backuplar geçerli mi, backupların geçerliliğini haftada bir, bir test sunucusunda geri yüklenerek kontrol etmek gerekmektedir.

 

Üç türlü backup alma yöntemi vardır;

–          Full Database Backup: Veritabanının tümünü yedekler.

–          Transaction Log Backup: Full backup alındıktan sonra değişen işlem loglarının yedeklerini alır. Geri yüklenmek istediğinde, en son full alınan backup’a kadar geri yüklenebilir.

–          Differential Database Backup: Full backup alındıktan sonra, değişen veri sayfalarının yedeğinin alır. Full backup ile geri dönüldükten sonra Differential backup ile en son yedek alınan kısma geri dönülmesi, en düşük veri kaybını sağlayacaktır. Full backup’a göre daha hızlı restore edilebilirler.

 

Log Backuplar arasında zincir bağlantı söz konusudur. Bir veya birden fazla log backup’ta bozulma meydana gelirse, geri yükleme gerçekleşmeyecektir. Bu da daha fazla veri kaybetmeniz demektir. Yedekleriniz sadece tek bir yere almayın, mutlaka off-site diye tabir edilen, ikincil bir yedekleme deponuza da yedek almalısınız.

 

RESTORE SEÇENEKLERİ

 

–          WITH RECOVERY: Varsayılan olarak gelen seçenektir, veritabanını tam olarak geri döner, kendinden başka hiçbir seçeneği kullandırmaya izin vermez. Kullanım sırasında problemler çıkabilir.

–          WITH NORECOVERY: Geri yükleme işlemlerinizde ilk tercih edeceğiniz yöntem bu olmalıdır. Bir hata olma durumunda, restore işlemini tekrardan başlatabilirsiniz.

–          WITH STANDBY: Norecovery’e benzer bir yapıdadır. Farkı salt okunur bir veritabanı oluşturarak bu veritabanını kontrol etmenize imkan verir.

 

Geri yükleme ile ilgili örnekler yapalım.

Yeni bir veritabanı oluşturuyoruz,

CREATE DATABASE [DBRESTORE] ON PRIMARY (NAME = N'DBRESTORE',
					  FILENAME = N'C:\DATA\DBRESTORE.mdf')
LOG ON
		( NAME = N'DBRESTORE_LOG', 
		  FILENAME = N'C:\DATA\DBRESTORE_LOG.ldf');
GO

USE DBRESTORE;
GO

--Veritabanımda bir tablo oluştuyorum,

CREATE TABLE [DBRESTORE]
	([C1] INT IDENTITY,
	 [C2] VARCHAR(150));
GO

--Tabloma veri  ekliyorum,

INSERT INTO [DBRESTORE] VALUES
	('data: islem 1');
GO

--Full bir yedek alıyorum;

BACKUP DATABASE [DBRESTORE]
TO DISK = N'C:\DATA\DBRESTORE_FULL.bak'
WITH INIT;
GO
------------------

Processed 328 pages for database ‘DBRESTORE’, file ‘DBRESTORE’ on file 1.

Processed 6 pages for database ‘DBRESTORE’, file ‘DBRESTORE_LOG’ on file 1.

BACKUP DATABASE successfully processed 334 pages in 0.029 seconds (89.725 MB/sec).

 

--Yedek aldıktan sonra tabloma 2 tane daha veri ekliyorum,

INSERT INTO [DBRESTORE] VALUES
	('data: islem 2');
INSERT INTO [DBRESTORE] VALUES
	('data: islem 3');
GO

--2. ve 3. Veriyi ekledikten sonra Transaction Log Backup alıyorum,

BACKUP LOG [DBRESTORE]
TO DISK = N'C:\DATA\DBRESTORE_Log1.bak'
WITH INIT;
GO
------------------

Processed 6 pages for database ‘DBRESTORE’, file ‘DBRESTORE_LOG’ on file 1.

BACKUP LOG successfully processed 6 pages in 0.018 seconds (2.495 MB/sec).

--4. ve 5. Verilerimizi de tablomuza kaydedelim,

INSERT INTO [DBRESTORE] VALUES
	('data: islem 4');
INSERT INTO [DBRESTORE] VALUES
	('data: islem 5');
GO

--4. ve 5. Kayıtlarımızı saat kaçta yaptığımızı öğrenmek için getdate komutunu kullanıyoruz,

SELECT GETDATE ();
GO
---------------------------

2014-02-20 00:21:47.207

--6. ve 7. Verileri ekliyoruz,

INSERT INTO [DBRESTORE] VALUES
	('data: islem 6');
INSERT INTO [DBRESTORE] VALUES
	('data: islem 7');
GO

--Bir log backup daha alıyoruz,

BACKUP LOG [DBRESTORE]
TO DISK = N'C:\DATA\DBRESTORE_Log2.bak'
WITH INIT;
GO
---------------------

Processed 1 pages for database ‘DBRESTORE’, file ‘DBRESTORE_LOG’ on file 1.

BACKUP LOG successfully processed 1 pages in 0.007 seconds (0.418 MB/sec).

Senaryomuza göre, veritabanımızda sorun var ve geri yüklememiz gerekiyor, ilk önce DBRESTORE veritabanımı drop database komutu ile Sql Server üzerinden düşürüyorum,

USE MASTER;
GO	

DROP DATABASE [DBRESTORE];
GO

--3 tane yedek almıştık, ilk önce Full backup’ımı geri dönüyorum,

RESTORE DATABASE [DBRESTORE]
FROM DISK = N'C:\DATA\DBRESTORE_FULL.bak'
WITH REPLACE;
GO
---------------------

Processed 328 pages for database ‘DBRESTORE’, file ‘DBRESTORE’ on file 1.

Processed 6 pages for database ‘DBRESTORE’, file ‘DBRESTORE_LOG’ on file 1.

RESTORE DATABASE successfully processed 334 pages in 0.017 seconds (153.061 MB/sec).

 

Full backup’ı geri döndükten sonra, Log backuplarımı da geri dönüyorum,

RESTORE LOG [DBRESTORE]
FROM DISK =N'C:\DATA\DBRESTORE_Log1.bak';

RESTORE LOG [DBRESTORE]
FROM DISK =N'C:\DATA\DBRESTORE_Log2.bak';
GO
------------------

Msg 3117, Level 16, State 1, Line 1

The log or differential backup cannot be restored because no files are ready to rollforward.

Msg 3013, Level 16, State 1, Line 1

RESTORE LOG is terminating abnormally.

Msg 3117, Level 16, State 1, Line 4

The log or differential backup cannot be restored because no files are ready to rollforward.

Msg 3013, Level 16, State 1, Line 4

RESTORE LOG is terminating abnormally.

 

Hatamızı aldık, bu şekilde yaparsak log backupları geri dönemeyiz. Norecovery seçeneği ile Full backuptan geri dönmemiz gerekiyordu, Norecovery ile restore işlemini tekrardan yapıyoruz,

RESTORE DATABASE [DBRESTORE]
FROM DISK = N'C:\DATA\DBRESTORE_FULL.bak'
WITH REPLACE, NORECOVERY;
GO
-----------------

Processed 328 pages for database ‘DBRESTORE’, file ‘DBRESTORE’ on file 1.

Processed 6 pages for database ‘DBRESTORE’, file ‘DBRESTORE_LOG’ on file 1.

RESTORE DATABASE successfully processed 334 pages in 0.019 seconds (136.950 MB/sec).

 

Ardından Log backupları geri yüklüyorum,

RESTORE LOG [DBRESTORE]
FROM DISK =N'C:\DATA\DBRESTORE_Log1.bak'
WITH NORECOVERY;

RESTORE LOG [DBRESTORE]
FROM DISK =N'C:\DATA\DBRESTORE_Log2.bak'
WITH NORECOVERY;
GO
--------------------

Processed 0 pages for database ‘DBRESTORE’, file ‘DBRESTORE’ on file 1.

Processed 6 pages for database ‘DBRESTORE’, file ‘DBRESTORE_LOG’ on file 1.

RESTORE LOG successfully processed 6 pages in 0.005 seconds (8.984 MB/sec).

Processed 0 pages for database ‘DBRESTORE’, file ‘DBRESTORE’ on file 1.

Processed 1 pages for database ‘DBRESTORE’, file ‘DBRESTORE_LOG’ on file 1.

RESTORE LOG successfully processed 1 pages in 0.005 seconds (0.585 MB/sec).

 

Geri yükleme işlemimiz daha bitmedi. Object explorerdan kontrol edersek, veritabanı hala restoring modunda.

Sql_Cor_29

Geri yüklemeyi tamamlayalım,

RESTORE DATABASE DBRESTORE WITH RECOVERY;
GO
---------------------

RESTORE DATABASE successfully processed 0 pages in 0.121 seconds (0.000 MB/sec).

Bakalım verilerimizin hepsi gelmiş mi,

SELECT * FROM DBRESTORE.dbo.DBRESTORE
---------------------------

C1           C2

1             data: islem 1

2             data: islem 2

3             data: islem 3

4             data: islem 4

5             data: islem 5

6             data: islem 6 7   data: islem 7

 

Tüm verilerim kurtarılmış durumda.

Şimdi de Standby komutu ile geri yüklemeyi deneyelim, Norecovery ile geri yüklediğimizde veritabanımızın yanında Restoring yazıyordu ve veritabanımıza bakamıyorduk. Standby ile salt okunur olarak veritabanımızı kontrol edebileceğiz.

TAIL-LOG YEDEKLEME

Bir veritabanı bozulmasında, yedekten geri dönülecek ise, transaction log yedeğinin ilk önce geri dönülmesi gerekmektedir. Böylece en az veri kaybı sağlanmış olur.  Bu yedeklemeye genel olarak tail-of-the-log backup deniyor. Management Studio ile yapılması daha kolay olduğundan, grafiksel arayüzden daha rahat backup tanımlarını yapabilirsiniz.

Eğer data dosyaları erişebilir durumda değil ise, tail-of-the-log backup’ı WITH NO_TRUNCATE seçeneğini kullanarak çalıştırabilirsiniz.

http://technet.microsoft.com/en-us/library/ms179314.aspx

GERİ YÜKLEME – RESTORE – FULL, DIFFERENTIAL, LOG

Şemamızda da gösterildiği gibi, ilk önce Full restore (F), en son alınan differential yedeği geri yüklüyoruz (D2), son olarak en son alınan transaction log backup’ı geri yüklüyoruz (L7).

Sql_Cor_30

Eğer D2 deki differential yedeğimiz bozuk ise ve bu yedekten geri dönemiyorsa eğer, ilk önce full restore (F), en son çalışan Differential yedeği geri yüklüyoruz (D1), D2 bozuk olduğu için, sırasıyla L4, L5, L6 ve son olarak L7 transaction log backupları sırasıyla geri dönüyoruz, burada atlanmaması gereken nokta, direk L7 den geri dönüş yapamazsınız çünkü aradaki D2 diff. Yedeğiniz bozulmuş durumda. Bu sayade en az veri kaybı ile geri dönmüş oluyoruz.

Sql_Cor_31

7 – B – ONARMA (REPAIR) TEKNİKLERİ

Bir corruption durumda her zaman backup’tan geri dönmek zorunda kalmayabilirsiniz. Corruption’ı gidermek için onarma (repair) işlemi  yapılabilir. Repair işlemi yapılırken dikkatli olunmalıdır, aksi takdirde daha fazla veri kaybına yol açabilir. Repair işlemini gerekirse production (çalışan ana sistem) üzerinde değilde, bir test ortamında ilk önce denemek daha doğru olacaktır.

Repair yapmaktaki amaç, veritabanını tutarlığı bir hale getirmektir. Corruptionları düzelterek veritabanının düzgün bir şekilde işlediğinden emin olunması gerekmektedir. Repair yöntemi restore yöntemine göre daha hızlı denenebilicek bir yöntemdir, çoğu zaman restore yönteminden önce denenmesinde fayda vardır.

Çoğu zaman repair yöntemi ile birçok hatayı düzeltebilirsiniz, yanlız bazı corruptionlar diğer corruptionların maskelenmiş hali gibidir. Bunun anlamı, maskelenen corruption’ı düzeltseniz bile esas arka plandaki corruption’ı düzeltmiş olmazsınız. Bir türlü Sql Server’a attach olmayan veritabanları bunlara güzel bir örnektir, genelde bu veritabanları 3. Parti bir yazılımla test edilir ve bu veritabanı düzeltilemez gibi bir sonuç ortaya çıkar. Gerçek anlamda corruption’ı bulamadıklarından dolayı veritabanı bir türlü online olamaz.

Repair işlemleri Single User Mode (tekil kullanıcı modu) da ve offline (çevrimdışı) olarak yapılır.

REPAIR SEÇENEKLERİ

DBCC CHECKDB’nin repair seçenekleri şunlardır;

–          REPAIR_FAST – Açıkcası pek bir onarım işlemi yapmaz, geriye doğru uyumluluk kontolleri yapar.

–          REPAIR_REBUILD – Veri kaybı olmadan veritabanınında onarma yapar.

–          REPAIR_ALLOW_DATA_LOSS – Veri kaybına müsade ederek onarma işlemi yapar.

Bu seçeneklerden Allow Data Loss’tan uzak durmak gerekir, bu isim özellikle verilmiştir. Veri kaybına izin ver anlamına geldiğinden, bu seçeneği kullanırsanız veri kaybetme de yaşayabilirsiniz. Foreing key kısıtlarını (constraints) leri, iş zekası – veri ilişkilerini ve replikasyon bilgilerini göz ardı eden bir seçenektir.

Repair işlemini yapmadan önce mutlaka yedek alınız. Repair işleminden sonra, DBCC CHECKDB’yi çalıştırarak, tüm corruptionların düzeldiğinden emin olunuz.

Repair işlemini varsayılan olarak, seçenekleri kullanmadan yapmak doğru değildir. Repair işlemi de DBCC CHECKDB nin bir parçasıdır, ayrı olarak düşünülemez. Repair herşeyi düzeltemez, tüm herşeyi repair komutlarından beklemek yanlış olur. Sistem veritabanlarından tempdb ve master’ı repair ile düzeltemezsiniz. Msdb  veritabanını repair ile düzeltmek mümkündür. Replikasyon sunucularına repair işlemi ulaşmaz, burası genelde atlanan bir kısımdır, repair işlemi sadece uygulanan sunucuda geçerli bir işlemdir.

Repair işlemleri ile ilgili birkaç örnek yapalım;

Daha önceki örneklerde yaptığımız gibi, Numune isimli bir veritabanı oluşturup, içine 2 sutün açıp veriler ekleyelim,

-- NUMUNE isminde bir veritabanı oluşturuyoruz - 2. veritabanımız
CREATE DATABASE [NUMUNE] ON PRIMARY (NAME = N'NUMUNE',
				      FILENAME = N'C:\DATA\NUMUNE.mdf')
LOG ON
		( NAME = N'NUMUNE_LOG', 
		  FILENAME = N'C:\DATA\NUMUNE_LOG.ldf');
GO

-- NUMUNEdata isminde bir tablo oluşturup, 2 sutün ekliyoruz, ve 30 satır veri ilave ediyoruz
USE NUMUNE;
GO

CREATE TABLE NUMUNEdata
				( [c1] INT IDENTITY,
				  [c2] CHAR (7000) DEFAULT 'aaa');
GO

INSERT INTO [dbo].[NUMUNEdata] DEFAULT VALUES;
GO	30

Verilerin page id’sine bakalım

DBCC IND (N'NUMUNE', N'NUMUNEdata', -1);
GO

<a href="http://www.yavuzfilizlibay.com/wp-content/uploads/2014/02/Sql_Cor_32.jpg"><img class="alignnone size-full wp-image-15320" alt="Sql_Cor_32" src="http://www.yavuzfilizlibay.com/wp-content/uploads/2014/02/Sql_Cor_32.jpg" width="1120" height="364" /></a>
--PagePID’si 119 olanda bozulma yapacağız. 
ALTER DATABASE [NUMUNE] SET SINGLE_USER;
GO
DBCC WRITEPAGE (N'NUMUNE', 1, 119, 0, 2, 0x0000, 1);
GO
ALTER DATABASE [NUMUNE] SET MULTI_USER;
GO

--Msdb’deki suspect page loglarınıda temizleyelim,
DELETE FROM msdb.dbo.suspect_pages;
EXEC sp_cycle_errorlog;
GO

--Checkdb ile veritabanını kontrol ediyorum,
DBCC CHECKDB (N'NUMUNE') WITH NO_INFOMSGS;
GO

Msg 8928, Level 16, State 6, Line 1

Object ID 0, index ID -1, partition ID 0, alloc unit ID 0 (type Unknown): Page (1:119) could not be processed.  See other errors for details.

Msg 8905, Level 16, State 1, Line 1

Extent (1:216) in database ID 16 is marked allocated in the GAM, but no SGAM or IAM has allocated it.

Msg 8905, Level 16, State 1, Line 1

Extent (1:232) in database ID 16 is marked allocated in the GAM, but no SGAM or IAM has allocated it.

Msg 8905, Level 16, State 1, Line 1

Extent (1:248) in database ID 16 is marked allocated in the GAM, but no SGAM or IAM has allocated it.

CHECKDB found 4 allocation errors and 0 consistency errors not associated with any single object.

Msg 8939, Level 16, State 98, Line 1

Table error: Object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data), page (1:119). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 133129 and -4.

Msg 8906, Level 16, State 1, Line 1

Page (1:118) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

Msg 8906, Level 16, State 1, Line 1

Page (1:119) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘IAM_PG MIXED_EXT ALLOCATED   0_PCT_FULL’.

Msg 8906, Level 16, State 1, Line 1

Page (1:120) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

Msg 8906, Level 16, State 1, Line 1

Page (1:121) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

Msg 8906, Level 16, State 1, Line 1

Page (1:126) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

Msg 8906, Level 16, State 1, Line 1

Page (1:127) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

Msg 8906, Level 16, State 1, Line 1

Page (1:142) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

Msg 8906, Level 16, State 1, Line 1

Page (1:144) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

Msg 8906, Level 16, State 1, Line 1

Page (1:145) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

Msg 2575, Level 16, State 1, Line 1

The Index Allocation Map (IAM) page (1:119) is pointed to by the next pointer of IAM page (0:0) in object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data), but it was not detected in the scan.

Msg 8939, Level 16, State 98, Line 1

Table error: Object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data), page (1:119). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 133129 and -4.

Msg 7965, Level 16, State 2, Line 1

Table error: Could not check object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data) due to invalid allocation (IAM) page(s).

CHECKDB found 11 allocation errors and 2 consistency errors in table ‘NUMUNEdata’ (object ID 245575913).

CHECKDB found 15 allocation errors and 2 consistency errors in database ‘NUMUNE’.

repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (NUMUNE).

 

Veritabanını single user mode’a çekip, Repiar Allow Data Loss seçeneği ile düzeltmeye çalışalım.

-- Repair Allow Data Loss
ALTER DATABASE [NUMUNE] SET SINGLE_USER;
GO

DBCC CHECKDB (N'NUMUNE', REPAIR_ALLOW_DATA_LOSS)
WITH NO_INFOMSGS;
GO
----------------------

Msg 8928, Level 16, State 6, Line 1

Object ID 0, index ID -1, partition ID 0, alloc unit ID 0 (type Unknown): Page (1:119) could not be processed.  See other errors for details.

The error has been repaired.

Msg 8905, Level 16, State 1, Line 1

Extent (1:216) in database ID 16 is marked allocated in the GAM, but no SGAM or IAM has allocated it.

The error has been repaired.

Msg 8905, Level 16, State 1, Line 1

Extent (1:232) in database ID 16 is marked allocated in the GAM, but no SGAM or IAM has allocated it.

The error has been repaired.

Msg 8905, Level 16, State 1, Line 1

Extent (1:248) in database ID 16 is marked allocated in the GAM, but no SGAM or IAM has allocated it.

The error has been repaired.

CHECKDB found 4 allocation errors and 0 consistency errors not associated with any single object.

CHECKDB fixed 4 allocation errors and 0 consistency errors not associated with any single object.

Repair: The page (1:118) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Repair: IAM chain for object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data), has been truncated before page (1:119) and will be rebuilt.

Repair: The page (1:120) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Repair: The page (1:121) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Repair: The page (1:126) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Repair: The page (1:127) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Repair: The page (1:142) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Repair: The page (1:144) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Repair: The page (1:145) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Repair: The extent (1:216) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Repair: The extent (1:232) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Repair: The extent (1:248) has been allocated to object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data).

Msg 8906, Level 16, State 1, Line 1

Page (1:118) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

The error has been repaired.

Msg 2575, Level 16, State 1, Line 1

The Index Allocation Map (IAM) page (1:119) is pointed to by the next pointer of IAM page (0:0) in object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data), but it was not detected in the scan.

The error has been repaired.

Msg 8906, Level 16, State 1, Line 1

Page (1:119) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘IAM_PG MIXED_EXT ALLOCATED   0_PCT_FULL’.

The error has been repaired.

Msg 8939, Level 16, State 98, Line 1

Table error: Object ID 245575913, index ID 0, partition ID 72057594039042048, alloc unit ID 72057594043432960 (type In-row data), page (1:119). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 2057 and -4.

The error has been repaired.

Msg 8906, Level 16, State 1, Line 1

Page (1:120) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

The error has been repaired.

Msg 8906, Level 16, State 1, Line 1

Page (1:121) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

The error has been repaired.

Msg 8906, Level 16, State 1, Line 1

Page (1:126) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

The error has been repaired.

Msg 8906, Level 16, State 1, Line 1

Page (1:127) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

The error has been repaired.

Msg 8906, Level 16, State 1, Line 1

Page (1:142) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

The error has been repaired.

Msg 8906, Level 16, State 1, Line 1

Page (1:144) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

The error has been repaired.

Msg 8906, Level 16, State 1, Line 1

Page (1:145) in database ID 16 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags ‘MIXED_EXT ALLOCATED   0_PCT_FULL’.

The error has been repaired.

CHECKDB found 11 allocation errors and 0 consistency errors in table ‘NUMUNEdata’ (object ID 245575913).

CHECKDB fixed 11 allocation errors and 0 consistency errors in table ‘NUMUNEdata’ (object ID 245575913).

CHECKDB found 15 allocation errors and 0 consistency errors in database ‘NUMUNE’.

CHECKDB fixed 15 allocation errors and 0 consistency errors in database ‘NUMUNE’.

 

Tüm hatalar düzeltilmiş gibi duruyor, kırmızı ile işaretli olan satırlardaki hataların tümü repaired edilmiş. Checkdb ile son bir kotrol yapıyoruz,

DBCC CHECKDB (N'NUMUNE') WITH NO_INFOMSGS;
GO

Hiçbir hata vermedi, ama veritabanımız hala Single User Mode’da, Multi User moda çekmemiz gerekiyor. Unutmamakta fayda var, boşa zaman kaybı yaşamayın.

ALTER DATABASE [NUMUNE] SET MULTI_USER;
GO

Repair işlemlerini production ortamında yapmadan önce, mutlaka test ortamında deneyiniz. Her zaman test ortamınızın hazır olması gerekmektedir, bir de bunları test ortamında deneyipte vakit mi kaybedeceğiz demeyin. Production tarafında yapılan bir hatanın geri dönüşü olmayabilir.

Bu makalede; corruptionlar nasıl meydana gelir, nasıl tespit edilir, tutarlılık testleri (Consistency Checks), Dbcc Checkdb komutunun ne olduğu-neler yaptığı, temel geri yükleme bilgileri ve temel onarım bilgilerini aktarmaya çalıştım. Makalenin başında da bahsettiğim gibi veritabanı bozulmalarını ilk tetikleyenler donanım sorunları olmaktadır. Disklerinizin durumunu sık sık kontrol etmelisiniz, çok eski disklerle devam etmek zorunda kalıyorsanız, sürekli veritabanı seviyesinde testler yapmayı ihmal etmeyiniz.