17 Temmuz 2017 Pazartesi

Bir içeriden saldırı hikayesi

Geçen hafta bir firmadan bir e-posta aldım, içeriği aynen şöyleydi:

"Elektrik gidip geldi ve SQL Database Recovery Pending moduna geçti. Konu hakkında yardımcı olabilir misiniz?"

Kısa ve öz.

Kendilerini aradım, konuştuk. Gündüz başka işlerim olduğu için, akşam bağlanıp kontrol edebileceğimi söyledim kendilerine. Akşam bağlanıp kontrol ettiğimde ve görüşmelere devam edip durum hakkında daha fazla şey öğrendiğimde ortaya çıkan tablo şöyleydi:

- "Recovery Pending" durumunda olduğu söylenen veritabanı dosyaları "Corrupt" idi, yani bozulmuşlardı,
- Bozulan veritabanı bir muhasebe uygulamasına aitti,
- Bozulan veritabanının yedek dosyaları da bozulmuş durumdaydı,
- Bozulan veritabanının normal şartlarda bağlı olduğu SQL Server Instance'ı silinmişti,
- Bozulan veritabanına ait yedek dosyaları Rar uygulaması ile şifreli sıkıştırılmıştı,
- Bozulan veritabanına ait ulaşılabilen ve çalışır halde olan en güncel yedek 3 ay öncesine aitti.

Sanırım hikayenin aslının ne olduğunu, biraz da dehşete kapılarak tahmin etmişsinizdir. Ben durumun böyle olduğunu gördüğümde, görüştüğüm yetkiliye bu durumun ancak "sinirli" ve "kırgın" bir şekilde işten ayrılan eski bir çalışan tarafından oluşturulabileceğini ilettim. Kendisi de bu senaryoyu onayladı.

Veritabanı dosyaları ve yedekler gerçekten elektrikler birden gidip sunucu kapandığı için mi, yoksa eski çalışan tarafından kasten mi bozulmuştu bilemiyorum, bunun aslını sanırım ancak beni arayan kişi ve işten ayrılan kişi bilir; ama durum içinden çıkılmaz bir haldeydi. Çünkü tüm kontrol sadece o işten ayrılan kişideydi, başka hiçbir yedekleme mekanizması yoktu. Haliyle ben de bir şey yapamadım.

Saldırıları veya felaketleri sadece firma dışından beklemeyin. Paranoyak olun ve herkese düşman gibi nefretle bakın demiyorum elbette, ama gerekli önlemleri aldığınızdan emin olmalısınız. İnsanların niyeti iyi veya kötü olabilir, siz her türlü niyet ve senaryo için olabildiğince hazırlıklı olmalısınız. Aksi takdirde kendinizi yukarıdakine benzer bir senaryonun oyuncularından biri durumunda bulabilirsiniz.

Not: Bir çözüm üretemediğim, müşteriyi memnun edemediğim işlerden ücret talep etmiyorum. Fakat en azından harcadığım o kadar zaman ve emek için bir teşekkür beklemek sanırım hakkım. Maalesef bu firmadaki yönetici arkadaş bunca inceleme ve harcanan zaman sonrası gönderdiğim durum raporuna cevap bile vermedi. Yine maalesef, bu örnek tek değil. Bu gibi durumlarda iletişime geçen herhangi bir kişi veya firmaya neden hemen yardımcı olmak istediğimi, bu kadar iyi niyetli yaklaştığımı ciddi ciddi sorguluyorum. Bazıları böyle bir ilgiyi gerçekten, hiç hak etmiyor.

Ekrem Önsoy
Microsoft SQL Server Danışmanı
www.ekremonsoy.com

11 Temmuz 2017 Salı

"Transaction Log" yedeğinin alınması neden uzun sürebilir?

Son zamanlarda bir ortamda Transaction Log yedeği alınırken yedek alma işleminin 1-2 saati bulabildiğini gözlemledim. Normal şartlar altında 2 dakikada bir yedek alınan ve yedeklerin de ortalama 10MB olduğu bir ortamdan bahsediyorum.

Sorunu incelerken Transaction Log yedek alma işleminin (BACKUP LOG ...) bir sistem işlemi tarafından (o anki "session_id"si 18 idi) bloke edildiğini gördüm. İşler gerçekten ilginçleşiyordu. O sistem işleminin ne olduğunu inceleyince Checkpoint olduğunu gördüm. Açıkçası, Checkpoint işleminin Transaction Log yedek işlemini bloke ettiğini ilk defa görüyordum.

Sorunu daha fazla inceledikçe aslında sorunun disk altyapısında olduğunu tespit ettim. Yani Transaction Log yedek alma işlemi aslında doğrudan kendi başına bir sorun değildi, başka bir sorunun sonucu oluşan bir durumdu.

Aklına "Disk altyapısındaki sorun, Checkpoint ve Transaction Log yedeği ne alaka?" diye soru gelenler için Checkpoint işlemine çok özetle deyineyim. SQL Server'da varolan kayıtlarda değişiklikler yaptığınızda veya yeni kayıtlar oluşturduğunuzda bu değişiklikler doğrudan veritabanı veri dosyalarına işlenmez, önce Transaction Log dosyasına işlenir, daha sonra da belli formüllere göre devreye giren Checkpoint ile bu değişiklikler ilgili veritabanı veri dosyalarına işlenir. Disk altyapısında performans sorunu olunca, Checkpoint ile değişikliklerin diske işlenmesi uzun sürüyordu ve bu da Transaction Log yedeklenmesi işlemini bloke ediyordu. Ben de bu sayede Checkpoint devam ediyorken Transaction Log yedek alınma işleminin sonlanamadığını, bloke olduğunu öğrenmiş oldum.

Biraz kısa bir yazı oldu, ama yine de değerli bir tecrübe olduğunu düşünerek paylaşmak istedim. Olur da bir gün Transaction Log'unun yedeğinin alınması uzun sürerse, disk altyapısının performansını da kontrol etmeyi unutmayın.

Not: Transaction Log ve veritabanı yedekleme işleminin uzun sürmesinin daha başka birçok nedeni var, ama bu yazıda belirli bir konuya değinmek istedim. 

Ekrem Önsoy
Microsoft SQL Server Danışmanı
www.ekremonsoy.com

3 Temmuz 2017 Pazartesi

Bakım çalışması sırasında disk alanının geçici olarak azalması durumu

Yönettiğim ortamların birinde aşağıdaki gibi bir senaryo oluştu, durumu bir veritabanı yöneticisinin ağzından aktarayım:

- Veritabanının veri dosyalarından biri (*.mdf veya *.ndf) E: diskinde konumlandırılmış durumda,
- Bu veri dosyasının otomatik büyüme (auto growth) özelliği kapalı,
- Gece diskin kapasitesine dair bazı alarmlar gelmiş. Sabah kalktığımda kontrol ettim, diskte sadece veritabanı veri dosyası görünüyor ve dosya değiştirilme tarihi bugünden daha eski bir tarih, bu dosya büyümemiş bundan eminim. Diskin boyutu da alarmlarda belirtilenden farklı. Zaten alarmlar da belli bir süre sonra durmuş.
- Bunun nasıl bir açıklaması olabilir?

Bu durum, DBCC CHECKDB komutuyla bütünlük kontrolü yapılırken oluşabilir. Eğer yukarıdakine benzer bir senaryo yaşadıysanız, ki umuyorum ki düzenli olarak en azından haftada bir kere bu bakımı yapıyorsunuzdur, bunun nedeni DBCC CHECKDB komutunun oluşturduğu dahili "snapshot"tır.

Dahili "snapshot" veritabanı, DBCC CHECKDB komutunun çalıştırıldığı veritabanının her bir veri dosyası için aşağıdaki ekran görüntüsünde olduğu gibi ayrı ayrı "snapshot" dosyaları oluşturur. Örneğin aşağıdaki durumda diskin kapasitesi 500GB idi; ama iki tane 460GB'lık dosya görüyorsunuz, peki bu nasıl oluyor? Çünkü "snapshot" dosyalarının boyutları her ne kadar veri dosyalarıyla aynı görünse de, o kadar yeri birden rezerve etmiyorlar. Bu dosyalar, dosya sistemi seviyesinde "sparse" olarak işaretlenirler. DBCC CHECKDB komutu çalıştığı sürece ilgili veritabanında ne kadar çok işlem yapılıyorsa, bu "snapshot" dosyaları da o kadar dolar.


Yine bu senaryoda E: diskinin kapasitesi 500GB iken ve gerçek veritabanının veri dosyasının boyutu 460GB iken, gelen disk kapasite alarmları azar azar artarak geliyordu. Bunun nedeni de bir önceki paragrafta belirttiğim gibi "snapshot" dosyalarının DBCC CHECKDB komutu çalışmaya devam ederken gerçek veritabanı dosyasında yapılan değişiklikler nedeniyle, yine yapılan işlem hacmine göre dosyanın adım adım dolması.

Veritabanı bütünlük kontrolü tamamlandıktan sonra "snapshot" dosyaları otomatik olarak silinir. Eğer sunucu veritabanı bütünlük kontrolü sırasında beklenmedik bir şekilde kapanırsa, o zaman bu dosyalar silinmez ve hem diskte boş yere yer kaplarlar, hem de tekrar bütünlük kontrolü yapmaya kalktığınızda ilginç hatalarla karşılaşabilirsiniz.

DBCC CHECKDB komutu zaten çok IO yoğunluklu bir işlemdir. Bu nedenle muhakkak veritabanı sistemlerinizin "yatış" durumunda oldukları zaman çalıştırılmalıdırlar. DBCC CHECKDB komutunun neden yoğun zamanlarda çalıştırılmaması gerektiğine bir de bu yazımda anlattığım nedeni ekleyebilirsiniz. Çünkü DBCC CHECKDB komutu çalıştığı sürece veri dosyalarınızın bulunduğu disklerin doluluk oranları artacaktır. Eğer disklerde yeterince yer yoksa çeşitli sorunlar yaşayabilirsiniz, en kötü ihtimalle can sıkıcı ve korkutucu alarmlar alabilirsiniz, ki umarım disk doluluk oranlarınızı yakınen takip ediyorsunuzdur.

Ekrem Önsoy
Microsoft SQL Server Danışmanı
www.ekremonsoy.com

23 Haziran 2017 Cuma

Yine, gene ve tekrar: Bir felaket hikayesi (veri kaybı) daha...

Ne kadar yazarsak yazalım (yazı, yazı, yazı) sonuçta yazdıklarımız, konuştuklarımız belli bir kitleye ulaşabiliyor.

Dün akşam bir tekstil firmasından aradılar ve teknik işlere bakan arkadaş telefonda şöyle dedi: 

"Bir veritabanı sunucumuz var ve bunun diskleri aslında yedekli, ama bu disklerden biri hata verdi ve yedek diskten veritabanı dosyalarını ve yedek dosyalarını kurtardık; ama bir türlü Attach edemiyoruz."

Sorunun yaşandığı SQL Server sunucusuna uzaktan bağlandım ve veritabanı dosyalarını ve yedek dosyalarını kontrol ettim.

Veritabanı dosyalarını Attach etmeye çalıştığımda bütünlük/IO tutarlılığı hatası alındığını gördüm. Bu etapta hata 9 sayılı Page'te alınıyordu. Bu da Boot Page demek. Bu noktada yedek dosyalarını düşündüm, fakat onların bütünlük kontrollerini yaptığımda veritabanı yedek dosyalarının bozulmuş olduğunu gördüm.

Veritabanlarının 6 ay önceki çalışan hallerinin sağlam kopyaları da ayrıca vardı. Sorun Boot Page'te olduğu için, eski veritabanlarından Boot Page'leri bu sorun yaşanan veritabanlarına aktarabilirdim. Bunu yaptım. Fakat gördüm ki tek sorun Boot Page'te değil. Boot Page'i onardıktan sonra da farklı farklı Page'lerde sorun yaşandığını gördüm. Sonraki kontrollerimde 3. Page'ten 36. Page'e kadar verilerin veritabanı dosyalarından komple silinmiş olduklarını gördüm.

Bu noktada artık şahsen benim yapabileceğim bir şey kalmadı. Kendilerine veri kurtarma konusunda çalışabilecekleri bir firma aramalarını önerdim. Ne kadar başarılı bir sonuç alınabilir, emin değilim; ama maalesef bu noktada artık görüşmeyi sonlandırdık.

Benim başıma gelmez demeyin, gerekli önlemleri almazsanız herkesin başına gelebilir bu durum. Geçen hafta sağlık bakımı çalışması yaptığım çok önemli bir veritabanı sunucusunda 2 aydır yedek alınmadığını tespit edip ilgili yöneticilere bildirdiğimde şok oldular.

Veritabanı dosyalarınızı ve aldığınız yedekleri aynı sunucu üstünde tutsanız bile en azından aynı disk altyapısında tutmayın. Mümkünse muhakkak yedeklerinizi uzaktaki, ayrı bir sunucuda düzenli ve güncel olarak barındırın. Kaybetmeye tahammülünüz olabilecek veri miktarını ve azami olarak ne kadar sürede geri dönmeniz gerektiğini önceden belirleyin ve yedekleme stratejinizi buna göre oluşturun. Yedekleme "kısmet" kategorisine girmeyecek kadar önemli bir konu. Yukarıda bahsettiğim tekstil firması muhtemelen son 6 aylık verisini kaybetti. Şirket bununla nasıl başa çıkacak bilemiyorum, ama umarım çok büyük kayıp yaşamazlar. Başkalarının hatalarından ders alarak kazanılan tecrübe, en ucuz ve acısız kazanılan tecrübedir, unutmayın.

Kazasız, belasız güzel günler dilerim.

Ekrem Önsoy
Microsoft SQL Server Danışmanı

6 Haziran 2017 Salı

Veritabanlarıyla rus ruleti oynamak

Yedeklemenin önemi ile ilgili (Bağlantı1, Bağlantı2) birçok yazı yazmama karşın maalesef sahada bu konuda birçok kötü pratik görüyorum. Son zamanlarda ilginç bir iş geldi. Önceden de bir projede birlikte çalıştığımız bir şirketten aradılar ve şöyle bir senaryo anlattılar:

- Yazılımcı, sistem yöneticisine Y veritabanının yedeğinin olup olmadığını soruyor,
- Sistem yöneticisi "var" diyor ve X konumuna Y veritabanının dosyalarını kopyalıyor,
- Yazılımcı, Y veritabanının zaten yedeği var diye, Y veritabanının kendisini (ayrıntılarını bilmediğim bir nedenden dolayı) ilgili SQL Server Instance'ından siliyor,
- Aradan 15 günden fazla bir süre geçtikten sonra yazılımcı X konumundaki yedeklerden dosyaları Attach ederek Y veritabanını geri getirmeye çalışıyor; fakat fark ediyor ki veritabanı dosyalarından biri eksik ve bu nedenle veritabanı Attach olmuyor,
- Yazılımcı, sistem yöneticisine bu eksikliği bildiriyor,
- Sistem yöneticisi geriye dönük olarak sadece 15 günlük yedek tuttuklarını iletiyor ve Y veritabanı ilgili SQL Server Instance'ından silineli 15 günden fazla olduğu için artık herhangi bir yerde bu veritabanının herhangi bir yedeğinin olmadığı anlaşılıyor,
- Bahsi geçen Y veritabanı, ilgili şirketin 4-5 senelik arşivi.
- Bu noktada benimle temas kurdular.

Hiçbir ekstra açıklamaya gerek kalmadan sırf yukarıdaki maddelerden, neyi nasıl yapmamanız gerektiğine dair birçok sonuç çıkarmışsınızdır diye tahmin ediyorum.

Bu sefer gerçekten çok şanslılardı ve veritabanını ciddi bir kayıp olmadan kurtarabildik. Ben elimden geleni yaparım, ama kimse bu konularda sadece şansına güvenmesin lütfen, her zaman bu seferki gibi şanslı olmayabilirsiniz.

Ekrem Önsoy
Microsoft SQL Server Danışmanı
www.ekremonsoy.com