16 Ocak 2012 Pazartesi

"Executed as user: DOMAIN\ServiceAccountName. Cannot open backup device 'X:\BACKUP\BackupFileName'. Operating system error 5(failed to retrieve text for this error. Reason: 15105). [SQLSTATE 42000] (Error 3201) BACKUP DATABASE is terminating abnormally. [SQLSTATE 42000] (Error 3013). The step failed."

HATA: "Executed as user: DOMAIN\ServiceAccountName. Cannot open backup device 'X:\BACKUP\BackupFileName'. Operating system error 5(failed to retrieve text for this error. Reason: 15105). [SQLSTATE 42000] (Error 3201) BACKUP DATABASE is terminating abnormally. [SQLSTATE 42000] (Error 3013). The step failed."

AÇIKLAMA: SQL Server veritabanlarında yedek alırken, böyle hatalar alabilirsiniz. Bu hata mesajında öncelikle benim dikkatimi çeken "Operating system error 5" mesajıydı. Bu mesajı gördüğünüzde, "Access is denied" cümleciği gelmeli aklınıza. Normalde hemen bu mesajın yanındaki parantez içerisinde yazmalıydı "Access is denied", fakat benim de bilmediğim bir nedenden dolayı hata mesajının alınamadığına dair bir mesaj var parantez içerisinde. Bu sonuca göre belli ki ilgili yola erişilemiyor. Bu da akla (en azından benimkine) iki şey getirir hemen

1- SQL Server servis hesabının ilgili yola erişim yetkisi yok,
2- Belirtilen yol yok, bir şekilde disk veya klasör uçmuş.

Normalde, hata mesajındaki parantez içerisinde

ÇÖZÜM: Yukarıda da belirttiğim aklıma gelen şeyleri kontrol ederken, diskin ve klasörün yerinde olduğundan emin olduktan sonra, SQL Server servis hesabının ilgili klasöre yetkisinin olup olmadığını kontrol ettim ve ilgili yetkinin olmadığını gördüm. SQL Server servis hesabı için o klasöre okuma\yazma yetkisi verdikten sonra yedek alma işlemi başarıyla tamamlandı ve sorun çözümlenmiş oldu.

10 Ocak 2012 Salı

Uzun süren maliyetli işlerin takibi

SQL Server Kurulumlarında Gözden Kaçanlar - 8 başlıklı yazımda bir DBA'in veritabanı sunucusunda takip etmek isteyeceği şeylerden bahsetmiştim, bunlardan bir diğeri de uzun süren maliyetli işlerin takibiydi. Bu yazımda da bu konuya değineceğim.

Uzun süren maliyetli işler, genelde:
- Eksik veya yanlış Index'lerden,
- Zamanla ilgili tablolara yeni sorguların gelmesinden,
- Gelen sorgularda değişiklik yapılıp Index'lerde değişiklik yapılmasının unutulmasından,
- Implicit Conversion'lar...


gibi nedenlerden dolayı kaynaklanır.

Geçmişe dönük olarak bu maliyetli işleri sorgulamayı ise, Server Side Trace kullanımıyla görebilirsiniz. Tabii ki kullanacağınız süzgeç değerlerinin kendi ortamınıza göre değişiklik gösterebileceği unutulmamalıdır. Örneğin biz genel olarak kendi ortamlarımızda Batch işlemlerin tamamlanma sürelerini yarım saniyeyi aştığı durumları yakalamayı uygun görüyoruz.

Uzun süren maliyetli işlerin geçmişe dönük takibi için aşağıdaki ekran görüntüsünde de görüleceği gibi bir Server Side Trace ayarlamanız çoğu durum için uygun olacaktır:



Çok temel olarak, gelen sorguların şayet Duration değerleri yüksekse, sorguda kullanılan Function'lara, Implicit Conversion'lara dikkat edin; şayet Reads fazlaysa, o zaman da eksik veya yanlış Index kullanımına odaklanabilirsiniz.

Konuyla ilgili yazılar:
Server Side Trace hazırlamak

9 Ocak 2012 Pazartesi

Server Side Trace hazırlamak

Deadlock takibi ve Blocking takibi yazılarımda bahsettiğim ve önerdiğim Server Side Trace kullanımı hakkında bilgi vermek için de bir yazı yazacağımı söylemiştim, bu işte o.

Bir Server Side Trace hazırlamanın en pratik yolu, SQL Server Profiler aracını kullanmaktır. Öncelikle Profiler'ı açar, istediğiniz Event'leri ve alanları seçer, istediğiniz süzgeci koyarsınız.



Ardından "Trace Properties" penceresindeki "Run" düğmesine tıklayıp Trace'i başlatır ve anında durdurursunuz. Trace'in Script'ini almak için "File->Export->Script Trace Definition->(kullanacağınız versiyona göre...)For SQL Server 2005 - 2008 R2..." komutunu seçebilirsiniz. Oluşturulan Script'i, Script içerisindeki "InsertFileNameHere" değerini değiştirdikten sonra (Script içerisindeki açıklamaları okuyun lütfen) doğrudan Query Editor'de çalıştırabilirsiniz ve Server Side Trace'iniz çalışmaya başlayacaktır.



Bu Trace'leri ağınızdaki başka bir sunucuda barındırmak mantıklı olacaktır. Hem üretim sunucunuzun disklerini meşgul etmezsiniz, hem eğer birden fazla SQL Server sunucunuz varsa tüm dosyaları merkezi bir yerde tutabilir ve üretim sunucunuzu etkilemeden tetkiklerde bulunabilirsiniz.

Ben ayrıca kritik sunucularım için bu Server Side Trace'lerinin çalışıp çalışmadığını kontrol ettirmeyi de yeğliyorum. "sys.traces" Catalog View'ünü kullanarak çalışan Trace'leri zaman zaman sorgulattırıp, çalışmayan Trace'ler için haberdar olmanızı sağlayabilirsiniz. Böylece Blocking, Deadlock, uzun süren sorguların kaydedilmesi gibi bir DBA için çok elzem olan bilgileri toparlama işini de garantiye almış olursunuz.

6 Ocak 2012 Cuma

Deadlock takibi

SQL Server Kurulumlarında Gözden Kaçanlar - 8 yazısında izlenmezse olmaz diye bahsettiğim şeylerden bir diğeri de Deadlock takibi.

Bir kullanıcı size aşağıdaki gibi bir hata mesajı gösterip, sorun yaşadığını söyleyebilir:

Transaction (Process ID 845) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

Şayet Deadlock takibi için bir Trace Flag veya bir Profiler\Server Side Trace kullanmıyorsanız, bu sorunun nedenini anlamanız pek mümkün değildir. Bu nedenle SQL Server'da Deadlock takibi için Trace Flag veya tercihen bir Server Side Trace kullanmak çok yerinde olacaktır. Çünkü bu sayede Deadlock sorunlarıyla ilgili tüm veriler tek bir yerde tutulmuş olur ve yönetimi ve ulaşılabilirliği kolay olur. Trace Flag kullandığınız zaman ise veriler SQL Server Error Log'a yazılacaktır ve diğer tüm verilerle karışacak ve Error Log'u da şişirmiş olacaktır.

Aşağıdaki kod ile, hiç SQL Server servisini kapatıp açmaya gerek kalmadan anlık Deadlock takibi yapabilirsiniz. Anlık diyorum, çünkü bunu bir Oturum (Session) açarak takip etmiş olacaksınız. Oturum kapanabilir, ama Server Side Trace daha sağlamdır.

dbcc traceon (1204, 3605, -1)
go
dbcc tracestatus(-1)
go

Bu takibi Profiler ile yapmak için, "Locks" Event'i altındaki "Deadlock graph" Event'ini kullanabilirsiniz.



Bu takipleri yaptığınız takdirde, geçmişe dönük Deadlock verilerine de ulaşabilir durumda olursunuz ve bu sayede Deadlock sorunlarını çözecek veriye sahip olursunuz.

Konuyla ilgili yazılar:
Server Side Trace hazırlamak

5 Ocak 2012 Perşembe

Blocking takibi

Yine SQL Server Kurulumlarında Gözden Kaçanlar - 8 yazısına istinaden, bu yazıda Blocking takibini nasıl yapabileceğinizden bahsedeceğim.

Blocking takibinin geçmişe dönük olsun, anlık olsun yapılmasında büyük fayda vardır. Örneğin kullanıcılar veya sistemciler size gelip "bugün şu saatte zaman aşımı sorunu yaşadık (time-out), acaba veritabanı tarafında bir sorun olabilir mi?" diye sorduklarında, şayet elinizde geçmişe dönük veri yoksa cevap veremezsiniz. Bu da pek hoş bir durum değil. Özellikle bu gibi durumlarda Deadlock, Blocking, uzun çalışan işlemler gibi bilgilere geçmişe dönük şekilde sahip olmak istersiniz. İşte bu yazıda bu 3 temel gereksinimden birisi olan Blocking takibinden bahsedeceğim.

Anlık Blocking takibini iki pratik araçla yapabilirsiniz. Bunlardan biri, Microsoft'un aracı olan "sp_blocker_pss08" isimli SP. Bu SP'ye aşağıdaki adresten ulaşabilirsiniz:

http://support.microsoft.com/kb/271509/tr

Diğer araç ise, SQL Server konusunda dünya çapındaki duayenlerden Adam Machanic'in yazdığı "sp_WhoIsActive" isimli araç. Bu aracı da aşağıdaki adresten edinebilirsiniz.

http://sqlblog.com/tags/Who+is+Active/default.aspx

sp_WhoIsActive isimli Stored Procedure (SP)'ün birçok parametresi bulunmaktadır ve temel maksadı o anda çalışan tüm işlemleri ayrıntılı şekilde göstermektir. Bu SP ile Blocking takibi yapabilmek için "@find_block_leaders" ve "@sort_order" parametrelerini kullanmalısınız, örnek:

EXEC sp_WhoIsActive @find_block_leaders = 1, @sort_order = '[blocked_session_count] DESC'

Geçmişe dönük Blocking takibi ihtiyacınızı karşılamak için ise bir Server Side Trace* kullanabilirsiniz. Bu Trace'te "Errors and Warnings" Event grubunun içindeki "Blocked process report" Event'ini kullanabilirsiniz.



Fakat bu Event'i kullanabilmek için öncelikle SQL Server Kurulumlarında Gözden Kaçanlar - 2 yazımda bahsettiğim "blocked process threshold (s)" ayarını yapmalısınız.

Sonuç olarak, eğer Microsoft'un aracı olan "sp_blocker_pss08" veya Adam Machanic'in çok amaçlı aracı olan (ki favorim) "sp_WhoIsActive" araçlarından birini veya hepsini kullanarak anlık Blocking takibi yapabilir ve "Blocked process report" Event'ini kullanarak oluşturacağınız bir Server Side Trace'i de geçmişe dönük verileri tutmak için kullanabilirsiniz.

*Bir Server Side Trace oluşturma ve yönetme konusunda da başka bir gün (belki yarın?) bir yazı yazacağım. Bu konuda deneyimi olmayan arkadaşlarım o yazıdan da yararlanabilir.

Konuyla ilgili yazılar:
Server Side Trace hazırlamak

4 Ocak 2012 Çarşamba

Transaction Log doluluk oranını tespit etmek

"SQL Server Kurulumlarında Gözden Kaçanlar - 8" başlıklı yazımda belirttiğim maddelerden biri olan Transaction Log dosyasının doluluk oranını takip etmek için örneğin 3. parti bir yazılım olan Quest'in Stoplight ürününü de kullanabilirsiniz, aşağıda anlattığım yöntemi de. 3. ürün paralı, anlatacağım yöntem beleş ;)

Normal şartlar altında Transaction Log dosyalarının boyutları ve içlerinin doluluk oranları gibi bilgileri DBCC SQLPERF(LOGSPACE) komutuyla alabilirsiniz. Zaten yazdığım Script'te de bunu kullandım. Ayrıca bu işlemi parametrik bir hale getirdim. Parametreler için bir tablo ve sonuçları almak için de bir SP iş görüyor. Eğer her SQL Server Instance'ınızda DBA araçları için oluşturduğunuz bir DBA veritabanınız varsa bu iki nesneyi de o veritabanında tutabilirsiniz.

Ben DBA isimli bir SCHEMA kullanıyorum DBA araçları için, siz de isterseniz böyle yapabilirsiniz veya kendi standardınız varsa onu kullanabilirsiniz.

Tüm bu işlemlere başlamadan önce, komutları nesneleri yaratmak istediğiniz veritabanında çalıştıracağınızdan emin olun. Yeni bir SCHEMA yaratmak için (örneğin DBA):

CREATE SCHEMA [DBA]

Tablonun Script'i şöyle:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON GO
CREATE TABLE [DBA].[GET_USED_LOG_PERCENTAGE_PARAMS](
[dbname] [nvarchar](250) NOT NULL,
[major] [tinyint] NOT NULL,
[critical] [tinyint] NOT NULL
) ON [PRIMARY]
GO

dbname: Bu alana, hangi veritabanının Transaction Log doluluk oranını izlemek istiyorsak, o veritabanının adını yazıyoruz.
major: Bu alana, kritik hatadan önce gelmesini istediğimiz uyarı değerini giriyoruz. Yani örneğin dosyanın boyutu 10GB ve dosyanın %60'ı doldu ve eğer major değer olarak "60" girdiyseniz, kendinize bu eşik değere ulaşıldığında (örneğin Database Mail ile) e-posta göndertebilirsiniz.
critical: Bu alana da kritik eşik değerini giriyoruz. Bu değere ulaşıldığında artık kesinkes haberdar edilmek istersiniz, bu değeri buna göre ayarlamalısınız. Örneğin "85" gibi.

Tabloyu oluşturduktan sonra, Transaction Log'ların doluluk oranını denetleyecek Stored Procedure (SP)'u da oluşturabilirsiniz:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [DBA].[GET_USED_LOG_PERCENTAGE]
AS
IF EXISTS(SELECT * from tempdb..sysobjects where name like '#LogSpaceUsed%')
DROP TABLE #LogSpaceUsed
CREATE TABLE #LogSpaceUsed (dbname nvarchar(200) not null, logsize dec not null, spaceused dec not null, [status] tinyint, )
INSERT INTO #LogSpaceUsed exec sp_executesql N'dbcc sqlperf(logspace)'
SELECT PRM.dbname [Database], spaceused [Percentage Used], PRM.[major], PRM.[critical], 'CRITICAL' AS [Severity] FROM #LogSpaceUsed AS LSU
INNER JOIN DBA.GET_USED_LOG_PERCENTAGE_PARAMS AS PRM ON PRM.dbname = LSU.dbname
WHERE PRM.dbname NOT IN ('model') AND LSU.[spaceused] >= PRM.[critical]
Union all
SELECT PRM.dbname [Database], spaceused [Percentage Used], PRM.[major], PRM.[critical], 'MAJOR' AS [Severity] FROM #LogSpaceUsed AS LSU
INNER JOIN DBA.GET_USED_LOG_PERCENTAGE_PARAMS AS PRM ON PRM.dbname = LSU.dbname
WHERE PRM.dbname NOT IN ('model') AND (LSU.[spaceused] >= PRM.[major] AND LSU.[spaceused] < PRM.[critical])

Bu SP ile, önceden oluşturduğumuz [DBA].[GET_USED_LOG_PERCENTAGE_PARAMS] isimli tablodaki parametreler kullanılarak takip edilmesi istenen veritabanlarının Transaction Log'larını her bir veritabanı için ayrı ayrı belirlediğiniz Major ve Critical değerlere göre sorgulayabilirsiniz. Çıkan sonucu ister HP Openview gibi bir izleme uygulaması ile alırsınız, isterseniz Database Mail ile kendinize e-posta göndertebilirsiniz veya RAISERROR ile Log'lara da kaydettirebilirsiniz ihtiyacınıza göre.

İlgili bağlantılar:
SQL Server Kurulumlarında Gözden Kaçanlar - 8

2 Ocak 2012 Pazartesi

Tüm "sysadmin"ler silinirse ne yapmak gerek?

Aşağıdaki gibi bazı durumlarda bir SQL Server Instance'ınız için tüm sistem yöneticiliği yetkilerini kaybedebilirsiniz:

- "sysadmin" rolüne sahip tüm kullanıcılar yanlışlıkla silinebilir,

- "sysadmin" rolüne sahip kullanıcılar şirketten ayrılır veya şirkete bağlanamıyor durumda olabilirler,

- "sa" hesabı pasiftir (disabled) ve kimse de şifresini bilmiyordur.

Böyle bir durumda kurulu olan SQL Server Instance'ını kaldırıp tekrar kurabilir ve kullanıcı veritabanlarını tekrar Attach edebilirsiniz. Fakat bu seçenek oldukça zaman kaybına neden olacaktır. Ayrıca sistem veritabanlarını kullanmazsanız tüm sunucu düzeyindeki ayarları ve nesneleri kaybedebilirsiniz.

Daha iyi bir çözüm ise, SQL Server Instance'ını "Single-user Mode"da çalıştırıp (-f veya -m parametresiyle), Local Administrators grubunun üyesi olan bir kullanıcıyı kullanarak bu Instance'a bağlanmaktır. Bu sayede yetkisi olsun olmasın, bu kullanıcı SQL Server Instance'ına "sysadmin" olarak bağlanacaktır. Bu noktadan sonra istediğiniz işlemi yapabilir, "sa" hesabını etkinleştirebilir ve şifresini değiştirebilir veya yeni kullanıcılar yaratıp veya varolan kullanıcılara "sysadmin" rolüne üyelik verebilirsiniz. Ayrıca bu parametre değişikliğini yaptıktan sonra, SQL Server servisini durdurup tekrar başlatmanız gerektiğini unutmamalısınız.

Bu işlemi yaparken (SQL Server'ı başlattığınızda) SQL Server Agent servisinin veya başka bir servisin çalışmadığından emin olmalısınız. Çünkü SQL Server'ı tek kullanıcı durumunda açmış oluyorsunuz ve eğer sizden önce başka bir servis veya kişi bağlanırsa o zaman sunucuya bağlanamaz durumda olursunuz. Bu nedenle sunucuya sizden başka kimsenin bağlanamadığından emin olmalısınız.

Bir SQL Server Instance'ını nasıl Single-user mode'a alabileceğinizi gösteren ekran görüntüsü aşağıdadır: