20 Aralık 2014 Cumartesi

Cumulative update package 5 for SQL Server 2014


Microsoft SQL Server 2014 için Cumulative Update Paketi  yayınladı.(build number: 12.0.2456.0)  Paket aşağıdaki linkde bulunan düzeltmeleri içermektedir.


SQL Server 2014 kullanıcıları Update paketini Live ortamda kullanmadan önce test ortamında uygulamaları önerilmektedir.
En son güncelleme daha önce yayınlanmış tüm güncellemeleri  ve tüm düzeltmeleri içermektedir.

Bu update aşağıda bulunan SQL Server sürümlerini kapmaktadır.
  • Microsoft SQL Server 2014 Enterprise
  • Microsoft SQL Server 2014 Developer
  • Microsoft SQL Server 2014 Standard
  • Microsoft SQL Server 2014 Express
  • Microsoft SQL Server 2014 Web
  • SQL Server 2014 Reporting Services
  • Microsoft SQL Server 2014 Business Intelligence
Update işlemi uygulandıktan sonra bilgisayar restart edilmelidir. SQL Serverımızın versiyon bilgisini aşağıdaki T-SQL kodu kullanarak görebiliriz.

SELECT @@Version as ProductName, 
SERVERPROPERTY('ServerName') AS 'ServerName', 
SERVERPROPERTY('Edition') AS 'Edition', 
SERVERPROPERTY('ProductVersion') AS 'ProductVersion' 
Always-on, Replication, Failover Cluster ve Mirroring kullanıcılarının yukarıda bulunan indirme linkindeki açıklamaları okuyarak uygulamaları önerilir.

18 Aralık 2014 Perşembe

SQL Saturday 359 -5(Monitoring and Assessing SQL Server with extended events)


5.seminer ise Batuhan YILDIZ'ın yaptığı Extended Event semineriydi.  Bugüne kadar SQL Profiler kullandığım için extended eventları hiç kullanmamıştım ancak Microsoft bir sonraki versiyonda Profilerı kaldıracağı için Extended Event konusuna bundan böyle daha sık eğilmemiz gerekecek gibi gözüküyor.

Extended Event ilk olarak 2008 versiyonu ile karşımıza çıkmış ancak o zaman bir arayüze sahip olmadığı için DBAler için pek tercih edilmemiş. 2012 versiyonu ile bir arayüze kavuşmuş.

Extended Events ile SQL Server sorgularını takip edebilir, performans analizi yapabilir, deadlock problemlerini çözebilir ve T-SQL statement’larını debug edebilirsiniz.


Extentet event bir wizarda sahip. Wizard kullanarak istediğimiz session oluşturup kullanabiliriz. Bu wizarda yardımı ile capture edeceğimiz veriyi seçerek analiz imkanını çok kolay bir şekilde yapabiliyoruz. Bu konu ile ilgili ileriki günlerde derinlemesine bir makale yazmak istiyorum

SQL Saturday 359 -4 (Write Quick, Readable and High Performance Queries Using Window Function)


4.seminer ise kitaplarından tandığımız İsmail ADAR hocanın semineriydi. Window functionları konusunda örnekler yapıldı.

Bu konuda bütün fonskiyonları yazmayacağım sadece Ranking Fonksiyonları yani derecelendirme fonksiyonları üzerine bir şeyler yazmak istiyorum.

Ranking fonksiyonları bir veri kümesi üzerinde kriter belirterek veri kümesinin gruplara bölünmesini sağlayan ve her gruba geçici bir numara veren fonksiyonlardır. SQL Server ile kullanılmaya başlayan ranking fonksiyonlarını şu şekilde listeleyebiliriz.

ROW_NUMBER:Veri kümesindeki gruplanmış her değer için numerik ve artan bir değer üretir. Bu değer istenirse tüm veri kümesi bir parça olarak alınabilir yada veriler belli kolona göre gruplanabilir.

SELECT FirstName,LastName ROW_NUMBER() OVER (ORDER BY SalesYTD
DESC
) AS 'Row Number',
SalesYTD,JobTitle

FROM
Sales.vSalesPerson
SELECT FirstName,LastName ROW_NUMBER() OVER (PARTITION BY JobTitle
ORDER
BY SalesYTD
DESC
) AS 'Row Number',
SalesYTD,JobTitle

FROM
Sales.vSalesPerson


RANK:fonksiyonuda ROW_NUMBER fonksiyonu gibi bir veri kumesi icinde
gruplama yaparak her bir veriyi belirtilen kritere gore siralama yaparak
numaralandirir. ROW_NUMBER fonksiyonundan farki ise siralama yaparken ayni degere sahip olan
satirlara ayni sira numarasi vermesidir. RANK fonksiyonunda siralama icin kullandigimiz alandaki ayni
degerler icin ayni sira numarasi kullanilir.

select i.ProductID,p.Name,i.LocationID,i.Quantity,
RANK
() OVER (PARTITION BY i.LocationID ORDER BY i.Quantity DESC) AS
'
RANK'
FROM

Production.ProductInventory i
INNER JOIN Production.Product p
ON
i.ProductID=p.ProductID


DENSE_RANK fonksiyonu RANK fonksiyonundan farklı olarak aynı sıra numarası verilse bile bir sonraki gelen kayda sıra numarası verilirken araya tekrar eden kayıt sayısı kadar boşluk ekleyen fonksiyondur.

select i.ProductID,p.Name,i.LocationID,i.Quantity,
DENSE_RANK
() OVER (PARTITION BY i.LocationID ORDER BY i.Quantity DESC) AS
'
RANK'
FROM

Production.ProductInventory i
INNER JOIN Production.Product p
ON
i.ProductID=p.ProductID where
i.ProductID in(
436,461,443)

 
NTILE fonksiyonu diğer ranking  yani derecelendirme fonksiyonlarından farklı olarak veri kümesini gruplarken her bir grup içinde en fazla kayıt olacağı bilgisini dışarıdan parametre olarak almaktadır.

SELECT p.FirstName, p.LastName,s.SalesYTD,a.PostalCode,
NTILE
(5) OVER(ORDER BY SalesYTD DESC) AS 'Ntile'
FROM
Sales.SalesPerson s
INNER
JOIN
Person.Person p
ON s.BusinessEntityID=P.BusinessEntityID
INNER
JOIN Person.Address a on a.AddressID=p.BusinessEntityID

SQL Saturday 359 -3( How Latch Contention Affects the Performance? )


3. Katıldığım seminer Turgay SAHTİYAN hocanın How Latch Contention Affects the Performance? adlı semineriydi. 

Bu seminerde öncelikle olarak latch nedir ve lock nedir ve aralarındaki farklar konuşuldu. 

Latch nedir tanımına bakacak olursak birden fazla process memoryde bulunan bir page'i değiştirmek isterse SQL Server ilk isteyen process için latch koyar.  Diğer processlerinde işlem yapmasını engeller. Aynı anda bir fazla process page üzerinde değişiklik yapabilseydi page tutarlılığı bozulurdu. Bu koyulan Latch'e PageLatch_EX adı verilir.

Aynı işlem bir page'in diskten memorye getirilmesi sırasındada olur. Bunada PageIOLatch_EX adı verilir.

DB serverda birden fazla Cpu varsa aynı objeye paralel olarak erişen process sayısı artacaktır. Aynı objeye birden fazla process erişmek isteyebileceğinden dolayı latch yaşanması kaçınılmazdır.

Latchler ile locklar birbirine oldukça benzerler ancak aralarında bir fark vardır. SQL Server lock'ı transaction tamamlanana kadar koyarken latch'i fiziksel operasyon bitene koyar.  İlgili page'de fiziksel işlem bitince latch kalkarken lock transaction tamamlanıncaya kadar durur.

Latchler üzerinde kullanıcılar hiçbir işlem yapamazken locklar üzerinde transaction level ile oynayarak değişiklikler yapabilirler.


Latch analizi için  Sys.dm_exec_wait_stats ve sys.dm_exec_latch_stats DMVleri kullanılırken  lock analizi için ise sys.dm_tran_locks ve sys.dm_exec_sessions DMVleri kullanılır.

Ayrıca Latch Contentiondan Hash partitioning yöntemi üzerine konuşuldu. Bir bankada DBA olarak çalışıyoruz. 1400 tane bankamatik şubemiz var. Her yapılan işlem bir identity kolonda veya bir sequence nesnesinden bir numara alarak ID kolonuna üzerine veri olarak işlenmektedir. Bu kolon clustered indexdir.

Her yapılan işlemi her zaman son page üzerine yapılacağı için latch contention'dan kaçmak nerdeyse imkansızdır.
Bundan kaçmak için Clustered Index'te değişiklik yaparak BankamatikID ekleyebiliriz. Ancak bu durumda  leading kolon olarak non-sequential bir kolon seçildiği için Page Split ve index fragmentation ile karşılaşılacağız.

Burada çözüm tablodaki bir kolon üzerinden oluşturulan bir hash value üzerine partitioning yapmaktır. Bu şekilde gelen insert’ler sıralı olarak farklı partition’lara dağılacak ve hep aynı page’e erişim olmayacağından dolayı contention çözümlenmiş olacaktır.


SQL Saturday 359 -2( How to understand if the storage is a problem on the database server)


İkinci seminerde Türkiye'de SQL Serverın en büyük gurularından birisi olan Yiğit AKTAN hocanın Troubleshooting: How to understand if the storage is a problem on the database server? Adlı seminerine katıldım. Şimdiye kadar teknik açıdan olsun sürükleyicilik açısından olsun  en iyi seminerlerden birisiydi.
 

Seminerde Sql Serverda yaşanabilecek IO problemleri ve bunların çözüm yöntemleri üzerine konuşuldu.  Bir işlem bir kayıt üzerinde değişlik yapacağı zaman ilk olarak kaydın olduğu page'i bulmak için memorye bakar. Burda yoksa  diskten okuyarak memory'e alır. SQL Server kayıtları direk diskten okumaz. Öncelikle memory'e alır. Burdan okur. Okuma devam ederken bir başka işlem bu page erişmek isterse ilk işlemin okuma işlemini bitirmesini bekler. Buna PageIOLatch_EX denir.  Aynı anda iki işlem aynı page'e erişip memory'e alamaz.

Bu PageIOLatch_EX problemlerinin nasıl tespit edileceği ve nasıl çözümler bulunacağı üzerine çok güzel bir seminer oldu.

I/O problemlerinde DBAler öncelikli olarak çözümü storage yöneticileri ile konuşarak bulmak isterler. Ancak genellikle çözüm bulunamaz. Çünkü storage yöneticileri hatalarını genellikle kabul etmezler. Bu gibi durumlarda problemin ne olduğu ve çözümün ne olacağı konusunda demo yapıldı.

Çözüm Örnekleri
  1. IO hızınızı artırmak ve hızı yüksek bir altyapıya sistemimizi taşımak. Disk yapımızı SSD ile değiştirmek.(Bu ilk etapta pek kolay gözükmüyor.)
  2. Eksik Indexleri yeniden oluşturmak
  3. Kullanılmayan Indexleri silmek
  4. İstatiktikleri Update Etmek
  5. MDF ve LDF disklerini ayrı diskler üzerine koymak ve TempDB veritabanını hızlı disklere taşımak.


Seminerde  sp_WhoIsActive  stored prosedürü üzerine bilgi verildi. Bu prosedür  Adam Machanic tarafından yazılmış. Sistemde o anda çalışan activiteleri görüntülüyor.

SQL Saturday 359 -1(SQL Server 2014: HA and DR Solutions)


Bu yazı dizimde 06.12.2014 tarihinde gittiğim SQL Saturday gününde katıldığım seminerlerden bahsetmek istiyorum. SQL Saturday  konusunda kısaca bilgi verecek olursak SQL Pass tarafından her Cumartesi dünyanın bir şehrinde düzenlenen bu etkinlikde  SQL Server konusunda hem lokal hemde uluslararası konusunda derin deneyime sahip uzmanlar eğitimler veriyorlar.

Türkiye'de 4.sü düzenlenen bu eğitim Microsoft Türkiye ofisinde yapıldı. 5 ayrı salonda toplam  30 'a yakın seminerden oluşmakta. Bende bu  etkinliği 4 senedir katılıyorum.

4 senedir gittiğim bu etkinlikde her yıla oranla katılımcı sayısı arttığını görmek çok sevindirici. Ancak Microsoft'un verdiği destek konusunda baya sıkıntılı. Kötü bir organizasyon ,kayıt yaptırıp kapılarda kalan insanlar, 45 dakika beklenen yemek sırası, salonların ısıtma ve havalandırma problemi gibi bir sürü problem.  Ancak gerek SQL Server Öncülerinin gösterdiği çaba gerekse eğitmenlerin teknik bilgisi ve tecrübeleri hepsine bedel diye düşünüyorum.

Katıldığım seminerlerden bahsedecek olursam ilk  katıldığım seminer Levent OKTAR hocanın SQL Server 2014: High Availability and Disaster Recovery Solutions semineriydi.

 
SQL Server ilk versiyonlarından bu yana bu konu ile ilgili bazı çözümler sunmakta.   Ancak son yıllarda iş sürekliliğinin sağlanması ve felaket senaryoları konusunda önemin artması ile birlikte database üreticileride  bu konularda baya geliştirmeler yapmışlardır.

  1. Replication
  2. Log Shipping
  3. Mirroring
  4. Failover Cluster
  5. Always-on

Seminerde bu 5 konu üzerinde teorik bilgiler anlatıldı.  Ancak 2012 ile birlikte gelen Always-On demosu yapılabildi. 2012 öncesinde High Availability konusunda ve Disaster Recovery konusunda ilk 4 madde birlikte kullanılarak çözümler geliştirilmekteydi. 2012 ile birlikte gelen Always-on ile birlikte bu 4 teknolojinin birlikte kullanılması ile elde edilen HADR çözümlerini tek başına yapabilmektedir.

 
Bu yapı bize Server seviyesinde koruma, Sql Server seviyesinde koruma sağlayabildiği gibi database seviyesinde koruma ve client connection seviyesinde koruma sağlar.

Always-on konusunda kısaca değinecek olursak öncelikle AlwaysOn Availability Groups arka planda Windows Failover Clustering teknolojisi üzerinde çalışmaktadır. Ancak Failover Cluster yapısı gibi ortak disk alanı olmasına gerek yoktur. İster shared disklere ister lokal diskler üzerinde çalıştırılabilmektedir.

Always-On kurulumunda öncelikle kurulacak server üzerinde yukarıdada belirttiğim gibi Windows Failover Cluster teknolojisi kurulu olmalıdır.   Windows Server Failover cluster yapısı kurulumunda 2 serverda da aynı versiyon işletim sistemi kurulu olmalıdır.  Aynı updateler yapılmış olmalıdır.Ancak failover cluster yapısında olduğu gibi  ortak bir shared disk alanı bulunmasına gerek yoktur.

Bu yapıda yer alacak tüm serverlar aynı domain içinde bulunmalıdır. Ayrıca tüm serverlar Failover Cluster yapısına eklenmelidir.   Üzerilerinde domain yapısı kurulu olmamalıdır. Tüm veritabanları Full Recovery modda olmalıdır.

Avalibality groupu senkron ve asenkron olarak iki farklı  şekilde tanımlayabiliyoruz.  Senkron modda  bir transactionın başarılı olması için tüm replicalarda tamamlanmış olması gerekmektedir. Ancak buda transaction'un geç bitmesine neden olmaktadır. Ancak replikalar arasında veri tutarlılığı sağlar.  Asenkron modda ise primary serverda tamamlanan her transaction replicalarda da tamamlanmış sayılacağı için işlemler hızlı olmaktadır ancak veri bütünlüğü ve tutarlılık garanti edilmez. 

 
Yukarıdada anlattığım gibi failover cluster yapısından farklı olarak shared disk gereksinimi olmadığı farklı subnetlerde kurulum yapılabilir. Ve hatta Azure üzerine bile replika kurulumu yapılabilir. 


3 Aralık 2014 Çarşamba

DMV-DMF Kullanımı-3(Kullanılmayan Indexlerin Tespit Edilmesi)


Bir önceki makalemde kullanılmayan  veya çok az kullanılan indexlerin query performansını  düşürdüğünü belirtmiştim. Sadece Select işlemleri için değil hatta özellikle insert ve update işlemlerinde kullanılmayan indexler performansı aşağılara çekmektedir.

Indexlerin bütün kullanım bilgileri sys.dm_db_index_usage_stats adlı  DMV'de tutulmaktadır. Bu DMV diğer sys.indexes, sys.objects, sys.schemas ve sys.partitions adlı DMVlerle birlikte sorgulandığında bize index kullanımları ile ilgili ayrıntılı bir bilgi verebilir.

Aşağıdaki script bize index kullanımı ile geniş bir kullanım bilgisi vermektedir. Bu tablo kullanılarak  kullanılmayan indexler silinebilir.  Ancak önceki makalelerimde belirttiğim gibi DMV ve DMFler her SQL Server restart olduğunda yeniden doldurulduğu için SQL Server başladıktan sonra belirli bir süre çalıştırılmış olması Best Practicedir.

SELECT TOP 250 db_name(dm_ius.database_id) As DbName
,o.name As ObjectName
,i.name As IndexName
,i.index_id As IndexID
,dm_ius.user_seeks As UserSeek
,dm_ius.user_scans As UserScans
,dm_ius.user_lookups As UserLookups
,dm_ius.user_updates As UserUpdates
,p.TableRows
FROM sys.dm_db_index_usage_stats dm_ius
INNER JOIN sys.indexes i ON i.index_id=dm_ius.index_id and
dm_ius.object_id=i.object_id
INNER JOIN sys.objects o ON dm_ius.object_id=o.object_id
INNER JOIN sys.schemas s on o.schema_id=s.schema_id
INNER JOIN (SELECT SUM(P.ROWS) TableRows,p.index_id,p.object_id
FROM sys.partitions p GROUP BY p.index_id,p.object_id)p
on p.index_id=dm_ius.index_id and dm_ius.object_id=p.object_id
where OBJECTPROPERTY(dm_ius.object_id,'IsUserTable')=1
and i.type_desc='nonclustered'
and i.is_primary_key=0
and i.is_unique_constraint=0
order by (dm_ius.user_seeks+ dm_ius.user_scans+dm_ius.user_lookups) ASC

DMV-DMF Kullanımı-2(Eksik Indexlerin Tespit Edilmesi)


Bir databasede sorgu performanslarını artırmak için öncelikle index yapısını gözden geçirip eklememiz index ekleyebilmek içinse  eksik olan indexleri ekleyebilmemiz için öncelikle eksik indexleri bulmamız gerekmektedir.  SQL Servera gönderilen sorgular için SQL Server bir query plan oluşturur. Bu query plan en iyi index kullanarak sorgu yapmaya çalışmakta eğer sorgu için index bulamadığı takdirde aşağıdaki DMV ve DMFler üzerinde depolama yapmaktadır.

Aşağıda bulunan 4 DMV ve DMF kullanarak eksik indexlerimizi belirleyebiliyoruz.
  •  sys.dm_db_missing_index_group_stats - DMV-Eksik index’ler hakkında özet bir bilgi sunar.
  • sys.dm_db_missing_index_groups - DMV-sys.dm_db_missing_index_group_stats ile sys.dm_db_missing_index_details arasında ilişki kurmamızı sağlar.
  • sys.dm_db_missing_index_details-DMV-Eksik index hakkında kolon bilgileri gibi detaylı bilgileri döndürür.
  •  sys.dm_db_missing_index_columns - DMF-Eksik index kolonları hakkında bilgi döndüren fonksiyondur. Diğer 3 tanesi ise  viewdir.
Örnek Sorgu
Aşağıdaki sorgu mevcut databasede bulunan eksik indexlerin bir listesini döndürür.
SELECT so.name
    , (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans) as Impact
    , mid.equality_columns
    , mid.inequality_columns
    , mid.included_columns
FROM sys.dm_db_missing_index_group_stats AS migs
INNER JOIN sys.dm_db_missing_index_groups AS mig ON migs.group_handle = mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details AS mid ON mig.index_handle = mid.index_handle
INNER JOIN sys.objects so WITH (nolock) ON mid.object_id = so.object_id
WHERE migs.group_handle IN (
    SELECT     TOP (5000) group_handle
    FROM sys.dm_db_missing_index_group_stats WITH (nolock)
    ORDER BY (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans) DESC)


DMVler her instance başlatıldığında yeniden doldurulduğu için bu DMVler SQL Server başlatıldıktan sonra ve belirli bir süre çalıştırıldıktan sonra kontrol edilmelidir.

SQL Server IQ oranı o kadar iyi olmadığı için bu sorguda önerilen indeksleri körü körüne uygulamak doğru değildir. Öncelikle bir test sunucusu üzerinde index oluşturulmalı ve iş yükü test edilmelidir. Eğer olumlu sonuçlar alınırsa teyit edilmeli ve kullanılmaya başlanmalıdır.

Eğer kullanılmayan bir index oluşturulursa boş yere disk alanı israfı veya dahada önemlisi tabloya yapılan diğer sorgularda performansı düşüreceği için index oluşturulma işi çok iyi analiz edilerek yapılmalıdır.

Not:Kullanılmayan indekslerin tespit edilmesi konusunu DMV-DMF Kullanımı-3 nolu makalede ayrıntılı olarak inceleyeceğiz.

Sql Server DateTime Veri Tipindeki Datayı Türkçe Formatında Göstermek

  SQL'de tarihleri farklı formatlarda göstermek için FORMAT fonksiyonunu kullanabilirsiniz. Türkçe kısa tarih formatı genellikle "...