SQL Server 2008 Filestream

  Ms Sql server 2008 ile gelen yeni özelliklerden birisi de Filestream özelliği.Öncesin de DataBase üzerinde BLOB tipinde binary datalar tutardık.Filestream de datalar NTFS disk sisteminde dosyalarda tutuluyor.Yani DataBase üzerinde değil. Fakat verilere, DataBase engine üzerinden ulaşıyoruz. Artık Ses dosylarını ,Resim gibi verileri tutmak için FileStrem yapısını kullanabiliriz. Şimdi bir örnek ile daha ayrıntılı inceleyelim...

Öncelikle disk üzerinde FileStrem ve data dosyalarının olacağı yeni dosya yaratalım 
C:\data

Ms SQL server sunucumuzda filestream özelliğini enable edelim
EXEC sp_configure 'filestream_access_level',2
RECONFIGURE
Tabiki bununla yetmiyor, birde configure tools dan enable edilmesi gerekiyor. 


Start menu / All Programs /Microsoft SQL Server 2008/ Configuration Tools/ SQL Server Configuration Manager.  Sağ click  SQL Server Services properties / click FILESTREAM tab  /enable FILESTREAM.

Eğer yazma ve okuma işlemleri olucaksa "FILESTREAM for file I/O streaming access" bölümünü de anable yapılmalı







  












Yeni bir DB yaratalım


CREATE DATABASE DOSYA
ON
PRIMARY ( NAME=DOSYA,FILENAME='c:\data\DOSYA.mdf'),
FILEGROUP FileStreamGroup1 CONTAINS FILESTREAM( NAME=DOSYA3,FILENAME='c:\data\filestream1')
LOG ON(NAME=DOSYA1,FILENAME='c:\data\DOSYA.ldf')
GO


Dosyalarımızı bir kontrol edelim.













C:\data altına yeni bir filestream dosyası yarattı










Şimdi yeni bir tablo yaratalım.


Not:  Filestream içeren tabloda [uniqueidentifier] alan kullanılması zorunludur. Filestream column veritipi VARBINARY(MAX) FILESTREAM 


use DOSYA

GO
CREATE TABLE Döküman
(
[Id] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE,
[SerialNumber] INTEGER UNIQUE,
[Chart] VARBINARY(MAX) FILESTREAM NULL
)
GO


  Tablonun özelliğine baktığımızda Filestream filegroup olarak yeni yarattımız Filestream filegroup1 üzerine konumlanmıştır.









 Böylelikle Filestream özelliğinden yararlanarak yeni bir tablo yaratmış olduk. Küçük bir örnek yapıcak olursak  şu şekilde bir kayıt insert edelim.Bu instert verileri içeren bir dosya nasıl oluşturulur bize gösteriyor. 

INSERT INTO Döküman

VALUES (newid (), 1, CAST ('ilker usta pusulanı ayarla' as varbinary(max)));
GO

  Şimdi gidip fileStream FileGroup incelersek buraya binary dataların oluştuğunu ve disk üzerindeki dosyalarda tutulduğunu görebiliriz.









  Bu dosyaları notepad ile açarsanız içerisinde insert edilen bilgileri görebilirsiniz. ( kontrol ettiğimde son insert ettiğim bu metni görüyorum 'ilker usta pusulanı ayarla'
  Şimdilik kolay gelsin J




Lock Request time out period exceeded Error 1222










   Bu hatayı, SSMS açmaya çalışırken (Tabloları,sp,view vs. görüntülemek adına) zaman zaman karşımıza çıkabilir. Sebebi ise o anda sistemi kilitleyen ciddi olabilecek bir işin çalışması yada açık transaction bırakıp lock koyması olabilir.
   Bunun için şu dmv ler ile neler oluyor bakabiliriz.

select distinct object_name(a.rsc_objid),a.req_spid,b.loginame
from sys.syslockinfo a (nolock) join sys.sysprocesses b (nolock) 
on a.req_spid=b.spid
where object_name(a.rsc_objid) is not null

   Bu query hangi tablo lock almış, proccesID ve LoginName, neyi tutuyor bunu görebiliriz.Daha sonra doğru proccesi bulup kill edersek sorunu çözmüş oluruz. 



Error Msg 3117 The log or differential backup cannot be restored

   Merhaba bu hatayı herhangi bir backup dan restore etmeye çalışırken almış olabilirsiniz. Ben log backup dan restore yapmaya çalışırken aldım. 
   Restore etmeye çalıştığım db FULL RECOVERY ben bunu NORECOVERY çevirmek istediğimde hiç sevmediğim kırmızı çıktı J

Error : Msg 3117, Level 16, State 4 The log or differential backup cannot be restored because no files are ready to rollforward

   Bunun için  fix/workaround solutions olarak full yada diff hangi backup elimizde ise bundan NORECOVERY  modelde restore dönmeliyiz.  

Dolu tablonun partitioning yapılması

   Merhaba , Table Partitioning yapısını daha önce anlatmıştım. Peki ya Dolu olan tablomu nasıl partition yapıya geçirebilirim ?
    Bu hangi koşullarda karşımıza çıkar derseniz örneğin milyonlarca kayıt olan bir tabloyu arşivlemem gerekiyor, ve belirli tarihten öncesini silmek zorundayım. Bu oldukça sıkıntılı bir iştir.Tablo'da lock olma ihtimalinden, çok fazla io yapmaya kadar uzanan bir çile..
   Eğer benim partition bir tablom olsaydı silinmek istenen tarih aralığını arşivdeki tablo'ya switch edip bu dertden kurtulabilirdim.
   Kısa bir örnek ile neler yapabildiğimize bakalım. Öncelikle yeni bir tablo yaratıyorum.


Create Table members
( id int,
  name char(20),
  surname char(20),
  startDate smalldatetime
)

Boş olan tabloya biraz data girelim.

Declare @x int

Declare @id int
  set @x=0
  set @id=1
 while @x < 100
 begin
  insert into members values (@id,'ilker','usta','20110101')
  set @x=@x+1
  set @id=@id+1
 end

Bakalım ne kadar yerimiz oldu

sp_spaceused 'members'






Şimdi tablomuzun özelliğine bakalım



















   Gördüğümüz gibi tablo PRIMARY yani default file gurup üzerinde yaratıldı. Şimdi gelelim asıl sorunumuza. Tablomuzda herhangi bir index yok. (olsada birşey değişmez) tabloya partition scheme üzerinde yeni bir index yaratırsak tablo primary den çıkıp partition yapıya geçmiş olur.
   Not : Kullanılan Partition scheme ve function daha önce yaratılmış type olarak smalldatetime dır. (startDate columundan partitions yapıyoruz.)

CREATE CLUSTERED INDEX [CIX] ON [dbo].[Members]

(
      [id] ASC
)WITH (SORT_IN_TEMPDB = ON, ONLINE = ON)
ON [PS_MONTHLY_RANGE]([startDate])
GO


Şimdi tablomuzun özelliğine yeniden göz atalım














   Gördük ki tablomuz PS_MONTHLY_RANGE üzerine geçti. Artık tablomuza gelecek yeni kayıtlar startDate üzerinden aylık olarak faklı partitionlar da olucaktır......     Kolay gelsin :) 



Table partitioning

   Partitioning table yapısı benim kullanmasını en çok sevdiğim ve faydasına çok inandığım bir özelliktir. MS Sql server 2005 versiyonu ile gelen bu özellik pek çok yapıda kullanılabilir. 
   MS SQL Server Table Partitioning yapısı isminden de anlaşılacağı üzere tabloyu fiziksel olarak parçalamaktır. Buda hem io kullanımı hem disk kapasitesi ,tabloya gelen sorgu performansı bakımından çok önemli faydalar sağlamaktadır. Tablonun bu şekilde belirli tarih yada sınıf bakımından arşivlenmesi oldukça kolaylaştırır.
   Örneğin tablomuza tarihe göre bir sorgu geldiğini düşünelim ve tablomuzun yapısı tarihlere göre partition yapıda,  Sql server sorguyu uygun partitiona götürür ve sorgu bu fiziksel dosyada arar bulur. Buda sorgu performansını ciddi boyutlarda arttırmış olur.

   Şimdi gelin birlikte ufak bir uygulama yaratalım.
   Öncelikle partition function yaratalım ,ben ay ay partition kullanıcam ,bu yıl yıl yada belirlenen sınıflara göre de ayrılmış olabilir.

CREATE PARTITION FUNCTION [PF_MONTHLY_RANGE](smalldatetime) AS RANGE RIGHT FOR VALUES (N'2011-01-01T00:00:00', N'2011-02-01T00:00:00', N'2011-03-01T00:00:00', N'2011-04-01T00:00:00', N'2011-05-01T00:00:00')

  Burda dikkat edilmesi gereken functionun kullanacağı column, Tarih columnu kullanacağımıza göre type smalldatetime verilmelidir. Şimdi sıra functionu kullanacak scheme yı yaratmakda. 
  Tabi bunun öncesinde her ay için yeni bir file gurup yaratıp bunlar için ayrı ayrı data file yaratmak gerekir , yada siz kendi yapınıza göre hepsini primary file gurupta yada herhangi bir file gurupta yaratabilirsiniz.

   Şimdi scheme yaratalım.

CREATE PARTITION SCHEME [PS_MONTHLY_RANGE] AS PARTITION [PF_MONTHLY_RANGE] TO([filegr], [filegr1], [filegr2], [filegr3], [filegr4], [filegr5])



   Dikkat ederseniz function da 2011 ocak dan başladık ve 5 partition numarası vardı. Scheme de ise 6 tane file gurup var, bu şu demek oluyor 2011 ocaktan küçük tarihler filegr dosyasına yazılır.
   Şimdi scheme üzerinde tablomuzu yaratalım.

CREATE TABLE CUS (id int, Tarih smalldatetime ) on PS_MONTHLY_RANGE(Tarih);

   Tablomuzu partition olarak yaratmış bulunuyoruz. Bu tabloya gelecek kayıtlar artık ay bazında farklı fiziksel dosyalara kayıt edilecekler.
   Hangi partition numarasında ne kadar kayıt olduğunu şu sorgudan görebilirsiniz.

select t.name,p.object_id,p.partition_id,p.index_id,p.partition_number,p.rows from sys.partitions p join sys.tables t
on p.object_id=t.object_id WHERE p.partition_number <> 1



   Table partitioning konusunda şimdilik anlatılacaklar bu kadar kolay gelsin :)  





Error 9003 The LSN(42:132:1) passed to log scan in database is invalid


   Bu hatayı database'mi attach ederken aldığım bir hata! Sorun ise .mdf ve .ldf dosyalarının uyuşmaması  diyebiliriz.
   Backup'dan dönülürken de böyle bir hata ile karşımıza çıkabilir. LSN uyuşmazlıkları sorunun kaynağıdır.
çözüm olarak sadece .mdf dosyasını attach edersek problemi aşabiliriz .ldf yeniden kendi oluşturacaktır.

SQL Server Edition Operating System Compatibilty (Warning)

     Kurulum sırasında alınan bu hatanın sebebi operating system ve SQL Server requirements lerin compatibil olmayışından kaynaklıdır.
      Windows xp,wista,7 gibi işletim sistemlerine enterprise edition kurulmak istenirse bu şekilde hata alınabilir. Bunu gidermek içib örneğin Developer,Express  edition kurabilirsiniz.


Temp DB Taşıması

Merhabalar Arkadaşlar , Bu yazımızda yine sistem veri tabanlarından birisi olan TempDB taşınmasından bahsedicez.
Zaman zaman Disk büyümesi ,Daha performanslı disklere geçiş gibi sebeplerden dolayı taşımalar meydana gelebilir. TempDB 'de diğer bir sistem veritabanı olduğu için move edilmesi farklıdır. Master DB taşıması gibi bize strese sokmadan bir iki ALTER komutu ile bunu yapabiliriz..

Adımları
Taşıyacağımız ortam "E" diski altında "SQLDATA" adlı klasör olduğunu farz edelim.
use master
go
Alter database tempdb modify file (name = tempdev, filename = 'E:\SQLDATA\tempdb.mdf')
go
Alter database tempdb modify file (name = templog, filename = 'E:\SQLDATA\templog.ldf')
go
Komutu ile yeni data fileları "E" diski altına yaratmış olduk.

Servis stop-start ile SQL Temp db olarak yeni taşınan yerde yazmaya ve loglamaya başlamış olur.

Kolay gelsin

Master DB Restore ve Master DB Taşınması

Merhaba , bu yazımızda Master veri tabanın taşınması hakkında konuşucağız. Oldukça belalı ve risk içeren bir işlem olması sebebi ile son derece dikkatle yapılması gereken bir işlemdir. Peki neden bu yola ihtiyaç duyabiliriz ? Yeni bir sunucuya geçilmesi yada master db in bulunduğu disklerin değiştirilmesi durumlarında olabilir.
Master veri tabanı SQL sunucumuz'un sistem veritabanı dır. Corrupt yada suspect olması durumunda veritabanı sunucusu açılmaz ve tüm sistemin çökmesine sebep olabilir..
Master veritabanının yeniden restore edilmesi için SQL server sunucumuz'un servislerinin durdurulması gereklidir. bunu da SQL Server Configuration Manager yada Windows services' dan yapabiliriz. Anlatacağım örnek de Primary server' dan Master db backup alıp secondary server olarak kabul ettiğim sunucuya restore yapacağız.

Öncesinde Dikkat edilmesi gereken hususlar
  • Restore yapılacak disklerin aynı harflerde olması önemlidir. Sebebi ise master db açıldık dan sonra temp db için pathlerini arıcak olmasıdır.
  • Yedeklerinin alınması. Önemli bir husus yedek alırken backup değil file taşınması daha doğru olacaktır, hata durumunda backup dan geri dönemeyiz.
Adımları
  • Servisler stop edilir.
  • Temp db path bilgileri ALTER edilir.
  • Single modda servis açılır.
  • Komut satırından gereken dosyaya ulaşıldıkdan sonra komut satırına(sqlservr.exe -m) yazıp devam ediyoruz.




Şimdi Master db geri yüklemesini yapabiliriz. Bunun için şu kodlama kullanılabilir.


RESTORE DATABASE master
FROM DISK = N"C:\m
aster.bak" WITH FILE = 1 GO

Bunu query analyzer dan yapıyoruz.
Yada





(Servicesler start edilir)
· SQL Server"ımızı normal modda tekrar başlatalım. Bu şekilde Master sistem veritabanını geri yüklemiş olduk.
· Master db ile gelen (primary serverdan) db ler suspect gelir.
· SQL Error loglardan hataları kontrol edebiliriz.
· Master db restorundan sonra server ismini rename etmek gerekiyor.
EXEC sp_dropserver 'old_name'
go
EXEC sp_addserver 'new_name', 'local'
Go
(Services ‘ler stop-start edilir)
· Msdb db altında sql server rename etmek gerekiyor.
select * from dbo.sysjobs
altın da
USE msdb
GO
update sysjobs
set origination_server 'new_name' where 'old_name'
(servicesler stop-start edilir)


Ara