Recent comments

None


İçerik Ara











Yasal Uyarı
Bu sitede sunulan tüm bilgi ve dökümanlar Turgay Sahtiyan tarafından yazılmaktadır. Yazıların kaynak göstermek şartıyla kullanılması serbesttir.

© Copyright 2009-2013
Takvim
<<  Haziran 2017  >>
PaSaÇaPeCuCuPa
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
Keywords

SQL Server 2011 Denali ile beraber 7 tane yeni Datetime fonksiyonu geldi. Bugün bu fonksiyonlardan en çok hoşuma giden EOMONTH’u örnekler ile inceleyip, diğer kalan 6 tane için de ufak bilgiler vereceğim.

[more]

EOMONTH fonksiyonu parametre olarak verilen tarihin içinde bulunduğu ayın en son gününü verir.

Örneğin aşağıdaki kod ile 2011 Şubat ayının son gününün hangi gün olduğunu öğrenebiliriz.

set dateformat dmy

DECLARE @date DATETIME;
SET @date = '01.02.2011';
SELECT EOMONTH ( @date ) AS Result;

Result
===============
2011-02-28 00:00:00.000

Ya da şu şekilde 2011 Şubat’tan sonra gelen 4.ayın son gününü öğrenebiliriz.

set dateformat dmy
DECLARE @date DATETIME;
SET @date = '01.02.2011';
SELECT EOMONTH (@date,4) AS Result;

Result
===============
2011-06-30 00:00:00.000

EOMONTH fonksiyonu hariç SQL Server 2011 Denali ile gelen diğer DateTime fonksiyonları ve kısa açıklamaları şu şekilde.

  • DATEFROMPARTS : Parametre olarak verilen yıl,ay,gün değerlerinden tarih değeri oluşturmak için kullanılır.
  • DATETIME2FROMPARTS : Parametre olarak verilen yıl, ay, gün, saat, dakika, saniye, hassaslık değerlerinden datetime2 formatında tarih-saat değeri oluşturmak için kullanılır.
  • DATETIMEFROMPARTS : Parametre olarak verilen yıl,ay,gün,saat,dakika,saniye değerlerinden datetime formatında tarih-saat değeri oluşturmak için kullanılır.
  • DATETIMEOFFSETFROMPARTS : Parametre olarak verilen yıl, ay, gün, saat, dakika, saniye ve offset değerlerinden datetimeoffset formatında tarih-saat değeri oluşturmak için kullanılır.
  • SMALLDATETIMEFROMPARTS : Parametre olarak verilen yıl, ay, gün, saat, dakika değerlerinden smalldatetime formatında tarih-saat değeri oluşturmak için kullanılır.
  • TIMEFROMPARTS : Parametre olarak verilen saat, dakika, saniye değerlerinden time formatında saat değeri oluşturmak için kullanılır.

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server 2011 Denali ile beraber gelen yeni objeler sayesinde bir T-SQL komutunun ya da SP,view gibi objelerin çalıştırıldığı zaman döndüreceği kolonların listesini ve veri tiplerini almak mümkün. Ayrıca gene bu objeleri, bir TSQL script içerisindeki parametrelerin tiplerini öğrenmek için de kullanabiliriz.

[more]

Bu objelerin tamamının en büyük özelliği kodu çalıştırmadan bu bilgileri veriyor olmalarıdır. Örneğin şöyle bir senaryo düşünelim.

Uzun çalışan bir TSQL sorgumuz olduğunu düşünelim. Bu sorgu sonucunu da çalıştırdıktan sonra bir temporary tabloya atmak istiyoruz ama tablonun tanımını yani hangi kolon ve kolon tipleri şeklinde oluşturmamız gerektiğini bilmiyoruz.

Klasik yöntemde “into” syntax’ı ile sorguyu çalıştırıp tabloyu create edebiliriz. Ya da artık SQL Server 2011 Denali ile gelen sp_describe_first_result_set ve sys.dm_exec_describe_first_result_set objelerini kullanabiliriz.

sp_describe_first_result_set

Parametre olarak verilen TSQL komutunun döndüreceği ilk result set’in metadata bilgilerini verir.

Örneğin aşağıdaki komut sys.tables system view’ine çekilecek select işlemi sonucunda dönecek kolonların bilgisini döndürür.

exec sp_describe_first_result_set N'SELECT * FROM sys.indexes'

 

1

İlk result set’in metadata bilgilerinin döneceği yukarıda belirtmiştim. Yani aşağıdaki gibi önce sys.tables’a daha sonra sys.columns’a select çeken bir sorgu için gene sys.tables’ın metadata bilgileri dönecektir.

exec sp_describe_first_result_set N'SELECT * FROM sys.indexes; SELECT * FROM sys.columns'

 

sys.dm_exec_describe_first_result

sp_describe_first_result_set ile aynı işi yapan bu DMV, ilk result set’in metadata bilgilerini almak için kullanılabilir.

Kullanımı aşağıdaki gibidir.

select * from sys.dm_exec_describe_first_result_set ('SELECT * FROM sys.indexes', null, 0)

 

2

Bu DMV’nin sp_describe_first_result_set system procedure’ünden en büyük farkı bir tablo gibi sorgulanabilmesidir. Örneğin aşağıdaki gibi bir kullanımımız olabilir.

select dfr.name,dfr.system_type_id,dfr.system_type_name,max_length,precision,scale
from sys.dm_exec_describe_first_result_set ('SELECT * FROM sys.indexes', null, 0) dfr

 

3

 

sys.dm_exec_describe_first_result_set_for_object

Yukarıda anlattığım 2 obje, parametre olarak TSQL ifadesi alıyordu. Bu objelerle aynı işi yapan sys.dm_exec_describe_first_result_set_for_object DMV’si ile parametre olarak object_id alıp bu object_id’den dönen ilk result set’in metadata bilgisini dönmektedir.

Kullanımı aşağıdaki gibidir.

CREATE PROC dbo.sp_mdSample 
AS
	SELECT * FROM sys.indexes

GO

select *
from sys.dm_exec_describe_first_result_set_for_object (object_id('sp_mdSample'), 0)
GO

4

sp_describe_undeclared_parameters

Yukarıda anlattığım objeler ile parametre olarak verilen TSQL komutu ya da Obje çalıştırıldığında dönecek sonucun metadata bilgilerinin nasıl alınacağına bakmıştık. sp_describe_undeclared_parameters sistem SP’si ise TSQL komutunda geçen parametrelerin metadata bilgilerini öğrenmek için kullanılabilir.

Örneğin aşağıdaki sorguda @param1 ve @param2 adında 2 parametre kullanılmakta. Bu parametrelerin tiplerini öğrenmek için şöyle bir komut kullanabiliriz.

exec sp_describe_undeclared_parameters 
   @tsql = N'select * from sys.columns where name = @Param1 and max_length = @Param2'

 

5

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


2008 sunucularımıza SP2 geçiş projesinde cluster ortamlarımızdan birine SP2 geçerken bir hata ile karşılaştık. Servisin tekrar online olmasını engelleyen bu hata neredeyse bizi cluster kurulumunu tekrar yapmaya götürüyordu ki…

[more]

Tek node cluster yapıdaki sunucumuza yaptığımız SP2 upgrade’i sorunsuz bir şekilde tamamlandı. Setup ekranında herhangi bir hata almadan upgrade sonlandı.

Fakat ilgili resource group online olurken sürekli hata alıp tekrar offline duruma geliyordu. Event viewer’ı incelediğimizde şu hata mesajları ile karşılaştık.

Script level upgrade for database 'master' failed because upgrade step 'sqlagent100_msdb_upgrade.sql' encountered error 598, state 1, severity 25. 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.

Görünen o ki, her ne kadar setup başarılı bir şekilde tamamlandığını söylese de SP geçişinde bir sıkıntı oluşmuş ve sqlagent100_msdb_upgrade.sql script’i tamamlanmadığı için SP geçişi yarım kalmıştı. Bu yüzden de servis açılamamaktaydı.

İlk aklımıza gelen, sistemi upgrade’i başlamadan önceki haline çekmek amacıyla SP2 kurulumunu uninstall yapmak oldu. Fakat uninstall işlemi de SP geçişi tamamlanmadığı için başarılı bir şekilde bitemedi.

Daha önce başka bir sunucumuzda bu problem ile karşılaşmış ve MS’e açtığımız case ile cluster kurulumunun tekrar yapılması önerisi gelmişti. Bu problemde de cluster kurulumunu tekrar yapacakken aklımıza şöyle bir şey denemek geldi.

Hata alan script sqlagent100_msdb_upgrade.sql scripti idi. Ama hata mesajını tam olarak göremiyorduk. Bir şekilde bu script’i çalıştırabilirsek hata mesajını açık bir şekilde görebileceğimizi düşündük.

İlk aklımıza gelen normal bir şekilde açılmayan servisi single user mode ile açmak oldu. –m parametresi ile servisi açmaya çalıştığımızda yukarıdaki “recover the master database” hata mesajı ile tekrar karşılaştık.

Daha sonra aklımıza 902 Trace Flag’i geldi. Undocumented olan bu trace flag system database’lerindeki hataları göz ardı edip servisi açmaya yaramakta.

Servisi command promptan 902 trace flag’i ile çalıştırdığımızda online oldu. Şimdi geriye script’i çalıştırmak kaldı.

sqlagent100_msdb_upgrade.sql script’ini osql ile command promptan çalıştırıp sonucu –o parametresi ile bir text dokümanı attık. Script hatalı bittiğinde txt dokümanda gördüğümüz hata mesajı şu şekilde idi.

Msg 5184, Level 16, State 2, Server SPRECBDB01, Line 103
Cannot use file 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Data\temp_MS_AgentSigningCertificate_database.mdf' for clustered server. Only formatted files on which the cluster resource of the server has a dependency can be used. Either the disk resource containing the file is not present in the cluster group or the cluster resource of the Sql Server does not have a dependency on it.

SP geçişlerinde setup.exe geçici bir veritabanı oluşturmakta. Hata mesajının detayına baktığımızda da bu geçici veritabanı C:\ altındaki bir klasöre oluşturulmaya çalışılmakta ve C:\ klasörü, sql server servisinin dependency listesinde olmadığından dolayı da hata alınmakta.

Peki ama bu temporary veritabanı niye C:\ klasörüne oluşturulmaya çalışılıyor?

Üzerinde çalıştığımız cluster ortamı daha önce de söylediğim gibi tek node’lu bir cluster ortamı. Tek node’lu olduğundan dolayı yani failover yapılmayacağından dolayı biz bu ortamı kurarken system database’lerini C:\ folder’ı altına create etmiştik. Normalde bildiğiniz gibi cluster ortamlarda system database’leri shared disk’lerden birinin içinde bulunmalı ki failover yapıldığında servis çalışabilsin.

Yani sonuç olarak bizim bu cluster ortamımızda master veritabanı C:\ folder’ında bulunmaktaydı. Yukarıda bahsettiğim geçici veritabanı da master veritabanının olduğu yerde oluşturulmaya çalışıldığı ve bu folder’da servisin dependency listesinde bulunmadığından dolayı hata alınmaktaydı.

Burada şu soru aklınıza gelebilir. “Hiç cluster’ın system database’leri C diskinde olur mu yahu?”.

Ortam tek node olduğu ve failover ihtiyacı olmadığı için neden olmasın? Ayriyeten eğer olmaması gerekiyorsa kuruluma da izin verilmemesi gerekiyor. Yani bu soruyu bir cevap olarak kabul etmiyorum Smile

Bu sorunun master database’inin C:\ diskinde olmasından kaynaklandığını farkettikten sonra master database’i dependency disklerden birine taşıyıp servisi tekrar çalıştırdık ve güncellenme işlemleri tamamlanarak servis sorunsuz bir şekilde çalıştı.

Aklımıza gelen bu çözümle en az 4-5 saat sürecek reinstallation’dan kurtulmuş olduk.

Şimdi bu durumu MS Connect’e bug kaydı olarak açacağım. En azından bu durumun SP kurulumu yapılırken check edilmesini ve uyarı verilerek kurulumun engellenmesi gerektiğini bildireceğim. Bakalım cevapları ne olacak?

Daha önce bu tarz bir bug kaydımı ByDesign diyerek reddetmişlerdi. Ama bu sefer bu kadar kolay olmayacak Smile

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


17 Ağustos Çarşamba günü yapacağım webcast’in duyurusunu yapmak istiyorum.

Microsoft SQL Azure’a Genel Bakış, SQL Azure Veritabanına İlk Bağlantı başlıklı webcast’im 17.08.2011 tarihinde 21:00-22:00 saatleri arasında gerçekleşecek.

Aşağıdaki url’i kullanarak vereceğim bu webcast’e katılabilirsiniz.

https://www.livemeeting.com/cc/mvp/join?id=NS8GZZ&role=attend&pw=2NM%7E%60JK%7Bt

Ajandamız şu şekilde olacak;

  • Neden SQL Azure?
    • Uygun Maliyetli Ölçeklenebilirlik
    • Yüksek Süreklilik (High Availability)
    • Yönetimsel Maliyetlerin Düşürülmesi
  • Topoloji
  • Ring Topology
  • Veri Merkezleri
  • SQL Azure’da Güvenlik
  • Migration – Deployment
  • SQL Server – SQL Azure Farklılıkları
  • SQL Azure’a İlk Bağlantı
  • Soru – Cevap

Not:Katılım url’i webcast başlamadan yarım saat önce aktif hale gelecektir.

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server 2008 Failover Cluster’ı denetim masasından remove ederken şöyle bir hata ile karşılaşabilirsiniz.

[more]

The SQL Server failover cluster instance name '' could not be found as a cluster resource.

Temiz bir uninstallation yapmak için kurulum programı içindeki Remove node from a SQL Server failover cluster kısmını kullanın.

image

image

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


Atakları minimum hale getirmek ve veritabanı sunucusunu daha güvenli hale getirmek için Shared Memory ya da Named Pipes gibi kullanılmayan protokolleri disable etmekte hatta kullanıcıları TCP/IP’den bağlanmaya zorlamakta fayda vardır.

Bugünkü yazımda hangi protokollerin kullanılmadığını nasıl monitor edeceğimizi ve kullanılmayan protokollerin nasıl disable edileceğini görüyor olacağız.

[more]

Kullanılmayan veya kullanılmadığını düşündüğünüz protokolleri disable etmeden önce bu protokollerin gerçekten kullanılmadığını monitor etmenizde fayda vardır. Bunun için sys.dm_exec_connections DMV’sine belirli aralıklarla sorgu çekilip TCP/IP protokolü hariç kullanılan protokoller var ise bu bilgiler bir temp tabloya kaydedilebilir.

Hatta bir SQL Server job’ı ile yukarıda bahsettiğim sorgu örneğin 1 dakika ara ile otomatik olarak çalıştırılıp, sorgu sonucu bir tabloyo loglanabilir. Job yeterli bir süre çalıştıktan sonra temp tablo kontrol edilerek hangi protokollerin kullanıldığı belirlenebilir.

Şimdi bu monitoring işlemini gerçekleştirelim. İlk olarak sorgu sonucunda çıkan kayıtları loglamak için bir tablo create ediyorum.

USE AdventureWorks2008R2
GO

CREATE TABLE [dbo].[dmexecconnections_perminute](
	[CollectionTime] [datetime] NOT NULL,
	[session_id] [int] NULL,
	[connect_time] [datetime] NOT NULL,
	[net_transport] [nvarchar](40) NOT NULL,
	[protocol_type] [nvarchar](40) NULL,
	[auth_scheme] [nvarchar](40) NOT NULL,
	[client_net_address] [varchar](48) NULL,
	[client_tcp_port] [int] NULL,
	[local_net_address] [varchar](48) NULL,
	[local_tcp_port] [int] NULL,
	[recent_sql_text] [varchar](max) NULL
)
GO

 

1 dakikada bir çalışıp TCP/IP haricinde protokol kullanılarak bağlantı kurulmuş connection’ları loglayan job ise şu şekilde;

USE [msdb]
GO

/****** Object:  Job [dmexeconnections_perminute]    Script Date: 08/03/2011 17:38:21 ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** Object:  JobCategory [[Uncategorized (Local)]]]    Script Date: 08/03/2011 17:38:21 ******/
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

END

DECLARE @jobId BINARY(16)
EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N'dmexeconnections_perminute', 
		@enabled=1, 
		@notify_level_eventlog=0, 
		@notify_level_email=0, 
		@notify_level_netsend=0, 
		@notify_level_page=0, 
		@delete_level=0, 
		@description=N'Gereksiz protokollerin disable edilmesinden önce monitor edilmesi', 
		@category_name=N'[Uncategorized (Local)]', 
		@owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object:  Step [s1]    Script Date: 08/03/2011 17:38:21 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N's1', 
		@step_id=1, 
		@cmdexec_success_code=0, 
		@on_success_action=1, 
		@on_success_step_id=0, 
		@on_fail_action=2, 
		@on_fail_step_id=0, 
		@retry_attempts=0, 
		@retry_interval=0, 
		@os_run_priority=0, @subsystem=N'TSQL', 
		@command=N'insert AdventureWorks2008R2.dbo.dmexecconnections_perminute
select GETDATE() as CollectionTime,session_id,connect_time, net_transport,protocol_type,auth_scheme,client_net_address,client_tcp_port,local_net_address,local_tcp_port
	,st.text
from sys.dm_exec_connections c
cross apply sys.dm_exec_sql_text (c.most_recent_sql_handle) st
where net_transport != ''TCP''', 
		@database_name=N'master', 
		@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N's1', 
		@enabled=1, 
		@freq_type=4, 
		@freq_interval=1, 
		@freq_subday_type=4, 
		@freq_subday_interval=5, 
		@freq_relative_interval=0, 
		@freq_recurrence_factor=0, 
		@active_start_date=20110720, 
		@active_end_date=99991231, 
		@active_start_time=0, 
		@active_end_time=235959, 
		@schedule_uid=N'66452ed0-9229-4eb5-a0aa-8da19ade87de'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
    IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:

GO

Bu job belirli bir süre çalıştıktan sonra log tablosunu kontrol edebiliriz.

image

Gördüğünüz gibi Shared Memory kullanılmakta. Ama Named Pipes kullanılmamakta. Bu durumda Named Pipes protokolünü disable etmeye karar verebilirim.

Ayrıca sorgu sonucunda gördüğünüz recent_sql_text kolonu vasıtasıyla ilgili connection'dan yapılan son sorguyu görmekte bir nebzede olsa connection’ın hangi uygulama için açıldığını anlayabilmekteyiz.

Protokol disable işlemi SQL Server Configuration Manager aracından yapılmaktadır.

image

Yapılan değişikliklerin geçerli olması için Database Engine servisinin restart edilmesi gerektiğini belirterek yazıma son veriyorum.

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server 2011 Denali ile gelen yeni DMV’lerden biri sys.dm_server_services DMV’si. Bu DMV ile SQL Server Agent, Database Service gibi servislerin startup seçenekleri, process id’leri, en son ne zaman başlatıldıkları gibi bilgilerin öğrenilmesi mümkün.

[more]

sys.dm_server_services DMV’si ile alınabilecek bilgilerin bir kısmı şu şekilde;

  • servicename : Kurulu olan servisin adı.
  • startup_desc : Servisin otomatik başlama tipi.
  • status_desc : Servisin şu anki durumu.
  • process_id : Servisin Windows Process ID’si
  • last_startup_time : Servisin en son çalıştırıldığı zaman.
  • service_account : Servisi çalıştırıan kullanıcının adı.
  • filename : Servis exe’sinin bulunduğu dizin ve dosya adı.

Sorguyu şu şekilde çekebiliriz.

select servicename, startup_type_desc, status_desc
	,process_id, last_startup_time, service_account
	,filename
from sys.dm_server_services

 

Yukarıdaki sorgu benim client makinamda şu sonuçları vermekte.

1

Bu DMV’yi özellikle service account’unu ve servisin process ID’sini öğrenmek için kullanabiliriz. Denali’den önceki sürümlerde bu bilgiyi almak için configuration manager’dan bağlantı kurmamız gerekmekteydi.

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server 2011 Denali ile gelen yeni DMV’lerden biri sys.dm_os_windows_info DMV’si. Bu DMV ile veritabanı sunucusunun, release, service pack seviyesi gibi işletim sistemi (Operatin System) bilgilerinin öğrenilmesi mümkün.

[more]

sys.dm_os_windows_info DMV’si ile alınabilecek bilgiler şu şekildedir;

  • windows_release : İşletim sisteminin versiyon numarasını verir. Tüm versiyon numarası listesine şu adresten bakabilirsiniz.
  • windows_service_pack_level : İşletim sisteminin service pack seviyesini verir.
  • windows_sku : İşletim Sistemi Stock Keeping Unit (SKU) ID’sini verir.
  • os_language_version : İşletim sistemi dil numarasını verir. Tüm dil numarası listesine şu adresten bakabilirsiniz.

Sorguyu şu şekilde çekebiliriz.

select * from sys.dm_os_windows_info 

 

Yukarıdaki sorgu benim client makinamda şu sonuçları vermekte.

1

windows_release kolonunda 6.1 değeri Windows7 işletim sistemini, os_language_version kısmındaki 1033 değeri ise English - United States dil seçeneğini ifade etmektedir.

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server sorgu performans analizi yapılırken en çok kullanılan DMV’lerden biri olan sys.dm_exec_query_statsDMV’sine SQL Server 2011 Denali ile beraber 4 yeni kolon eklendi.

[more]

Yeni eklenen bu kolonlar ile sorgu sonucu dönen satır sayısı istatistiklerini öğrenmek mümkün.

Eklenen kolonlar ve açıklamaları şu şekilde;

  • total_rows : Sorgu sonucunda dönen toplam satır sayısı. Bu değer kümülatif olarak hesaplanmaktadır. Yani sorgu her çalıştığında 5 satır döndürüyor ve toplamda 10 kez çalıştırıldıysa bu kolonda 50 değeri yazacaktır.
  • last_rows : Sorgunun en son çalışmasında kaç satır döndürdüğünü gösterir. Yukarıdaki örnek için bu kolonda 5 değeri yazacaktır.
  • min_rows : Sorgunun şu ana kadarki çalıştırılmalarında en az kaç kayıt döndürdüğü bilgisini verir.
  • max_rows : Sorgunun şu ana kadarki çalıştırılmalarında en fazla kaç kayıt döndürdüğü bilgisini verir.

Aşağıdaki sorgu ile SELECT sorgularının döndürdüğü satır sayılarının istatistiklerini analiz edebiliriz.

SELECT qs.execution_count,
    SUBSTRING(qt.text,qs.statement_start_offset/2 +1, 
                 (CASE WHEN qs.statement_end_offset = -1 
                       THEN LEN(CONVERT(nvarchar(max), qt.text)) * 2 
                       ELSE qs.statement_end_offset end -
                            qs.statement_start_offset
                 )/2
             ) AS query_text, 
     qt.dbid, dbname= DB_NAME (qt.dbid), qt.objectid, 
     qs.total_rows, qs.last_rows, qs.min_rows, qs.max_rows
FROM sys.dm_exec_query_stats AS qs 
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt 
WHERE qt.text like '%SELECT%' 
ORDER BY qs.execution_count DESC

 

1

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server 2011 Denali ile gelen yeni araçlardan biri olan “Crescent”, web tabanlı bir raporlama aracı. Crescent ile raporların nasıl hazırlanacağını anlatan aşağıdaki demoyu sizin ile paylaşmak istedim.

SQL

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server 2011 Denali ile gelen yeni DMV’lerden biri sys.dm_os_volume_stats DMV’si. Bu DMV ile data ve log file’larının bulunduğu sürücülerin toplam alan, boş alan gibi bilgilerinin öğrenilmesi mümkün.

[more]

SQL Server 2011 Denali’den önceki sürümlerde de sürücülerin doluluk-kullanım oranlarını öğrenmemiz mümkündü. Hatta bu konu ile ilgili şu makaleyi yazmıştım. Makaleyi incelerseniz eğer doluluk oranları için uzun bir kod kullanmış ve Ole Automation Procedures özelliğini enable etmiştik.

2011 Denali ile beraber bu isteğimizi tek bir DMV’e sorgu çekerek gerçekleştirebiliriz.

Örneğin sunucumuzda bulunan sürücülerden içinde DB olan sürücülerin doluluk-kullanım oranları için şu sorguyu kullanabiliriz.

SELECT volume_mount_point
	   , total_bytes/1024/1024 as ToplamMB_MB
	   , (total_bytes-available_bytes)/1024/1024 as KullanilanAlan_MB
	   , available_bytes/1024/1024 as BosAlan_MB
FROM sys.master_files AS f
CROSS APPLY sys.dm_os_volume_stats(f.database_id, f.file_id)
GROUP BY volume_mount_point, total_bytes, available_bytes

1

Data ve Log dosyalarının bulunduğu sürücülerde yer kalmadığı zaman veritabanının hizmet veremez duruma gelme ihtimalinden dolayı sürücülerdeki boş alanların sürekli monitor edilmesinde fayda vardır.

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan


SQL Server’da bulunan Auto Growth (Otomatik Büyüme) özelliği sayesinde veritabanı dosyaları dolduğunda sistem tarafından otomatik olarak büyütülmektedir. Bu büyüme oransal ya da boyutsal olarak daha önceden belirlenebilir. Aynı zamanda dosyaların en fazla hangi boyuta kadar büyüyebileceği de ayarlanabilir.

Auto Growth işlemi diskte yeni bir alan allocate edilmesinden dolayı kaynak tüketimi fazla olan bir operasyondur. Büyümenin boyutlarına göre bazı durumlarda bu büyüme işlemi 1-5 saniye arasında sürebilir. Büyüme tamamlanana kadar da ilgili dosyaya gelen okuma ve yazma istekleri bekletilecek bu da performans sıkıntısı olarak dönecektir.

[more]

Best practice olarak dosyaların büyümesinin Auto Growth ile değil de DBA’lerin kontrolü altında yapılması önerilir. Sistemin en az yoğun olduğu saatlerde dosyalar yeteri kadar büyütülürse sistemin yoğun olduğu zamanlarda büyüme ihtiyacı ortaya çıkmayacak dolayısıyla performans sıkıntısı oluşmayacaktır.

Her ne kadar büyümeler DBA’ler tarafından yapılsa da plansız büyümelere karşı yine de Auto Growth özelliğinin açık olması önerilir. Bu durumda siz uygun bir saatte büyüme yapsanız da veritabanında gerçekleşecek plansız bir data girişi sonucu dosya dolarsa auto growth özelliği bu durumu sıkıntısız aşmanızı sağlayacaktır.

Auto Growth konusunda SQLRAP’ın önerisi aşağıdaki gibidir.

“Always maintain sufficient free disk space on the SQL Server data and transaction log drives. Enable Autogrow for managing the unexpected growths only. Do not use the Autogrow option for the day-to-day growth operations. Expand the database files during the non-peak times and expand to sufficiently larger chunks.”

Ben aşağıdaki gibi bir job ile otomatik büyümeleri kontrol altında tutmaktayım. Job’ın çalışma mantığını şu şekilde özetleyebiliriz;

  • @FreeSpaceThresholdRate parametresi ile boş alan için bir eşik değeri belirlenir. Örneğin bu değer 0.7 ise; dosyadaki boş olan %70 in altında ise ilgili dosyada büyüme gerçekleştirilir.
  • Sunucuda bulunan bütün veritabanlarının bütün dosyaları bazı özellikler ile beraber bir temp tabloya yazılır. Bu özellikler aşağıdaki gibidir.
    • DBReadOnly : Veritabanının readonly olup olmadığıdır. Readonly olan veritabanlarının dosyaları threshold değerinin içinde kalsalar dahi büyütülmeyecektir. Çünkü bu veritabanlarına veri girişi olmadığı için büyüme ihtimalleri yoktur.
    • FileReadOnly : Dosyanın readonly olup olmadığıdır. Readonly olan dosyalar threshold değerinin içinde kalsalar dahi büyütülmeyecektir. Çünkü bu dosyalara veri girişi olmadığı için büyüme ihtimalleri yoktur.
    • GrowthType : Auto Growth şeklinin oransal mı yoksa boyutsal mı olduğunu gösterir.
    • Growth : Auto Growth’un boyutunu gösterir. Örneğin %10 büyüme olsun şeklinde set edilen parametre için bu kolonda 10 yazacaktır.
    • MaxSize_MB : Dosya boyutu için bir sınır verildiyse bu kolonda gözükür. -1 değeri herhangi bir sınır verilmediğini belirtir.
    • TotalSize_MB : Dosyanın şu andaki boyutudur.
    • SpaceUsed_MB : Dosyanın ne kadarının kullanıldığını gösterir.
    • FreeSpace_MB : Dosyanın boş alanını gösterir.
    • FreeSpaceThreshold_MB : @FreeSpaceThresholdRate parametresine göre dosyada bulunması gereken minimum boş alanı gösterir. Bu değerin FreeSpace_MB değerinden büyük olduğu dosyalarda büyüme gerçekleştirilecektir.
    • NextGrowthSize_MB : Bir sonraki büyümenin ne kadar olduğunu gösterir. File alter edilirken TotalSize_MB+ NextGrowthSize_MB değeri ile alter edilecektir.
  • Temp tablo doldurulduktan sonra bütün satırlar cursor ile dönülür ve FreeSpaceThreshold_MB değeri FreeSpace_MB’dan büyük olan dosyalar alter edilerek büyütülür.
  • Eğer dosya için maksimum büyüme değeri verildi ise(MaxSize_MB), bu değer TotalSize_MB+ NextGrowthSize_MB ile karşılaştırılır. Eğer maksimum değeri aşma durumu var ise büyüme yapılmaz.
Job’ın scripti ise şu şekilde;
declare @FreeSpaceThresholdRate float = 0.7

declare @DBName sysName, 
		@DBIsReadOnly int,
		@FileIsReadOnly int,
		@LogicalFileName sysName, 
		@TotalSize_MB int, 
		@NextGrowthSize_MB int,
		@sql varchar(max)=''

CREATE TABLE #tmptbl1(
	[DBName] [varchar](128),
	[DBIsReadOnly] [int] ,
	[fileid] [smallint] ,
	[LogicalFileName] [sysname] ,
	[FileNameWithURL] [varchar](260) ,
	[FileIsReadOnly] [int] ,
	[IsPrimaryFile] [int] ,
	[IsLogFile] [int] ,
	[GrowthType] [varchar](7) ,
	[Growth] [float] ,
	[MaxSize_MB] [float] ,
	[TotalSize_MB] [float] ,
	[SpaceUsed_MB] [float] ,
	[FreeSpace_MB] [float] ,
	[FreeSpaceThreshold_MB] [float] ,
	[NextGrowthSize_MB] [float] 
) ON [PRIMARY]

select @sql='use ?;
	insert #tmptbl1
	select DB_NAME() as DBName
		, (case DATABASEPROPERTYEX(DB_NAME(),''Updateability'') when ''READ_ONLY'' then 1 else 0 end) as DBIsReadOnly
		, f.fileid, f.name as LogicalFileName
		, f.filename as FileNameWithURL
		, FILEPROPERTY(f.name, ''IsReadOnly'') as FileIsReadOnly
		, FILEPROPERTY(f.name, ''IsPrimaryFile'') as IsPrimaryFile
		, FILEPROPERTY(f.name, ''IsLogFile'') as IsLogFile
		, (Case when f.growth<128 then ''Percent'' else ''MB'' end) as GrowthType
		, (Case when f.growth<128 then growth else Round(cast(f.growth*8 as float)/1024,2) end) as Growth
		, (Case f.maxsize when -1 then -1 else Round(cast(f.maxsize/1024 as float)*8,2) end) as MaxSize_MB
		, Round(cast(f.size*8 as float)/1024,2) as TotalSize_MB
		, Round(cast(FILEPROPERTY(f.name, ''SpaceUsed'')*8 as float)/1024,2) as SpaceUsed_MB
		, Round(cast((f.size - FILEPROPERTY(f.name, ''SpaceUsed''))*8 as float)/1024,2) as FreeSpace_MB
		, Round('+cast(@FreeSpaceThresholdRate as varchar(5))+'*(Case 
			when f.growth<128 then (growth/100.)*cast(f.size*8 as float)/1024
			else Round(cast(f.growth*8 as float)/1024,2) 
			end),2) as FreeSpaceThreshold_MB
		, Round((Case 
			when f.growth<128 then (growth/100.)*cast(f.size*8 as float)/1024
			else Round(cast(f.growth*8 as float)/1024,2) 
			end),2) as NextGrowthSize_MB
	from sys.sysfiles f
	order by f.fileid
'
exec sp_msforeachdb @sql

declare CursorX cursor for
select DBName, DBIsReadOnly, FileIsReadOnly, LogicalFileName, TotalSize_MB, NextGrowthSize_MB from #tmptbl1 
	where (DBIsReadOnly = 0) and (FileIsReadOnly = 0)
		and (FreeSpaceThreshold_MB>FreeSpace_MB)
		and (MaxSize_MB=-1 or (TotalSize_MB+NextGrowthSize_MB)<=MaxSize_MB)
open Cursorx
fetch from Cursorx into @DBName, @DBIsReadOnly, @FileIsReadOnly, @LogicalFileName, @TotalSize_MB, @NextGrowthSize_MB
while @@FETCH_STATUS=0
begin
    set @sql = 'USE [master];
		ALTER DATABASE ['+@DBName+'] MODIFY FILE ( NAME = N'''+@LogicalFileName+''', 
	         SIZE = '+cast((@TotalSize_MB+@NextGrowthSize_MB)*1024 as varchar(10))+'KB )'
    exec(@sql)
    fetch next from Cursorx into @DBName, @DBIsReadOnly, @FileIsReadOnly, @LogicalFileName, @TotalSize_MB, @NextGrowthSize_MB
end
close Cursorx
deallocate Cursorx

drop table #tmptbl1

 

Veritabanı dosyalarının otomatik büyüme işlemlerinin gün içinde yapılmaması performans amaçlı best practice’lerden biridir. Bu yüzden otomatik büyümeler kontrol altında tutulmamalı ve gün içinde büyüme ihtiyacı olmayacak şekilde az yoğun olan saatlerde bakımı yapılarak büyütülmelidir. Her ne kadar büyümeler bu şekilde kontrol altına alınsa da plansız büyümelerin problem yaratmaması için Auto Growth özelliği kullanılmaya devam edilmelidir.

 

İyi Çalışmalar

Turgay Sahtiyan

Not : Blog haricinde, faydali gördügüm yazilari ve linkleri twitter adresimden paylasiyorum. Beni twitter'da takip etmek için : twitter.com/turgaysahtiyan