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

18 Mayıs 2017 Perşembe

Bir sorun "çözme" yöntemi: SQL Server servisinin düzenli olarak kapatılıp açılması fenomeni

Microsoft SQL Server ortamları için "sağlık-kontrolü / healthcheck" ve performans iyileştirme çalışmaları için yeni müşterilere gittiğimde zaman zaman "Procedure ve Data Cache"in düzenli olarak boşaltıldığını veya Microsoft SQL Server sunucusunun düzenli olarak (mesela haftada bir veya ayda bir) yeniden başlatıldığını görüyorum. Müşteriye nedenini sorduğumda ise şöyle yanıtlar geliyor:

  1. Zamanla SQL Server çok RAM kullanıyor, bunu düzeltmek için,
  2. CPU kullanımı zaman zaman tavan yapıyor, sunucuyu yeniden başlatınca düzeliyor,
  3. Tam emin değiliz; ama zamanla SQL Server'da çalışan sorgular yavaşlıyor, yeniden başlatmak sorunları çözüyor.
  4. Sizden önceki gelen danışman veya X arkadaş böyle tavsiye etti,


    Bahsettiğim senaryoda aldığım yanıtlar aşağı yukarı hep böyle. Bu yanıtları özellikle numaralandırdım, çünkü aşağıda tek tek özetle açıklayacağım.

    1- SQL Server kurulumlarında varsayılan olarak SQL Server sunucuda varolan tüm hafıza kaynağını kullanmak üzere ayarlıdır ve doğası gereği sadece SQL Server değil, tüm veritabanı sistemleri olabildiğince RAM kullanmak ister. Ne kadar çok işlem diskten değil de doğrudan hafızadan yapılabilirse, işlemler o kadar hızlı gerçekleşir. 

    İşletim sistemi, SQL Server'ın kendi diğer bileşenleri veya sunucu üstündeki diğer uygulamaların da hafıza ihtiyacı vardır ve SQL Server yapılandırması da bu çerçevede ayarlanmalıdır. Aksi takdirde "Paging / Swap" oluşur, bu da uygulamaların ağır çalışmasına, yani performans sıkıntılarına neden olur. Çünkü yetersiz hafıza kaynağı nedeniyle uygulamalar çatışır ve Windows işletim sisteminin Page File'ı kullanılmaya başlanır. Yani hafıza (RAM) yerine bazı uygulamalar için fiziksel disk hafıza niyetiyle kullanılmaya başlanır, ki bu yöntem hafızaya göre defalarca kat yavaştır. Donmalara, uzun süreli beklemelere neden olur.

    2- Bunun nedeni genellikle "Parameter sniffing"tir. Parameter sniffing normal şartlar altında kendi başına bir sorun değildir, ama planlar anormal değerlere göre derlendiğinde parameter sniffing can yakabilir. Her sorgu çalışmadan önce o sorgu için bir çalıştırma planı (Execution Plan) oluşturulur ve bu çalıştırma planı da sorgu çalıştırılırken kullanılan ilk parametre değerine göre oluşturulur. Çalıştırma planı Plan Cache'te konumlandıktan sonra (parameterize sorgular, stored procedure'ler ve diğer basit sorgular gibi) ilgili sorgular artık bu planı kullanarak çalışır. Eğer plan en uygun şekilde ve en genel talebe hitap edecek değerlerle oluşmadıysa, kötü bir performans ile çalışabilir ve bu da CPU'nun ve diğer donanım kaynaklarının verimsiz olarak kullanılmasına neden olabilir.

    Plan Cache'i boşalttığınızda veya SQL Server servisini yeniden başlattığınızda (veya bazı SQL Server Instance'ı düzeyinde ayarı değiştirdikten sonra veya tekil bir planı Plan Cache'ten sildikten sonra) sorunlu çalıştırma planı gitmiş olur ve ilgili sorgu veya stored procedure ilk çalıştırışınızda yeni bir plan oluşturulur. Şansınıza yeni plan daha uygun değerler kullanılarak oluşturulabileceği için o anda "sorun çözüldü" sanabilirsiniz. Fakat Plan Cache'in bir dahaki sıfırlanışında veya herhangi başka bir nedenle ve zamanda bu plan yeniden kötü bir şekilde derlendiğinde yine bu sorunu yaşarsınız.

    Yani sunucuyu veya SQL Server servisini kapatıp açmak kalıcı bir çözüm değildir, bu nedenle sürekli kapatıp açmaya devam edersiniz.

    3- Bunun nedeni genellikle ya 2. maddede açıkladığım neden veya sorguların bloklanması (blocking) kaynaklı oluyor. Haliyle sunucu veya servis yeniden başlatılırken tüm bloke eden sorgular da sonlandırılmış oluyor ve servis yeniden başlayınca bloke olma sorunu "çözülmüş" oluyor.

    4- Eğer bir danışman veya X arkadaş ilk 3 maddede yaşanılan sorunlar için size en iyi pratik olarak "SQL Server servisini veya sunucusunu düzenli olarak yeniden başlatmayı" veya "Cache'leri boşaltmayı" önerirse arkanıza bakmadan kaçın. Tabii ofis ve ortam sizin olacağı için kaçamayacağınıza göre "arkadaşa" veya her ne sıfatla size bunu öneriyorsa ona bir çay ısmarlayıp nazikçe konuyu düşüneceğinizi iletebilir ve numarasını telefonunuzdan silebilirsiniz.

    Peki "Cache"lerin boşaltılması neden kötü?
    • Ad-hoc ve dinamik olmayan, parameterize olan tüm sorguların ilk çalışışlarında bir çalıştırma planı oluşturulur ve (sunucu ayarlarınıza göre) bu plan ilk veya ikinci seferinde Plan Cache'te konumlandırılır. Daha sonra ilgili sorgu / stored procedure her çalıştığında bu planı kullanır. Çalıştırma planının oluşturulma işlemi CPU yüklü bir işlemdir. Eğer sık sık Plan Cache'i boşaltırsanız veya ilgili sorgu her çalıştığında planın yeniden derlenmesini sağlarsanız sık sık tüm ilgili işlemler için yeniden çalıştırma planı oluşturulması gerekir ve bu da işlemlerinizin anlık olarak yavaşlamasına, genel olarak sunucu işlemci masraflarınızın artmasına neden olur.
    • SQL Server'da geleneksel (In-memory / Hekaton olmayan) bir tablodaki kayıtlar için işlem yapacağınız zaman bu işlem hafızada (RAM) yapılır ve daha sonra Lazy Writer veya Checkpoint ile diske aktarılır. Update, Delete ve Insert hangi DML komutu çalıştırırsanız çalıştırın, ilgili kayıtlar önce hafızada değiştirilir doğrudan diskteki kayıt değiştirilmez. Eğer değişiklik yapılmak istenen kayıtlar Data Cache'te / Buffer Pool'da yoksa, önce diskten okunur ve Buffer Pool'a getirilir ve kayıtlardaki değişiklik hafızada yapılır (bu durumda ilgili kayıtlar "Dirty Page" olur). Select için de aynı şey söz konusu, sorguladığınız kayıtları içeren Page'ler hafızada yoksa önce diskten Buffer Pool'a taşınır ve sorgunuz ondan sonra cevap verir. Bu nedenle işlem yapılacak kayıtların ne kadar çoğu hafızadaysa, işlemler o kadar hızlı gerçekleşir. Eğer siz düzenli olarak Buffer Pool / Data Cache'i boşaltırsanız, bu sefer her seferinde, her kayıt için önce diske gidip o kayıtları hafızaya yüklemek gerekiyor. Böyle bir ortamda da bol bol PAGEIOLATCH bekleme tipleri görürsünüz, çünkü diskleriniz harıl harıl çalışır durur, kullanıcılar yavaşlık hisseder. Bazı senaryolarda Deadlock ve Blocking'in nedeni de budur.
    Veritabanı sunucunuzu sürekli yeniden başlatarak ve Cache'leri düzenli olarak boşaltarak sorunları sadece ötelemiş olursunuz. Bu sorunları çözmek için SQL Server Instance'larınızın doğru yapılandırılması, sorunlu sorguların iyileştirilmesi, çalıştırma planlarının çeşitli tekniklerle istikrarlı hale getirilmesi ve gerekiyorsa dondurulması gerekiyor. Yukarıda maddeler halinde sıraladığım sorunların tek çözümü budur.

    Ekrem Önsoy
    Microsoft SQL Server Danışmanı

    4 Mayıs 2017 Perşembe

    Bir Cumulative Update kazası

    Bu sıralar bir müşterimin canlı veritabanı sunucusu için SQL Server 2012'den SQL Server 2016'ya sürüm yükseltme çalışmaları yapıyorum. Bu çalışmalar sırasında geçen sene de karşılaştığım, ama hakkında yazı yazamadığım bir sorun ile tekrar karşılaştım. Bu sefer bu sorunu günlüğüme kaydediyorum.

    Bu çalışma kapsamında yeni bir Windows Server 2016 kurulumu ve üstüne de SQL Server 2016 kurulumu yaptık. Müşterim SQL Server Standard Edition kullandığı için, SQL Server 2016 Service Pack 1 ile gelen birçok Enterprise Edition özelliğinden faydalanabileceği gibi SQL Server 2016 ile gelen yeniliklerden de faydalanabilecek. Bu ortamdaki en büyük maliyet disklerden kaynaklanıyor. Bu sürüm yükseltme çalışmasıyla Data Compression ve Columnstore indeksler ile müşterimin disk maliyetlerini ciddi oranda düşürmeyi ve aynı zamanda performansın iyileşmesini hedefliyorum. Ayrıca dahili ve harici denetim firmaları hassas verilerin maskelenmesini ve nesne düzeyinde kayıt tutulmasını talep ediyor; Dynamic Data Masking ile verilerin maskelenmesini ve Database Level Auditing ile de nesne düzeyinde kayıt tutulmasını sağlayacağız. Tüm bu ihtiyaçlar ekstra bir ürün alıp hem karmaşaya hem de ekstra maliyete neden olmadan sağlanmış olacak.

    Windows Server 2016'yı, SQL Server 2016'yı ve Service Pack 1'i kurduktan sonra en son Cumulative Update'i de kurarken, kurulumun sonunda gereğinden uzun süre bekleyince bir sorunun olduğunu anlamıştım. Tabii ki bekledim ve ardından beni bekleyen hata mesajıyla karşılaştım:


    Cumulative Update (KB4013106) kurulumunda oluşan hata mesajı
    Başlatılamayan tek servis "SQLSERVERAGENT" değildi, "MSSQLSERVER" yani Database Engine servisi de "Change Pending" durumunda kalmıştı. Windows Event Log'larını ve SQL Server Error Log'larını inceledim, şu mesajlar vardı:

    "Script level upgrade for database 'master' failed because upgrade step 'msdb110_upgrade.sql' encountered error 226, state 6, severity 16. This is a serious error condition which might interfere with regular operation and the database will be taken offline. If the error happened during upgrade of the 'master' database, it will prevent the entire SQL Server instance from starting. Examine the previous errorlog entries for errors, take the appropriate corrective actions and re-start the database so that the script upgrade steps run to completion."

    "Cannot recover the master database. SQL Server is unable to run. Restore master from a full backup, repair it, or rebuild it. For more information about how to rebuild the master database, see SQL Server Books Online."

    Nasıl, mesajlar yeterince korkutucu mu? Bu sefer bu sorun ile yeni, geçiş sunucusunda karşılaştım; ama geçen sene bu sorunla karşılaştığımda ortam canlı ortamdı. Benzer hataları bir de canlı bir ortamda aldığınızı düşünün...

    SQL Error Log'da aşağıdaki mesaj öbeğine odaklandım:


    SQL Server Error Log'tan bir görüntü

    Mesajlardan da görebileceğiniz üzere haliyle önce replikasyondan şüphelendim, bu sunucuda 70 küsur veritabanı var ve canlıda 2 tanesi Transactional Replication ile raporlama sunucusuna replike ediliyor. Önce bu 2 veritabanındaki replikasyon artıklarını kaldırmayı düşündüm ve bunu yapmam için de [sp_removedbreplication] sistem SP'sini çalıştırmam gerekiyor, ama Database Engine servisi hiç açılmıyor, bunu nasıl yapacağım?

    Neyse ki böyle durumlarda kullanabileceğimiz bir Trace Flag var, T902. Database Engine servisini Trace Flag 902 ile başlatırsanız, Service Pack veya Cumulative Update Script'leri servis açılışında çalıştırılmaz ve böylece Database Engine servisiniz açılabilir. Ben de böyle yaptım ve Database Engine servisini T902 ile çalıştırdım ve ardından ilgili 2 veritabanı için [sp_removedbreplication] komutunu çalıştırıp veritabanlarındaki replikasyon artıklarını temizledim ve Database Engine servisini T902'siz çalıştırdım. Maalesef sorun çözülmemişti.

    Not: Unutmayın, Trace Flag'leri bilinçli bir şekilde kullanmalısınız. Örneğin Trace Flag 902 sadece böyle bir durumda ve geçici olarak kullanılmalıdır. Canlı ortamınızı sürekli Trace Flag 902 çalıştırmamalısınız.

    Bu sefer hata mesajının oluştuğu silsileye odaklandım ve tam olarak her seferinde Upgrade Script'inin belli bir veritabanı adından sonra hata aldığını fark ettim. Bu veritabanı da önceden replike ediliyordu, ama uzun süre önce ilgili arkadaşların talebiyle replikasyondan çıkartmıştım. Database Engine servisini yine T902 ile çalıştırdım ve bu veritabanını bu SQL Server Instance'ından Detach ettim, yani bu veritabanının ilişiğini kestim. Daha sonra Upgrade Script'i olan [sp_vupgrade_replication] isimli Script'i Query Editor'den elle çalıştırınca hata oluşmadığını gördüm. Database Engine servisini T902'siz tekrar çalıştırdım ve Viola! Database Engine servisim artık sorunsuz çalışıyordu. Demek ki bir şekilde, kim bilir neden, ama bu veritabanımın içinde eski replikasyon kurulumuyla ilgili bazı sıkıntılar/artıklar vs kalmıştı ve Service Pack 1 kurulumunda değil, ama Cumulative Update kurulumunda hataya neden olmuştu.

    Tabii ki konuyu burada bırakamazdım, sonuçta bu veritabanının da Upgrade işlemini tamamlatmam ve taşımam gerekiyordu. İçimden bir ses veritabanını tekrar Attach edince, yani tekrar SQL Server Instance'ına bağlayınca sorunun kendiliğinden çözüleceğini söylüyordu ve aynen öyle de oldu. Cumulative Update ve Upgrade Script'lerinin çalıştırılması sırasında hataya neden olan veritabanı, tekrar Attach edilince herhangi bir sıkıntıya neden olmamıştı.

    Böylece bir güncelleme sürecini daha kazalı belalı da olsa atlatmış oldum. Olur da benzer bir sorun ile karşılaşırsınız ve faydası olabilir diye sizlerle de paylaşmak istedim.

    Kazasız, belasız günler dilerim!

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



    20 Nisan 2017 Perşembe

    Duyuru: Microsoft İş Ortaklığı

    Gün itibariyle, gerek Microsoft Azure bulut ortamında, gerekse geleneksel ortamlardaki Microsoft SQL Server konusunda kurulum, sağlık bakımı (healthcheck), performans iyileştirme çalışmaları, sürekli kullanılabilirlik ve felaket önleme planlama ve kurulumları konusunda uzmanlaşmış olan ve hizmet veren şirketimin Microsoft Silver Cloud Partner olduğunu iftihar ile ilan ederim efendim.

    Bu iş ortaklığı sayesinde, yaptığımız projelerde Microsoft ile daha yakın çalışabileceğiz. Projelerimizde Microsoft ürünleriyle ilgili karşılaştığımız sorunlar için Microsoft'tan daha iyi destek alabileceğiz.

    Bu süreçteki desteği için Hakan Türköner'e ve bu vesileyle benimle çalışmayı tercih eden değerli tüm müşterilerime teşekkür ederim.

    Verdiğimiz hizmetler hakkında daha fazla bilgi için lütfen tıklayın.


    4 Nisan 2017 Salı

    Olası gizemli kesintilere hazırlıklı mısınız?

    Yoğunluktan dolayı yine uzun bir süre yazamadım, projelerden kalan bu aralıkta hemen bu yazıyı yazmak istedim.

    Bir müşterimde bir süredir büyük bir tabloda yaşanan dahili kayıt tekilleştirici mekanizmasının yarattığı kesinti sorununun giderilmesi konusunda çalışıyorduk. Nihayet sorunu giderdik. Bu yazımda sorunun tanımından ve çözmek için neler yapılabileceğinden özetle bahsedeceğim.

    Yazının başında belirtmem gerekir ki bu yazı Microsoft SQL Server konusunda bazı ileri seviye terim ve kavramları bilmenizi gerektiriyor. Bu yazıda her kavramı tek tek açıklamayı hedeflemiyorum.

    "Dahili kayıt tekilleştirici" nedir önce ondan bahsedeyim. Muhtemelen oldukça küçük bir azınlığın haberdar olduğu bir terim olduğu için ilk bakışta ilginç görünse de Türkçe olarak tanımlamak istedim ki biraz daha anlaşılabilir olsun. Efendim bahsettiğim kavram Microsoft SQL Server ürünündeki Clustered tablolardaki tekrar eden kayıtların tekilleştirilmesi için kullanılan Uniquifier kavramı. Öncelikle bu kavram tam olarak nerede, nasıl ve neden kullanılıyor ondan bahsedeyim.

    Bir tabloyu Clustered yaptığınızda, yani bir tabloda bir Clustered indeks oluşturduğunuzda, o tablodaki tüm kayıtların eşsiz olması gerekiyor. Bu eşsizliği, oluşturacağınız Clustered indeksi Unique Clustered indeks olarak oluşturarak sağlayabilirsiniz; aksi takdirde, yani indeksinizi Unique Clustered indeks olarak değil de sadece Clustered olarak oluşturursanız SQL Server indeksinize Uniquifier adında dahili bir alan ekleyecektir. Normal şartlar altında, SELECT sorgularınızda veya [sp_helpindex] ile ve benzeri diğer yöntemlerle bu alanı görmezsiniz. Bu alanın varlığını ve etkilerini görebilmek için özel bazı yöntemler kullanmak gerekiyor. Heap tablolarda, yani bir Clustered indeks tanımlanmamış bir tablodaki kayıtların bir Unique indeks ile veya Uniquifier ile eşsizleştirilmesine ihtiyaç yoktur.

    Uniquifier isimli alanın veritipi INT'tir, tutabileceği azami değer 2.147.483.647'dir ve diskte 4 baytlık yer kaplar. Cluster Key kendini tekrar etmedikçe Uniquifier'ın değeri artmaz, 0 olarak kalır ve diskte de yer kaplamaz. Cluster Key, Clustered indeksi oluşturan alandır. Clustered indeksi oluşturan alan sayısı birden fazla da olabilir, birden fazla alandan oluşan indekslere de Composite indeks denir.

    Biraz da örnek ve görsellerle anlatayım, bu kavramlara çok yabancı olan arkadaşlar için daha anlaşılabilir olsun.

    Not: Öncelikle şunu belirtmek gerekiyor ki DBCC PAGE komutu Microsoft tarafından resmen desteklenen ve dokümante edilmiş bir komut değildir. Bu ve diğer komutları canlı/üretim sunucularınızda çalıştırmamanızı öneririm.

    Bu örnekte önce [uniq_test] adında bir tablo oluşturuyorum ve bu tablodaki [id] alanı için de bir Clustered indeks oluşturuyorum. Sonra aynı kayıttan 2 tane oluşturuyorum. DBCC IND komutuyla [test] veritabanındaki [uniq_test] tablosunun Page'lerini tespit ediyorum. DBCC PAGE komutuyla da yine [test] veritabanındaki birinci veri dosyasındaki 36296 numaralı Page'in içeriğine bakıyorum.

    CREATE TABLE [uniq_test](id INT, isim NVARCHAR(50), soyisim NVARCHAR(50));
    GO
    CREATE CLUSTERED INDEX [CIX] ON [uniq_test]([id]);
    GO
    INSERT INTO [uniq_test] VALUES(1, 'Ekrem', 'Önsoy');
    GO 2
    DBCC IND([test], [uniq_test], 1);
    GO
    DBCC PAGE(test, 1, 36296, 3) WITH TABLERESULTS;


    DBCC PAGE'in sonucu

    Not: Burada [isim] ve [soyisim] alanlarının aynı olması değil, [id] alanının aynı olması Uniquifier'ın kullanılmasını sağlıyor. [isim] ve [soyisim] alanları farklı da olsa yine de Uniquifier değeri artacaktı.

    Not: DBCC IND komutu sizde muhtemelen farklı bir Page numarası döndürecektir, bunda hiçbir gariplik veya sakınca yok. Eğer örneği siz de kendi test ortamınızda uygulamak istiyorsanız DBCC PAGE komutuyla sizde dönen Page numarasını kullanın.

    DBCC PAGE ile ilgili Page'in içerisine baktığımda yukarıdaki ekran görüntüsünde paylaştığım gibi bir sonuç görüyorum. Önceden de belirttiğim gibi eğer Clustered indeksimi oluştururken Unique Clustered indeks olarak oluştursaydım veya hiç Clustered indeks oluşturmasaydım ve yine bu Page'in içine baksaydım o zaman UNIQUIFIER diye bir alanı hiç görmeyecektim.

    Yukarıdaki ekran görüntüsünde oluşturduğum 2 kayda ait değerleri her kayıt için ayrı ayrı renklerle ve dikdörtgen ile işaretledim. Önce lütfen daha uzun olan kırmızı ve mavi dikdörtgenlere bakın. Bu değerlere dikkatlice baktığınızda UNIQUIFIER'ın normalde 4 bayt uzunluğunda oduğunu, diskte ne kadar yer kapladığını ve o anki değerini göreceksiniz. (physical) 0 olduğunda diskte yer kaplamıyor demektir, yani aynı değer birden fazla tekrar etmemiş demektir. Bu nedenle uzun kırmızı dikdörtgende (physical)'ın yanında 0 varken, uzun mavi dikdörtgen ile işaretlediğim 2. kayda ait değer 4. Kırmızı ile işaretlediğim ilk kayda ait UNIQUIFIER'ın değil de mavi ile işaretlediğim ikinci kayda ait UNIQUIFIER'ın diskte 4 bayt yer kapladığını da küçük dikdörtgenlerle çevrelediğim Record Size değerlerinden anlayabilirsiniz. İlk kaydın boyutu 39 bayt iken, ikinci kaydın boyutu 4 baytlık UNIQUIFIER değer nedeniyle 43 bayt.

    Eğer aynı kaydı 3. kere ekleseydim UNIQUIFIER'ın değeri 2 olacaktı ve INT veritipindeki bir alanın alabileceği azami değer olan 2.147.483.647'ye kadar gidecekti. Şayet aynı Cluster Key değeriyle bir kayıt bu kadar tekrar ederse, bir sonraki kaydı oluşturamazsınız ve aşağıdaki hatayı alırsınız:

    "The maximum system-generated unique value for a duplicate group was exceeded for index with partition ID XXX. Dropping and re-creating the index may resolve this; otherwise, use another clustering key."

    Emin olun, böyle bir durumla karşılaşmak istemezsiniz. Çünkü bu durumla karşılaştığınızda bu demektir ki tablonuzda en az 2 küsur milyar kayıt var ve muhtemelen önemli bir tablonuzdur ki bu kadar besleniyordur.

    Bu sorun, hatalı tablo tasarımından kaynaklanır. Kayıtları blok blok silmeniz bir şey ifade etmez, çünkü UNIQUIFIER değeri böyle sıfırlanmaz. UNIQUIFIER değerinin sıfırlanması için tekrar eden kaydın tamamının silinmesi veya blokları sildikten sonra tabloyu hata mesajında da belirtildiği gibi komple yeniden oluşturmanız gerekir. Bu da size ancak bir sonraki hataya kadar zaman kazandırır.

    Firmalar iş hayatlarına başlarken genelde düşük bütçeyle başlar, bu nedenle her konuda uzmanı bünyelerinde barındıramazlar ve böyle tasarımlar da genelde bu gibi nedenlerden kaynaklanır. Çünkü eğer firmanın bünyesinde donanımlı bir veritabanı yöneticisi varsa ve tasarım sırasında kendisine tablo tasarımı danışılsa, o böyle bir tasarımın yaratacağı olası sonuçları önceden öngörebilir.

    Bu sorunu düzeltmek için tablonuzu Heap'e çevirebilir veya Clustered indeksinizi değiştirebilirsiniz. Tabii ki bunlar çok ciddi süreçler, çok iyi hazırlık ve doğru aksiyon gerekiyor. Aksi takdirde, performans sorunu gibi yeni sorunlarla karşılaşabilirsiniz. Belki fırsat olursa ileride de bu konulardan bahsederim.

    Ekrem Önsoy




    10 Mart 2017 Cuma

    Veritabanı sunucunuzun "rutin" durumu gerçekten normal mi?

    Son zamanlarda bir firma ile kısa bir çalışma yaptık. Microsoft SQL Server veritabanı sunucusu sağlık kontrolü çalışması yaparken, sunucunun işlemci kaynaklarının neredeyse sürekli %100 kullanıldığını gözlemledim. Açıkçası ben her ne kadar o anda veritabanı sunucusu sağlık kontrolü çalışmasını erteleyip sorunlara göz atmak için sabırsızlansam da, müşteri bu durum ile yaşamaya alışıktı. Bu nedenle o gün sağlık kontrolü çalışmamıza devam ettik.


    Kontrollerde sunucunun CPU durumu (temsilidir).

    Aslında benimle çalışmak istemelerinin nedenlerinden biri de işlemcinin bu durumuydu, ama bu sorun hakkında çok da kaygılı değillerdi. Sonuç itibariyle günlük operasyonlarını durduran, kesintiye neden olan bir durum yoktu ortada. Sadece zaman zaman ağırlık hissediliyordu ve Deadlock'lar oluşuyordu. Muhtemelen kullanıcılar da zaten sistemin böyle bir performansla çalışmasına alışmışlardı, o yüzden kimse yadırgamıyordu, sonuç itibariyle sistemin "rutin" hali bu idi.

    Şahsen sağlık kontrolü çalışmasınının tamamlanmasını ve ertesi gün yapacağımız performans iyileştirme çalışmasını iple çekiyordum. Ertesi gün performans iyileştirme çalışması için yalnızca birkaç saat ayırabildik. Bu kadarlık bir sürede bile, yaptığımız müdahalelerle işlemci kullanımının (sıçramaları hariç tutarsak) %1'lere indiğini gözlemledim. Zaman zaman işlemci kullanımını %100'e çıkartan bir (ve muhtemel başka zaman aralıklarında çalışan birkaç tane daha) sorgu hala vardı ve en sorunlu görünen sorguyu da tespit edip ilgili yöneticiye bildirmiştim; fakat sorgular uygulamada gömülü olduğundan hemen o gün müdahale edip sorun düzeltilemedi. Birkaç saatte bu kadar iyileştirme sağlanabildiyse çalışmak için 1 ekstra günümüz daha olsa, stabil olarak işlemci kaynaklarını %5'in altına indirebileceğimize eminimdim. Tabii tüm ortamlar için mümkün olan bir sonuç değil bu, bazı çalışmalar daha uzun sürüyor; ama bu müşterim için durum böyleydi.


    Önceden de benzer senaryolara ve konulara değinmiştim. Sorunları CPU ve RAM ekleyerek ancak bir yere kadar öteleyebilirsiniz. Tabii CPU ve RAM eklemek de yetmiyor, bu donanımlar için Microsoft SQL Server lisansı da satın almanız gerekiyor. Örneğin Microsoft SQL Server 2016 Enterprise Edition veritabanı sunucunuzu Per Core modeliyle lisanslamak istediğinizde tek bir CPU Core'u için lisans bedeli 14,256$ ve sunucunuzdaki tüm fiziksel Core'lar için lisans satın almanız gerekiyor.


    Güncelleme (2017-03-13): Per Core lisanslama modelinde çekirdek başına lisanslama yapılıyor ve 2 çekirdek paketiyle satılıyor. Yani 14,256$, 2 Core'luk paket fiyatı. Eğer sunucunuz 8 çekirdekliyse, o zaman 4 tane 2 Core'luk paket almanız gerekiyor. Tabii her lisanslama senaryosu bu kadar basit hesaplanmıyor. Senaryoya göre lisans hesabı çok daha ayrıntılı olabiliyor. Her halükarda bu konuyu yetkili bir satış kanalıyla görüşmenizde fayda var.

    Bu konuda size bazı önerilerim var:


    • Yazılımcıların veritabanı kodlaması konusunda en iyi pratikleri bildiğinden ve uyguladığından emin olun, 
    • Veritabanı sunucunuza kod taşımalarını yapmadan önce taşınacak değişiklikleri iyi ve sistemli bir şekilde test edin, 
    • Testleri küçük boyutlarda, gerçekçi olmayan verilerle yapmayın, 
    • Test ortamınızın hem donanım olarak, hem yapılandırma olarak, hem de veri olarak üretim ortamınıza olabildiğince benzer ve güncel olmasını sağlayın, 
    • Kod taşımalarından önce ve sonra, üretim ortamınızdaki performans değişikliklerini takip edin, kodu taşıyıp hiçbir şey olmamış gibi üretim ortamını kendi haline bırakmayın,
    • Performans sorunlarınızı donanım kaynaklarını arttırarak değil, öncelikle veritabanı yapılandırmanızı ve kodlarınızı iyileştirerek gidermeyi deneyin,
    • Bu değişikliklerin yaratacağı olası performans sorunları takip edilmediğinde ve gerekli müdahaleler zamanında yapılmadığında bir noktada artık sistemin sağlıklı çalışamaz hale geleceğini unutmayın.

    Microsoft SQL Server ile ilgili profesyonel bir desteğe ihtiyacınız varsa beklerim efendim.

    Ekrem Önsoy

    27 Şubat 2017 Pazartesi

    MVP Reconnect Programı Anısı

    1 ay önce LinkedIn'de Microsoft'un MVP Reconnect programını aşağıdaki gibi duyurmuştum.



    Bu program çerçevesinde Microsoft bu ay bu programa dünya çapında kayıt olan ilk 200 kişiye bir hatıra gönderdi. Efendim benim hatıram da bugün geldi, resmini çekip sizlerle de paylaşmak istedim.



    Sevgiler,
    Ekrem Önsoy

    15 Şubat 2017 Çarşamba

    SQL Server 2016'da Database Mail ve .Net 3.5

    Firma ziyaretlerimde sık karşılaştığım sorulardan biri şu:

    "Ekrem, sen birçok firmaya girip çıkıyorsun, birçok ortam görüyorsun, şu anda sektörde en çok kullanılan SQL Server versiyonu nedir?"

    Bu sorunun cevabı an itibariyle şu: "SQL Server 2012".

    Sektör Microsoft'un hızına yetişemiyor. Bu sadece Türkiye'de değil, tüm dünyada böyle.

    Efendim bu yazımın konusuna dönelim. Böyle bir giriş yapmamın nedeni, SQL Server 2016 ile fazla karşılaşmadığımızdan, SQL Server 2016'da Database Mail ile ilginç bir sorun yaşama olasılığınıza dikkat çekmekti. 

    Belki bazılarınızın bildiği gibi SQL Server 2016 kurarken .Net 3.5 kurulumu zorunlu değil. SQL Server 2016 medyanızla doğrudan SQL Server 2016 Instance'ınızı kurabiliyorsunuz. Böyle kurulmuş bir ortamda Database Mail'i yapılandırdım ve test amaçlı bir eposta gönderdim ve beklemeye başladım. İlk dikkatimi çeken şey, Database Mail işleminin bir türlü başlamayışıydı. Task Manager'a baktım, DatabaseMail.exe yok. "sysmail_start_sp" isimli, Database Mail'i başlatmak için kullanılan sistem Stored Procedure'ünü çalıştırdım, ama gene tık yok.

    DatabaseMail.exe'nin bulunduğu yola "C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Binn" gittim ve elle çalıştırmayı denedim ve bir sürpriz ile karşılaştım:

    Genişletmek için resmin üstüne tıklayın
    Bu ekranı görünce, önceden bu konuda bir yazı okuduğum geldi aklıma. SQL Server 2016 kurulumu için .Net 3.5 gerekmese de, SQL Server 2016'da Database Mail kullanmak için .Net 3.5 kurulumu gerekiyordu.

    Genişletmek için resmin üstüne tıklayın
    Ben de kurulumu gerçekleştirdim ve Database Mail'i tetiklemek için aşağıdaki Stored Procedure'ü çalıştırdım:

    EXEC sysmail_start_sp;

    Akabinde Task Manager'ı kontrol ettim ve aşağıdaki gibi DatabaseMail.exe'nin çalıştığını gördüm.


    Genişletmek için resmin üstüne tıklayın

    SQL Server 2016 kurulumlarınızda Database Mail'in bu durumuna dikkat etmeyi unutmayın. İşin kötüsü, herhangi bir yerde bu konuda bir hata veya kayıt da yok. Eğer ben de sorunu çözmek için izlediğim bu yöntemi izlemesem veya çook önceden okuduğum o yazı aklıma gelmese, bu sorun kim bilir ne saç baş yoldururdu.

    Güncelleme: Bu sorun SQL Server 2016 Cumulative Update 2 ile çözülmüş ve Service Pack 1'e de yansıtılmış. Henüz kendim test etmedim, ama bu Connect'e göre Microsoft böyle diyor.

    Ekrem Önsoy


    7 Şubat 2017 Salı

    Microsoft Azure: Query Editor

    30 Ocak 2017 tarihinde Microsoft, Query Editor'ün ilk sürümü hakkında bir duyuru yayınladı.

    Bugün bu yeni özelliği biraz inceleme fırsatım oldu, sizlerle de paylaşmak istedim.

    Peki neden SQL Server Management Studio (SSMS) gibi, diğer benzeri araçlara nazaran çağlar ötesinde olan bir uygulama varken Query Editör gibi bir araca ihtiyaç duyulabilir? Eğer Azure Portal'da çalışıyorken portalı hiç terk etmeden, SSMS gibi harici bir uygulamaya geçiş yapmak zorunda kalmadan, güvenlik duvarı ayarlarıyla uğraşmadan Azure SQL Database veya Azure SQL Data Warehouse veritabanlarınızda komut çalıştırmak istiyorsanız Query Editor pratik bir seçenek olabilir.


    SQL Database veya SQL Data Warehouse içerisinden Query Editor'e ulaşabilirsiniz. SQL Data Warehouse'taki ekran biraz daha farklı, ama Overview'üne giriş yapınca hemen fark edeceksinizdir.

    Eğer Query Editor'ü ilk defa kullanacaksanız, özellik henüz deneme aşamasında olduğu için sizden onay istenecek. Sonrasında ise komutları çalıştırmak için aşağıdaki görselde gösterildiği gibi sisteme giriş yapmanız gerekecek.


    Sisteme giriş ekranı
    Sisteme başarılı bir şekilde giriş yaptıktan sonra SSMS'teki gibi yeni tablo oluşturabilir, SP yazabilirsiniz. Tabii SSMS gibi bir ortam beklemeyin, yani Object Explorer veya diyaloglar yok, adından da anlaşılabileceği gibi sadece kod yazılıyor Query Editor'de. Komutların sadece seçtiğiniz bölümlerini çalıştırabiliyorsunuz, yani kısmi kod çalıştırma özelliği mevcut. Ayrıca "Open query" düğmesine tıklayarak makinenizde varolan Script'lerinizi açıp çalıştırabilirsiniz ve "Save query" düğmesiyle de yeni Script'lerinizi yine kendi makinenizde saklayabilirsiniz.


    Bir komutu çalıştırdığınızda "Authenticated as eonsoy" yazan bölümde saniye işlemeye başlıyor.

    Sorguları çalıştırmak için alışkanlıkla F5'e basmayın sakın, tahmin edeceğiniz gibi tüm sayfa yenileniyor, yazdığınız onca Script'i kaybedebilirsiniz! Maalesef bu versiyonda henüz bu konuda bir önlem yok. Yani F5'e bastığınızda "Henüz kaydedilmemiş veriniz silinecektir" gibi bir uyarı gelmiyor. Microsoft'un ilgili bölümüne bu konuda geribildirimde bulundum, bunu dikkate almamaları imkansız. Bu konuda bir gelişme olursa, yine burada ayrıca paylaşırım.

    Güncelleme: Az önce Microsoft'taki ilgili takımdan cevap geldi, bu sorunun farkındalarmış ve zaten üstünde çalışmaktalarmış.

    Ekrem Önsoy



    31 Ocak 2017 Salı

    Ocak ayında oluşturduğum Microsoft SQL Server hata kayıtları

    Sizlerle Ocak ayında oluşturduğum SQL Server'a ait hata (bug) kayıtlarını paylaşmak istiyorum. Ocak ayı hata kayıtları açısından biraz yoğun geçti.

    Hata 1:
    Aşağıdaki hata kaydı, SQL Server Management Studio'nun yeni versiyonlarında Task List'in hatalı oluşuyla ilgili. Hatalı derken kastettiğim şu, mesela yeni görev oluşturma düğmesi ve görevin türünün belirlendiği aşağı açılır kutu Task List penceresinde görünmüyor.

    https://connect.microsoft.com/SQLServer/feedback/details/3118202/task-list-seems-incomplete


    Hata 2:
    Aşağıdaki diğer hata kaydı da veritabanınızı yerel sunucunuzda oluşturup, dosyalarını Microsoft Azure Blob Storage'da sakladığınızda oluşuyor. Hata, veritabanınız için oluşturduğunuz Database Snapshot'tan dönüş yapmaya çalıştığınızda oluşuyor. Aynı senaryo, veritabanı dosyaları yerel sunucuda konumlandığında oluşmuyor. İpucu: Database Snapshot'tan nasıl geri dönüş yapılacağı da ayrı bir blog konusu.

    https://connect.microsoft.com/SQLServer/feedback/details/3117785/reverting-from-a-database-snapshot-when-database-files-on-azure-blob-storage


    Hata 3:
    Bu hata da Transparent Data Encryption özelliği etkinleştirildiğinde ve kapatıldığında SQL Server 2014 SP2 ve SQL Server 2016 SP1'deki sys.databases ve sys.dm_database_encryption_keys catalog view'lerinin farklı sonuçlar döndürmesiyle ilgili.

    https://connect.microsoft.com/SQLServer/feedback/details/3118734/tempdb-looks-encrypted-but-it-shouldnt-have-been

    Güncelleme 01.02.2017: Ben 13 Ocak tarihinde bu konuda yukarıdaki hata kaydını açtıktan sonra Microsoft'tan Bob Ward yine bu konuda 27 Ocak tarihinde bu konuyu incelemiş. Merak edenler yazıya buradan ulaşabilir.

    Eğer açtığım hata kayıtlarına oy vermek isterseniz, bir Microsoft hesabı açmanız yeterli.


    Ekrem Önsoy

    23 Ocak 2017 Pazartesi

    Başvuru kaynağı: SQL Server bağlantı sorunları ve açıklamaları

    Yazının ilk yayınlandığı tarih: 23 Ocak 2017
    Son güncellenme tarihi: 2 Şubat 2017, v1.1
    Yazının konusu: SQL Server bağlantı sorunları ve açıklamaları
    Yazının kapsamı: Bu dokümanın kapsamı Database Engine servisiyle sınırlıdır, versiyon bağımsızdır ve Microsoft Azure bağlantı sorunlarını da kapsar.
    Yazar: Ekrem Önsoy


    SQL Server Bağlantı Sorunları ve Açıklamaları 


    Microsoft SQL Server Forumlarında ve daha birçok farklı platformda bazı sorular tekrar tekrar soruluyor. Böyle bir yazı yazarak sık soru gelen konu başlıklarından biri olan SQL Server'a bağlantı ile ilgili sorunların nasıl çözüleceğine dair bilgi ve tecrübeleri derli toplu bir doküman ile paylaşmak istedim. SQL Server'ın farklı versiyonlarındaki değişiklikler, çeşitli güncellemeler ve yeni sorunlar için bu yazıyı zaman zaman güncelleyeceğim. Bu sayede bu yazımın SQL Server'a bağlantı sorunlarının çözümü için farklı platformlarda genel bir referans kaynağı olmasını hedefliyorum.

    SQL Server'a bağlanamamakla ilgili birçok sorun senaryosu ve hata mesajı mevcut. Birçok farklı mesaj, farklı bir sorunun sonucunda oluşuyor. Bu nedenle SQL Server'a bağlanma sorununu tek bir senaryoyla veya hata mesajıyla değil, farklı senaryo ve hata mesajlarına göre ayrı ayrı açıklayacağım.

    Hataların açıklamalarına ve sorunların çözümüne geçmeden önce, bu süreçte kullanılacak bazı temel kavram ve araçlardan bahsetmek istiyorum. Bu kavram ve araçları sorun çözümlerinde başvuru kaynağı olarak göstereceğim ve bunu yaparken madde numaralarını da kullanacağım.

    Notlar: 

    • Zaman zaman bazı terimleri İngilizce kullanacağım, çünkü kullanacağınız uygulamalarda karşınıza çıkacak olan ilgili terim bu dilde olacak, bir de çevirme ve tahmin işleriyle boğuşmak istemezsiniz diye düşünüyorum.
    • Hata mesajları şu anda sadece İngilizce, zamanla Türkçelerine ulaştıkça ilgili senaryoya hata mesajının Türkçesini de ekleyeceğim.
    • Güncelleme 03.02.2017: Bu konuda 27 Ocak tarihinde Microsoft tarafından da kapsamlı bir makale (İngilizce) yayınlandı. Bu makaleye de buradan ulaşabilirsiniz.


    1.KAVRAMLAR

    1.1 Instance / Database Engine

    Bu yazıda sık sık "Instance" ve "Database Engine" kavramları kullanılacaktır. Bir Database Engine Instance'ı, bir işletim sistemi altında çalışan "sqlservr.exe" uygulamasının bir kopyası demektir. Her Database Engine Instance'ı birkaç sistem veritabanını, bir veya daha fazla kullanıcı veritabanını yönetir. Her sunucuda Database Engine servisinin birden fazla Instance'ı, yani kopyası olabilir. Uygulamalar veritabanlarında işlem yapabilmek için ilgili Database Engine Instance'ına bağlanırlar. 

    Database Engine servisi 1.2 numaralı maddedeki ekran görüntülerinde de gösterilen ve etrafı kırmızı ile çizilen servistir. Bundan hariç olarak aynı veya farklı Instance adıyla Analysis Services, Reporting Services, Integration Services ve benzeri başka servisler kurulabilir. SQL Server 2000'den itibaren bir işletim sistemine birden fazla SQL Server Instance'ı kurulabilir.

    Instance tipleri ikiye ayrılır ve farklarının ayrıntıları aşağıda 1.2 numaralı maddede açıklanmıştır.

    1.2.Default Instance / Named Instance

    SQL Server ürününü kurulum esnasında iki şekilde, Default Instance veya Named Instance olarak kurabilirsiniz. Her bir sunucuda, yani işletim sistemi düzeyinde sadece 1 tane Default Instance olabilir. Eğer aynı sunucuya birden fazla SQL Server kurulumu yapılacaksa ve zaten bir Default Instance kurulu ise diğer Instance'ların Named Instance olması gerekir.

    Bir SQL Server Instance'ı kurulduktan sonra sunucu adı değiştirilebilir, fakat Instance adı değiştirilemez. Bir kurulumu Default Instance olarak yaptıysanız bunu Named Instance'a çeviremezsiniz veya tam tersini yapamazsınız. Instance adını değiştirmek için kurduğunuz Instance'ı silmeniz ve tekrar kurmanız gerekmektedir.

    Default ve Named Instance tipleri arasındaki temel farklar şunlardır:
    • Default Instance varsayılan olarak Static Port kullanır, yani kullandığı port numarası sabittir, birisi elle değiştirmediği sürece değişmez.
    • Default Instance'ın varsayılan port numarası 1433'tür.
    • Default Instance'ın servis adı MSSQLSERVER'dır. SQL Server Configuration Manager'da (2.1) aşağıdaki gibi görünür:
    • Bir Default Instance'ın SQL Server Configuration Manager'daki (2.1) görünümü.
      Not: Bu ekran görüntüsünde Default Instance olan bir Database Engine servisi çalışır (Running) durumdadır.
    • Bir Default Instance'a bağlanmak için aşağıdakileri "sunucu adı" olarak kullanabilirsiniz:
      • Bilgisayar adı,
      • Bilgisayarın yerel IP'si,
      • localhost (eğer Instance'a bağlantı, kurulumla aynı sunucu üstünden yapılacaksa),
      • 127.0.0.1 (eğer Instance'a bağlantı, kurulumla aynı sunucu üstünden yapılacaksa).
    • Named Instance varsayılan olarak Dynamic Port, yani servis başlangıcında müsait olan herhangi bir port numarasını kullanır.
    • Named Instance'lar her yeniden başlatıldıklarında port numaraları değişir.
    • Bir Named Instance'ın adının biçimi şöyledir: Instance adı>. 
    SQL Server Configuration Manager'da (2.1) aşağıdaki gibi görünür:
    "SQL2014_DEV" adındaki bir Named Instance'ın SQL Server Configuration Manager'daki (2.1) görünümü.
    Not: Bu ekran görüntüsündeki SQL2014_DEV isimli Instance'a ait Database Engine servisi durmuş (Stopped) durumdadır.

    • Named Instance'lara bağlanmak için aşağıdakileri "sunucu adı" olarak kullanabilirsiniz.
      • Bilgisayar adı ve Instance adını, örnek: CONTOSO\SQL01. Bu örnekte "CONTOSO" bilgisayarın/sunucunun adı, "SQL01" de Instance'ın adı.
      • Bilgisayarın/sunucunun IP'si + Instance adı, örnek: 192.168.1.205\SQL01.
    Güncelleme 02.02.2017: SQL Server'a bağlanmak için kullanılabilecek birçok yönteme dair örnek kaynağa (İngilizce) buradan ulaşabilirsiniz.

    1.3.TCP/IP Protokolü - Port

    TCP/IP protokolü etkin olan her SQL Server Instance'ı ayrı bir port numarası kullanır. Bu port SQL Server Instance'ı ile istemci arasındaki veri alışverişi için kullanılır. İster Default Instance ister Named Instance olsun, port numaraları kurulum sonrasında SQL Server Configuration Manager (2.1) kullanılarak değiştirilebilir. Bu değişiklik SQL Server Database Engine servisinin yeniden başlatılmasını gerektirir, aksi takdirde değişiklik devreye girmez.

    SQL Server Express Edition kurulumlarında varsayılan olarak TCP/IP protokolü devre dışı bırakılır.

    Herhangi bir Edition'dan olan SQL Server Instance'ı için TCP/IP protokolünü etkinleştirmek isterseniz, ki uzaktan bağlanmak istediğiniz bir SQL Server Instance'ı için TCP/IP veya Named Pipe protokolü etkin olmalıdır, aşağıda gösterildiği gibi SQL Server Configuration Manager (2.1)'ı kullanabilirsiniz.

    SQL Server Configuration Manager (2.1) ile TCP/IP protokolünü etkinleştirme. Değişikliğin devreye girebilmesi için Database Engine servisinin yeniden başlatılması gerekmektedir.

    Protokoller hakkında daha fazla bilgi için SQL Server 2005: Bağlantı Protokolleri başlıklı yazımı okuyabilirsiniz. Şu anda kullandığınız SQL Server'ın versiyonu muhtemelen daha yeni olacaktır, ama merak etmeyin protokoller hala aynı.

    İlgili Database Engine servisinin o anda hangi portu kullandığını öğrenmek isterseniz Error Log (2.3) dosyasını veya Windows Application Event Log (2.4)'u kullanabilirsiniz.

    • Error Log (2.3):
    • Database Engine Instance'ının Error Log dosyasının içeriğinden port numarasını bulma.


    2.ARAÇLAR

    2.1.SQL Server Configuration Manager 

    Bu araç, SQL Server kurulumuyla birlikte gelir. SQL Server 2005'ten beri vardır. Bu araç ile daha birçok işlemin yanısıra özetle SQL Server servislerinin durumları gözlemlenebilir ve değiştirilebilir, Database Engine servisinin başlangıç parametreleri değiştirilebilir, servis kullanıcı ayrıntıları değiştirilebilir, bağlantı protokolleri (TCP/IP, port gibi) ayarlanabilir ve takma isimler oluşturulabilir.

    2.2.SQL Server Browser Service

    Bir uygulamanın Connection String'inde port numarası belirtilebilse de, eğer bir SQL Server Instance'ı Dynamic Port kullanmak üzere ayarlanmışsa SQL Server Database Engine servisi yeniden başlatıldığında port numarası değişecektir. Eğer Browser Service çalışıyorsa, başlatıldığında UDP port 1434'ü sahiplenir, kayıt defterindeki (Registry) ilgili anahtarları okur ve sunucu üstündeki tüm SQL Server Instance'larını kullandıkları portlarla birlikte belirler. Bir sunucuda bir veya daha fazla ağ kartı varsa SQL Server Browser servisi SQL Server için karşılaştığı ilk etkinleştirilen portu seçer.

    Bir SQL Server istemcisi (mesela bir uygulama) SQL Server kaynaklarına erişmek istediğinde, istemci ağ kütüphanesi 1434 portunu kullanarak sunucuya mesaj yollar. SQL Server Browser servisi ulaşılmak istenen Instance'ın TCP/IP portuyla karşılık verir. İstemci uygulamasındaki ağ kütüphanesi ulaşılmak istenen SQL Server Instance'ının portunu kullanarak sunucuya talebini göndermek suretiyle bağlantıyı tamamlar.

    2.3.SQL Server Error Log

    SQL Server Database Engine servisinin kendi Error Log dosyası vardır. Bunu bu şekilde belirtmemin nedeni, SQL Server Agent servisinin de kendi Error Log dosyasının olmasıdır, bunlar birbirine karıştırılmamalı. Bu yazı kapsamında ilgili olanı SQL Server Database Engine servisinin Error Log dosyasıdır. Bu dosyanın konumu, yaptığınız kuruluma göre değişir. Aşağıda belirtilen yol biçimi SQL Server Instance'ınızın adına göre (Default Instance mı, Named Instance mı olduğuna göre) ve SQL Server'ın versiyonuna göre değişir.

    Error Log dosyasının yolunun biçimi şöyledir:
    Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG\ERRORLOG

    Her SQL Server Database Engine servisinin yeniden başlatılmasıyla Error Log dosyası yenilenir. Varsayılan olarak geriye dönük 6 tane Error Log dosyası tutulur. O anki en güncel Error Log dosyası, uzantısı olmayan dosyadır, sadece ERRORLOG adıyla oluşturulur. Bundan sonraki en güncel dosyanın adı ERRORLOG.1, sonraki ERRORLOG.2 diye gider. Error Log dosyaları düz metin dosyalarıdır ve mesela Notepad ile birlikte açılabilir.

    2.4.Event Viewer (Olay günlüğü) 

    Windows işletim sisteminde System ve Application Event Log'ları (daha başkaları da var, ama bu yazı kapsamında ilgili dosyalar bunlar) vardır. Kural olarak şu unutulmamalıdır, SQL Server Error Log'a işlenen tüm hatalar Windows Application Event Log'una da işlenir. Bazı hatalar vardır ki, bunlar System Event Log'a işlenir. Bu nedenle bir hata soruşturması yürütürken iki log dosyasına da bakmak iyi bir yöntemdir.

    2.5Ping komutu (Komut İstemcisi)

    Ping komutu, TCP/IP protokolünü kullanan diğer sunucuya Internet Control Message Protocol (ICMP) Echo Request mesajları göndererek IP seviyesinde erişim olup olmadığını kontrol eder.

    Hem karşı bilgisayar adına, hem de IP'sine karşı Ping komutunu çalıştırabilirsiniz. Eğer Ping komutu karşı bilgisayarın IP'si için başarılı sonuç döndürüyorsa, fakat bilgisayar adı için başarısız sonuç döndürüyorsa, o zaman isim çözme ile ilgili sorun yaşıyor olabilirsiniz. 

    Ping komutu Komut İstemcisi'den (Command Prompt) aşağıdaki biçimde çalıştırılır:

    C:\>ping

    veya

    C:\>ping

    Örnek:

    C:\>ping SQL01.contoso.com

    veya

    C:\>ping 192.168.1.66

    2.6Telnet (Komut İstemcisi)

    Telnet komutunu, uzaktaki bir sunucudaki bir portun açık olup olmadığını kontrol etmek için kullanabilirsiniz.

    Bazı sistemlerde Telnet istemcisi kurulu olmayabilir, böyle durumlarda önce Telnet istemcisini kurmanız gerekir.

    Telnet komutu Komut İstemcisi'den (Command Prompt) aşağıdaki biçimde çalıştırılır:

    C:\>telnet

    veya

    C:\>telnet

    Örnek:

    C:\>telnet SQL01.contoso.com  

    veya

    C:\>telnet 192.168.1.66  


    3.SORUN SENARYOLARI

    3.1.Senaryo

    Alınan hata mesajı:

    "A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Shared Memory Provider, error: 40 - Could not open a connection to SQL Server) (Microsoft SQL Server, Error: 2)

    The system cannot find the file specified"

    veya

    "A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) (Microsoft SQL Server, Error: 67)

    The network name cannot be found"

    Açıklama:

    İlk hata, yerel bir SQL Server Instance'ına bağlanmaya çalıştığınızda, ikinci mesaj da uzaktaki bir SQL Server Instance'ına bağlanmaya çalıştığınızda oluşur.

    Eğer yukarıdaki gibi hata mesajları alıyorsanız ve bağlanmaya çalıştığınız sunucu uzaktaysa ilk yapmanız Ping (2.5) komutuyla sunucuya ulaşıp ulaşamadığınızı kontrol etmektir. Çünkü bırakın SQL Server servisini, sunucunun kendisi de kapalı olabilir. Bununla birlikte, bazı sunucular çalışıyor olsa da Ping komutuna cevap vermeyecek şekilde ayarlanmış olabilirler, bu bilgiyi de bir kenarda tutmakta fayda var.

    Eğer sunucunun açık olduğundan eminseniz ve yukarıdaki gibi hata mesajları alıyorsanız SQL Server Configuration Manager (2.1)'ı açın ve SQL Server Database Engine servisinizin çalışıp çalışmadığını kontrol edin.

    Database Engine servisinizin çalışır durumda (Status = Running) olduğundan emin olun.

    Eğer SQL Server Configuration Manager (2.1)'ı açtığınızda "SQL Server Services" penceresinde hiçbir servis adı görmüyorsanız ya SQL Server Configuration Manager (2.1)'ın başka bir versiyonuyla SQL Server Database Engine'in farklı bir versiyonuna bakmaya çalışıyorsunuz ya da bu sunucuya henüz bir SQL Server Instance'ı kurulmamış demektir.

    SQL Server Configuration Manager (2.1)

    3.2.Senaryo

    Alınan hata mesajı:

    "A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified) (Microsoft SQL Server, Error: -1)"

    Açıklama:

    Bu hata mesajı 3.2'de anlatılan hata mesajına benzerdir, ama sizi yanıltmasın, hata mesajının sonundaki parantezlerin içerisindeki mesajlar farklıdır.

    Eğer böyle bir hata mesajı alıyorsanız bağlanmaya çalıştığınız SQL Server Instance adını yanlış yazıyorsunuz demektir. Örneğin eğer varolan Instance adı "CONTOSO\SQL01" ise ve ben Connection String'ime veya SQL Server Management Studio'daki "Server name"e "CONTOSO\SQL2" yazarsam o zaman bu hata mesajını alırım.

    Kullandığınız Instance adının doğruluğunu teyit edin. Bunun için SQL Server Configuration Manager (2.1)'ı kullanabilirsiniz.

    3.3.Senaryo

    Alınan hata mesajı:

    "A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 0 - The remote computer refused the network connection.) (Microsoft SQL Server, Error: 1225)"

    Açıklama:

    Bu sorun da ilk bakışta önceki sorunlara benzer, fakat yine hata mesajının sonundaki parantez içerisindeki ayrıntılarla farklılaşır.

    Eğer böyle bir hata mesajıyla karşılaşıyorsanız ilk yapmanız gereken kullandığınız veya kullanmanız gereken ama kullanmadığınız port (1.2) numarasından emin olmaktır. Misal Database Engine Instance'ınız 1533 numaralı portu kullanıyorsa ve Browser Service (2.2) çalışmıyorsa ve Connection String'inizde veya SQL Server Management Studio'daki "Server name"de bunu belirtmiyorsanız bu hata ile karşılaşırsınız.

    Olması gereken Connection String biçimi (Server kısmına odaklanın lütfen)

    "Server=, ; Database=; Trusted_Connection=True;"

    Örnek:
    "Server=CONTOSO\SQL01, 1533; Database=Veritabanim; Trusted_Connection=True;"

    Port'un açık olup olmadığını Telnet (2.6) komutuyla da kontrol edebilirsiniz.

    3.4.Senaryo

    Alınan hata mesajı:

    "A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)"

    Açıklama:

    Diyelim ki uzaktaki bir SQL Server Instance'ına SQL Server Management Studio veya başka bir uygulama ile bağlantı kurdunuz ve işlemlerinizi gerçekleştiriyorsunuz. Eğer bağlantınız aşağıdaki gibi nedenlerden ötürü sonlandırılırsa, bu hata ile karşılaşırsınız:

    • Oturumunuz SQL Server Instance'ında KILL komutu ile sonlandırılırsa,
    • Ağ bağlantınız veya uzaktaki SQL Server Instance'ının ağ bağlantısı koptuysa,
    • Oturumunuz SQL Server Database Engine tarafından sunucudaki yoğunluk ve kaynak yetmezliği nedeniyle sonlandırılırsa.

    Böyle bir sorun ile karşılaştığınızda hizmet almaya çalıştığınız SQL Server'ın yöneticileriyle irtibat kurup oturumunuzun kim tarafından ve neden sonlandırıldığını sorgulayabilir veya ağ bağlantılarınızı kontrol edebilirsiniz.

    3.5.Senaryo

    Alınan hata mesajı:

    "A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) (Microsoft SQL Server, Error: 5)

    Access is denied"

    Açıklama:

    Şayet bu hata mesajıyla karşılaştıysanız, bağlanmaya çalıştığınız uzaktaki SQL Server Instance'ının TCP/IP protokolü devre dışıdır. Bu protokolü etkinleştirme hakkında daha fazla bilgi için lütfen 1.2TCP/IP Protokolü - Port başlıklı maddeye başvurun.

    Port'un açık olup olmadığını Telnet (2.6) komutuyla da kontrol edebilirsiniz.

    3.6.Senaryo

    Alınan hata mesajı:

    A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The specified network name is no longer available.)

    Açıklama:

    Böyle bir sorun yaşıyorsanız muhtemelen sunucuyla bağlantı kurmuş ve işlem yapıyorsunuzdur, fakat bu sürecin bir aşamasında bu hata ile karşılaşmışsınızdır.

    Şahsen ben bu hata ile bugüne kadar hep ağ bağlantısı kopmalarında karşılaştım. Örneğin farklı ağlardaki iki sunucu arasında Log Shipping ile dosya kopyalama işlemi yapıyorsunuz diyelim, eğer işlem sırasında sunucular arasındaki ağ bağlantısı koparsa böyle bir hata ile karşılaşabilirsiniz.

    Eğer sunucularınızdan birisi buluttaysa veya ayrı bir bölgedeyse, örneğin bir sunucu Hollanda'da, diğeri Amerika'da gibi ve uygulamalarınızın bu mantıkla hata almadan çalışmaya devam ediyorsa ve uygulamayı siz geliştiriyorsanız o zaman uygulamanızı bağlantı koptuğunda kaldığı yerden devam edecek bir mantıkla yazmanız gerekiyor. Bağlantı gittiğinde ve bu hatayı aldığınızda bunu handle edebilmeniz gerekiyor. Çünkü böyle yapılarda bağlantı kopma olasılıkları çeşitli nedenlerle (bakım nedeniyle, ağdaki gel gitler nedeniyle gibi) kaçınılmazdır ve tekrarlar. Bu sorunla nasıl yaşayacağınızı öğrenmeniz gerekiyor.

    Şayet yukarıdaki paragrafta bahsettiğim gibi farklı bölgeleri barındıran bir yapı yoksa ve birbirine yakın veya dahili ağlarsa bunlar, o zaman (varsa) ağ uzmanlarınızla bu konuyu konuşmalısınız ve ağınızın istikrarlı çalışmadığını kendilerine bildirmelisiniz. Muhtemelen ilk etapta itiraz edebilirler, ama pes etmeyin, bu sorun ağ bağlantı kopmasıyla ilgili bir sorundur.

    3.7.Senaryo

    Alınan hata mesajı:

    Login failed. The login is from an untrusted domain and cannot be used with Windows authentication. (Microsoft SQL Server, Error: 18452)

    Açıklama:

    Uzaktaki SQL Server Instance'ınıza bağlanırken böyle bir hata alabilirsiniz. Bu bir bağlantı hatası değil, kullanıcı yetkilendirme hatasıdır. Hata mesajında da belirtildiği gibi, bağlantı için kullandığınız Windows Login'i güvenli bulunmamaktadır.

    Bu sorun, SQL Server'ın bulunduğu karşı Domain ile yerel bilgisayarınızdaki Domain veya Windows ortamı ile bir güven ilişkisi bulunmadığında oluşur. Bir güven ilişkisi olmadığı için, karşı tarafta bulunan SQL Server Instance'ı, yerel bilgisayarınızdan karşı SQL Server'a giriş yapmak için kullanmaya çalıştığınız kullanıcıyı tanımayacaktır.

    Bu sorunu çözmek için ya bağlantı için SQL Login kullanmalısınız ya da Domain'ler arasında güven ilişkisini oluşturmalısınız.

    3.8.Senaryo

    Alınan hata mesajı:

    Login failed for user 'test'. (Microsoft SQL Server, Error: 18456)

    Açıklama:

    SQL Server Instance'ınıza bağlanırken böyle bir hata alabilirsiniz. Bu bir bağlantı hatası değil, kullanıcı yetkilendirme hatasıdır. Bu hata mesajı güvenlik nedeniyle çok yüzeysel olarak oluşturulmaktadır. Kastettiğim şu, bu hata mesajından bu şekilde yalnızca "test" isimli kullanıcının SQL Server Instance'ına bağlanırken hata aldığı sonucuna varabiliriz. Fakat bunun binbir çeşit türlü nedeni olabilir.

    Bu farklı nedenleri incelemek için 2.3 ve 2.4 numaralı maddelerde bahsedilen Log dosyaları incelenmelidir. Log dosyalarında bu hatanın hemen altında hataya dair ayrıntı bulunacaktır. Örneğin Login'in şifresinin yanlış girilmesi, Login'in Disabled rudumda oluşu gibi.

    SON

    Kaynaklar:

    Ping, https://technet.microsoft.com/en-us/library/bb490968.aspx
    Telnet, https://technet.microsoft.com/en-us/library/bb491013.aspx