Yazar arşivleri: Ahmet Kaymaz

DBCC INPUTBUFFER Kullanımı

SQL Server üzerinde sistemin durumunu izlediğimizde o anda çalıştırılan SQL ifadelerini, scriptlerini görmek isteriz. Bu amaçla genellikle sp_who veya sp_who2 komutlarını kullanarak ilgili SPID’ye erişilir. O oturumdaki SQL cümleciğine erişmek için DBCC INPUTBUFFER komutu çalıştırılır. Bu komuta SPID değeri parametre olarak verilir.

DBCC INPUTBUFFER(60)

Bu komuta alternatif olarak dm_exec_requests DMV tercih edilebilir. Böylece her iki yöntemle de bir oturumdaki en son çalıştırılan SQL ifadesini görmüş oluruz.

SELECT 
    SQLStatement       =
        SUBSTRING
        (
            qt.text,
            er.statement_start_offset/2,
            (CASE WHEN er.statement_end_offset = -1
                THEN LEN(CONVERT(nvarchar(MAX), qt.text)) * 2
                ELSE er.statement_end_offset
                END - er.statement_start_offset)/2
        )
        
FROM sys.dm_exec_requests er
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt
WHERE er.session_id = 60

SQL Server Yüksek CPU Sorunu

Veri tabanı yönetim tarafındaki en büyük kabusumuz disk, işlemci ve bellek kaynaklarının yüksek ölçüde kullanılıyor olmasıdır. Bu yazıda SQL Server tarafından CPU kullanımını nasıl takip edeceğimizi ve yöneteceğimizi örneklendiriyor olacağız. Ayrıca CPU ile ilişki konusunda SQL Server yönetimi konusunda kullandığım farklı kaynaklardan edindiğim birkaç script paylaşıyor olacağım. SQL Server üzerindeki CPU kullanımını izlemek için sp_who2 komutu Activity Monitor veya DMV’ler ((Dynamic Management Views)) kullanılabilir. Sunucuda yüksek CPU kullanımına denk geldiğimizde bakacağımız ilk yer Task Manager aracıdır. Burada SQL Server’in yüksek CPU kullandığından emin olmamız gerekiyor. Task Manager içerisinde sqlservr.exe programının karşısında CPU kullanımı gösterilmektedir. Ardından SQL Server tarafına geçip tam olarak SQL Server’in hangi prosesin bu kaynağı kullandığını takip ederiz. Bunun için kullanacağımız Performance Monitor (perfmon) aracını kullanacağız. SQL Server, her bağlantı için tekil bir numara verir. SPID (SQL Server Process ID) olarak bilinen bu numara tam olarak hangi bağlantıya odaklanmamız konusunda yönlendirici olacak. 1 ve 50 aralığındaki SPID’leri SQL Server, kendisi kullanır. Kullanıcı bağlantılarını 50’den sonra olacak şekilde numaralandırır. SQL’deki her bağlantının işletim tarafındaki thread ile ilişkisini KPID (Kernel Process ID) numarası üzerinden sağlar. ID Thread olarak ta bilinen bu numara SQL tarafından bir thread açıldığı zaman Windows tarafından atanır. Windows tarafındaki thread’lari ayırt etmek için kullanılır. spid ve kpid ilişkisi için master.dbo.sysprocesses DMV’ye bakılabilir.


Okumaya devam et

SQL Server Cluster Node Sorgulama

T-SQL ile SQL Server Cluster altındaki düğüm ve paylaşılmış disklerini (Shared Drives) T-SQL komutlarıyla sorgulamak isteyebiliriz.

SQL Server’in üzerinde koştuğu mevcut node’u bulmak için

SELECT SERVERPROPERTY('ComputerNamePhysicalNetBIOS') AS [Mevcut Node Adı] 

SQL Server’in node’larını listelemek için

SELECT * FROM fn_virtualservernodes()

--Veya
SELECT * FROM sys.dm_os_cluster_nodes 

Cluster için kullanılan ortak diskleri listelemek için

SELECT * FROM fn_servershareddrives() 

--Veya
SELECT * FROM sys.dm_io_cluster_shared_drives

CorFlags dönüştürme aracı

Visual Studio ile birlikte gelen CorFlags aracı PE image’a ait corflags section bölümünü dönüştürmek için kullanılır. Bu şu demek; bilindiği gibi .NET ortamında bir uygulama geliştirirken derleme işlemini istediğimiz 32-bit veya 64-bit ortamına göre gerçekleştirebiliriz. Bu durumda kullanılacak Assembly’ler ona göre aktifleştirilir. Yani uygulamayı 32-bit’e göre gerçekleştirirsek kütüphaneler aşağıdaki klasörden

…\WINDOWS\Microsoft.Net\Framework\v2.0.50727

64-bit’e göre gerçekleştirirsek aşağıdaki klasörden okunur.

…\WINDOWS\Microsoft.Net\Framework64\v2.0.50727

.NET Framework’ün kendisinde olmayan bir Assembly’i kullanmışsak bunu uygulamanın config dosyasında belirtmemiz gerekiyor. Aynı şekilde 64-bit makinelerde türüne göre GAC_32, GAC_64 ve GAC_MSIL Global Assembly Cache klasörleri mevcuttur. 32-bit ortamlarda sadece GAC_32 ve GAC_MSIL klasörleri bulunur. GAC_MSIL klasörü platformu belirsiz yani AnyCpu olarak derlenmiş Assembly’leri içerir.

Bir uygulamayı aşağıdaki seçeneklere göre derleyebiliriz;

Anycpu – platform belirsiz
x86 – 32-bit platform
x64 – x64 platform
itanium – IA platform

.NET derleyicisi default olarak uygulamayı anycpu türünde derler. Bu da o uygulamanın hem 32-bit hem de 64-bit ortamında çalışabileceğini belirtir. Bu nedenle portable assembly olarak isimlendirilir.

Fakat bazı durumlarda hazırladığımız bir uygulamanın mutlaka belli bir platformda örneğin ne olursa olsun hep 32-bit çalışmasını istediğimizde bu dönüştürmeyi CorFlags aracı ile gerçekleştirebiliriz.

Ben bu aracı daha çok bir Assembly’nin hangi platformda kullanılabileceğini öğrenmek için kullanıyorum. CorFlags şeklinde komutu çalıştırdıktan sonra aşağıdaki gibi bir sonuç elde edilir.

Version : v4.0.30319
CLR Header: 2.5
PE : PE32+
CorFlags : 0x9
ILONLY : 1
32BITREQ : 0
32BITPREF : 0
Signed : 1

Bu alanlar uygulamanın hangi .NET Framework versiyonunda built edildiğini, CLR versiyonunu gibi bilgileri belirtir. Örneğin bu dosya için PE değerinin PE32+ olması bu assembly’nin 64 bit olduğunu gösterir.

CorFlags aracını kullanmak için Visual Studio Command Prompt üzerinden çalıştırmak gerekir.

Stored Procedure’in Sonucunu Tabloya Aktarma

SQL Server’de bir Stored Procedure ‘ü çalıştırıp sonucunu bir tabloya aktarmak için genellikle önce o şemaya uygun tablo oluşturulur. Ardından o tabloya INSERT INTO ile data aktarılır. Aşağıdaki örnekte spGetData prosedürünün sonucuna uygun şemada bir #table1 oluşturulmuş ardından prosedürün sonucu bu tabloya aktarılmıştır.

CREATE TABLE #table1
(
   Column1 INT,
   Column2  VARCHAR(10)
)

INSERT INTO #table1 
Exec spGetData 1

Kolay bir yöntem olarak OPENROWSET fonksiyonunun kullanılmasıdır.

SELECT * INTO #table1 FROM OPENROWSET('SQLNCLI', 'server=(local)' , 
	'Exec spGetData ')

Shrink Esnasında “Backup, file manipulation operations” Hatası

Management Studio üzerinden veya Job aracılığıyla otomatik olarak SHRINK işlemi yapılmak istendiğinde aşağıdaki hata mesajı alınabilir.
Backup, file manipulation operations (such as ALTER DATABASE ADD FILE) and encryption changes on a database must be serialized. Reissue the statement after the current backup or file manipulation operation is completed
Bu hata mesajına veri ambarı projesinde her gece shrink Job çalışırken almıştım. Bu mesajın 2 nedeni olabilir;

      O anda veritabanına ait dosyalarda değişiklik ekleme çıkarma yapılıyorsa. Yani mevcut MDF’lerden biri kaldırılıyor veya yeni MDF ekleniyorsa bu hata mesajı alınabilir. Bunu da bilindiği gibi ALTER DATABASE komutu aracılığıyla ADD FILE veya REMOVE FILE tümceleri kullanılarak yapılmaktadır.
      İkinci neden de o esnada sistemde backup alıyor olmasıdır ki ben de bu şekilde tecrübe edindim.

O esnada bu işlemler yapılıyorsa Shrink işlemi başarısız bir şekilde sonlandırılacaktır.

SQL Server VLF (Virtual Log File) Nedir ?

VLF, SQL Server tarafından dahili olarak yönetilen LDF içerisinde bulunan sanal log dosyalarıdır. Fiziksel log dosyaları (LDF dosyaları) veritabanı sistemi tarafından iç transaction yönetimi için birden fazla mantıksal dosyalara bölümlendirilir. Bir sistemde bu dosyaların sayısı artıkça özellikle sistemin yeniden açılma durumlarında o veritabanının toparlanma süresi (recovery time) uzadığı gibi LOG dosyasına ihtiyaç duyuldukça performans sorunu yaşanır. Bu tür çok log dosyalı veritabanlarında SQL servisini restart ettiğimizde o veritabanı uzun süre “Restoring” modunda kalabiliyor. Bu veritabanının kendine gelme süresi bazen 1-2 saati bulabiliyor.
İdeal durumda VLF sayısının 50 veya altı olması beklenir. Bu rakamın üstündeki her dosya performansı olumsuz etkileyecektir. Mevcut veritabanında ne kadar VLF olduğunu anlamak için DBCC LOGINFO komutu kullanılır.
Bu sayıyı düşürmek için sık sık Transaction Log Backup alınabilir.
BACKUP LOG VeriTabaniAdi TO SurucuAdi
Veya DBCC SHRINKFILE komutu aracılığıyla Transaction Log dosyası mümkün olduğunca sıkıştırılır. Transaction Log içerisinde ne kadar boş alan olduğunu DBCC SQLPERF(LOGSPACE) komutuyla öğrenebiliriz.

Backup / Restore / Index Reorganize İşlemi Ne kadar Sürecek

Geçen gün virtual device üzerinden restore işlemi yaparken bu işlemin tahminen ne kadar süreceğini öğrenmek istedim. Veritabanı RESTORING modunda görünüyor ancak bu işlemi yapan Agent network üzerinden çalıştığın için hiçbir yerde percent değeri yazmıyord.
Konuyu biraz araştırınca sys.dm_exec_requests isimli DMV’deki percent_complete kolonunun Backup / Restore / Index Reorganize işlemleri için yüklendiğini öğrendim.

SELECT  command,
        session_id,
        percent_complete,
        DATEADD(ms, estimated_completion_time, GETDATE()) AS estimated_completion_time,
        start_time
FROM    master.sys.dm_exec_requests
WHERE   percent_complete > 0

Bu sorguda işlemin ne zaman başladığı, ne kadarının tamamlandığı ve tahmini ne zaman biteceğini döndürmektedir. Eğer o esnadan birden fazla işlem varsa aşağıdaki script aracılığıyla sadece BACKUP / RESTORE işlemi sorgulanabilir.

SELECT command, s.text, start_time,percent_complete,
CAST(((DATEDIFF(s,start_time,GetDate()))/3600) as varchar) + ' hour(s), '
+ CAST((DATEDIFF(s,start_time,GetDate())%3600)/60 as varchar) + 'min, '
+ CAST((DATEDIFF(s,start_time,GetDate())%60) as varchar) + ' sec' as running_time,
CAST((estimated_completion_time/3600000) as varchar) + ' hour(s), '
+ CAST((estimated_completion_time %3600000)/60000 as varchar) + 'min, '
+ CAST((estimated_completion_time %60000)/1000 as varchar) + ' sec' as est_time_to_go,
dateadd(second,estimated_completion_time/1000, getdate()) as est_completion_time
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) s
WHERE r.command in ('RESTORE DATABASE', 'BACKUP DATABASE', 'RESTORE LOG', 'BACKUP LOG')

SQL Server Change Data Capture (CDC) Nedir?

Kritik verilerin bulunduğu veritabanı uygulamalarında en önemli ihtiyaçlardan biri de kullanıcının yaptığı değişikliklerin kayıt altına alınıyor olmasıdır. Bu amaçla ilgili tablolara ait bir log/tarihçe tablosu oluşturulup değişiklikler bu tabloya yazılır. Bunun için ya veritabanı içerisinde ilgili tablolar üzerinde trigger oluşturulur veya uygulama içerisinde değişiklikler uygulanmadan önce değişiklikler tarihçe / arşiv tablolarına aktarılır.
SQL Server 2008 ile sunulan Change Data Capture (CDC) özelliği tablo üzerinde gerçekleşen INSERT, DELETE, UPDATE faaliyetlerinin doğrudan SQL Server tarafından izlenmesini ve kayıt altına alınmasını sağlar. Bu özelliğin en önemli anvantajı doğrudan log altyapısını kullandığı için bizim oluşturacağımız algoritmalara göre daha performanslı olmasıdır. Ayrıca tüm satırı değil sadece değişikliğin yapıldığı kolonları alması da ergonomik bir yapı sağlamaktadır.
MSDN’den alınmış aşağıdaki illustration CDC’nin temel çalışma akışını göstermektedir.

Okumaya devam et

Resource Database Nedir ?

SQL Server 2005 ile birlikte Resource isimli sistem veritabanı geldi. Salt-Okunur ve gizli olan bu veritabanı “sys” şeması altında bulunan tüm sistem nesnelerini içerir. Kullanıcı veri veya şemasıyla ilgili herhangi bir bilgi içermez. Bu veritabanın amacı upgrade işlemlerini hızlı yapılmasını sağlamaktır.
Resource veritabanının dosyaları mssqlsystemresource.mdf ve mssqlsystemresource.ldf olarak isimlendirilmiştir. Bu dosyalar “:\Program Files\Microsoft SQL Server\MSSQL10_50.\MSSQL\Binn\” altında bulunmaktadır.
SQL Server üzerindeki Resource veritabanını versiyonu ve en sonki upgrade bilgisini görmek için sunucuya ait aşağıdaki özellikler okunur.

SELECT SERVERPROPERTY('RESOURCEVERSION')
GO
SELECT SERVERPROPERTY('RESOURCELASTUPDATEDATETIME')

Gerekli durumda bu database’e ait dosyaları taşımak için SQL Server servisini -F parametresi T3608 trace flag koduyla başlatmak gerekir. Single User modunda iken “ALTER DATABASE” komutlarıyla sözkonusu mdf ve ldf dosyalarını kolayca taşıyabiliriz.

ALTER DATABASE mssqlsystemresource MODIFY FILE (NAME=data, FILENAME= 'C:\mssqlsystemresource.mdf')
ALTER DATABASE mssqlsystemresource MODIFY FILE (NAME=log, FILENAME= 'C:\mssqlsystemresource.ldf')