Shrink, veritabanı dosyalarının disk üzerinde kapladıkları alanın küçültülmesi için yapılan işlemdir. Shrink işlemini Windowstaki defragmenta benzetebiliriz. İşletim sisteminde herhangi bir disk bölümü üzerindeki dosyalar üzerinde yapılan değişikliker disk üzerinde farklı konumlara yazılır. Dosyalar üzerinde zamanla düzenleme/silme işlemi gerçekleştirdikçe değişikliklerin farklı konumlara yazılması nedeni ile dosyada, dolaylı olarak diskte fragmentation yani parçalanma meydana gelir. Bu parçalanma nedeni ile bir dosya açılırken birçok konuma bakılması gerektiğinden performans kaybı ortaya çıkar. Defragment işleminde, disk üzerindeki veriler yeniden düzenlenerek parçalanmış dosyalar birleştirilir.

Veritabanı dosyalarında da zamanla düzenleme ve silme işlemlerinden kaynaklanan fragmentation benzeri bir durum ortaya çıkar. Shrink işlemi kullanılmayan bu alanların işletim sistemine release edilmesidir. Dosya üzerindeki kullanılmayan alanlar işletim sistemine bırakıldığından dosyanın boyutu küçülür.

Shrink işlemini daha iyi anlayabilmek için SQL Server’ın veriyi nasıl tuttuğuna yakından bakmak gerekir. SQL Server’ın veri deplomasının temelinde sayfalar(pages) vardır. Data dosyaları disk üzerindeki alanı numaralandırarak sayfalara böler. Veritabanında gerçekleştirdiğimiz işlemler yani disk üzerindeki I/O işlemleri bu sayfalar üzerinde gerçekleşir. Her page 8KB’dır. 1MB = 1024KB olduğunu hatırlarsak, bu demek oluyor ki veritabanı her 1MB için 128 sayfaya sahiptir. Her sayfa, sayfa numarası, sayfa tipi, sayfadaki boş alan miktarı ve sayfanın kimliği olan allocated unit ID bilgisini tutan 96 byte’lık bir headera sahiptir. Başlık bilgisindan sonra data rowlar vardır. Sayfanın sonunda ise 36 byte’lık row offsets tablosu vardır. Her data row için row offsets tablosunda sayfanın başından satırın ilk byte’ına kadar olan bölümün kaydı bulunur. Aşağıda bir data page’in yapısı görünmektedir:

SQL Server Data Page
SQL Server Data Page

Bütün sayfalar etkili sayfa yönetimi için extentler halinde tutulur. Extent, ardışık  sekiz sayfadan oluşan bir sayfa koleksiyonudur.  Bir sayfa 8KB olduğundan, her extent 64KB’tır. Veritabanı da her 1MB için 16 extente sahiptir. Data dosyasında, veritabanı nesneleri için yer ayırma ve boş alan yönetimi extentler kullanılarak sağlanır.

Uniform ve mixed olmak üzere iki tür extent vardır. Uniform extentte, extentteki sekiz sayfayı da aynı veritabanı nesnesi kullanır. Mixed extentte ise extentteki sayfalar farklı nesneler tarafından kullanılabilir.

Uniform Extent - Mixed Extent
Uniform Extent – Mixed Extent

64.000 extentten(Yaklaşık 4GB veri demek) oluşan ve herhangi bir nesne için ayrılmış alanların bilgilerini tutan GAM(Global Allocation Map) ve SGAM(Shared Global Allocation Map) haritaları ile data dosyaları üzerinde alan ayırma yönetimi yapılır. GAM, herhangi bir nesne için ayrılmış olan extentlerin kaydını tutar. SGAM ise mixed extent olarak kullanılan extentlerin kaydını tutar.

GAM’ın kapsama aralığında extentlerin kullanımda olup olmadığını anlamak  için her extentte bir bit tutulur. Bu bit 1 ise extent boş, 0 ise extentin herhangi bir veritabanı nesnesi tarafından kullanımda olduğu anlaşılmaktadır.

SGAM’ın kapsama aralığında yine extentlerin kullanılabilir olup olmadığını anlamak için bir bit tutulur. Bu bit 1 ise extent, en az bir kullanılmayan sayfası olan mixed extent, 0 ise extentin  uniform extent olduğu veya mixed extent olup bütün sayfalarının kullanımda olduğu anlaşılır.

GAM ve SGAM  durum bitlerinin değerine göre extentlerin durumu aşağıdaki gibidir:

Extent Durumu

GAM biti

SGAM biti

Boş

1

0

Uniform extent veya boş sayfası olmayan mixed extent

0

0

Boş sayfası olan mixed extent

0

1

Bir veritabanı nesnesi için extentte yer ayrıldıktan sonra Database Engine extentteki hangi sayfaların kullanımda hangi sayfaların boş olduğunu anlamak için PFS(Page Free Space) sayfalarını kullanır. PFS sayfaları, her sayfanın kullanım durumunu ve boş alan miktarını tutar.  Bu bilgi, Database Engine tarafından bir veritabanı nesnesi için yeni bir sayfa ayrılacağı zaman kullanılır. PFS sayfası data file’da header sayfasından sonraki sayfadır. Header sayfasından sonra yaklaşık 8000 PFS sayfası vardır. PFS sayfalarını GAM ve SGAM sayfaları takip eder. Aşağıda data file’ın yapısı görünmektedir:

Data File Yapısı
Data File Yapısı

Database Engine, yazılacak data için yer ayıracağı sayfayı bulmak için PFS sayfaları ile birlikte IAM(Index Allocation Map) sayfalarını kullanır. IAM sayfaları, yer ayırma ünitesi(allocation unit) tarafından kullanılan, database dosyasının 4GB’lık bir bölümündeki extentleri haritalayan sayfalardır.  GAM veya SGAM ile aynı kapsama sahiptir.  Database Engine, allocation unit’in ayıracağı extentleri bulmak için IAM sayfalarını kullanır. Extentte kullanılabilecek sayfa olup olmadığını anlamak için de PFS sayfalarını gözden geçirir.

SQL Server’da data dosyasında nesnelerin nasıl tutulduğuna göz attıktan sonra shrink işlemine geri dönelim.

SQL Server’da, doğrudan veritabanını  veya data/log dosyalarını shrink edebilirsiniz.

Database Shrink:

Shrink yapmak istediğiniz veritabanına sağ tıklayarak Tasks/Shrink/Database’i tıklayarak açılan Shrink Database ekranından veritabanını shrink edebilirsiniz.

Database Shrink
Database Shrink

Currently allocated space alanında data ve log dosyalarının toplam boyutu görüntülenir. Available free space alanında data ve log dosyalarındaki toplam kullanılmayan alan görüntülenir. Maximum free space in files after shrinking bölümünden shrink işleminden sonra dosyada ne kadar boşluk kalacağını yüzde olarak belirleyebilirsiniz. Örnek olarak veritabanımızın data dosyası 100 MB olsun. Dosyada 60MB’da veri olsun. Shrink sonrası data dosyasındaki boş alan miktarını %25 olarak belirttiğimizde, shrink sonrası data dosyasının boyutu yeniden hesaplanır.  Shrink sonrası data dosyasının boyutuna X dersek dosyadaki boş alan miktarı 25X/100 olur. Bu durumda 60MB’lık datamız 75X/100’e tekabül ediyor. Bu eşitliğin çözümünden data dosyamızın shrink sonrasındaki boyutunun 80MB olacağı hesaplanır. 60MB veri ve 20MB(%25) boş  alan.

Shrink işlemi ile veritabanı, ilk oluşturulduğu boyuttan veya shrink file/alter database ile değiştirilen son boyutundan daha küçük yapılamaz.

File Shrink:

Üç farklı şekilde shrink işlemi gerçekleştirilebilir:

1.       Release unused space

Bu seçenekte, data/log dosyasında kullanılmayan alanlar işletim sistemine bırakılır. Herhangi bir sayfa  düzenlemesi olmaz. Doğrudan veritabanını shrink ettiğinizde bu şekilde yapılır.

2.       Reorganize files before releasing unused space

Yukarıdaki seçenekten farklı olarak, kullanılmayan alanlar release edilmeden önce dosya üzerindeki sayfalar düzenlenir. Bu seçeneği seçtiğinizde Shrink to file bölümünden dosyanın kaç megabayt’a kadar küçültülmesini istediğinizi seçebilirsiniz. Data dosyaları minimum 2 MB, log dosyaları minimum 1 MB’a kadar küçültülebilir.  Dosyanın minimum küçültülebilme boyutundan daha yüksek küçültme değeri girdiğinizde, dosya yine  küçültülebileceği minimum değere kadar küçültülür.

3.       Empty file by migrating the data to other files in the same filegroup

Bu seçenek seçildiğinde, seçilen dosyadaki bütün içerik, aynı dosya grubundaki diğer dosyalara taşınır. Bunun için shrink edilecek dosya ile aynı dosya grubunda başka data dosyalarının da olması gerekmektedir. Veritabanına sağ tıklayıp Properties/Files‘a girin. Add butonuna tıklayarak dosya grubuna yeni bir data dosyası ekleyin. Eklenen bu dosya “.ndf” uzantılı Secondary data files dosyasıdır.  Secondary data files dosyaları, çok büyük veritabanlarında datayı, birden fazla diske yayarak query performanslarını artırmak için kullanılır. Aynı dosya grubunda birden fazla secondary data file oluşturulabilir ve data birden fazla disk üzerine yayılabilir.

“.mdf” dosyaları primary data file olduğundan bu seçenekte shrink yapılmaya çalışıldığında non-data içerik secondary data file’lara taşınamadığından aşağıdaki hata alınır:

Cannot move all contents of file “DB NAME” to other places to complete the emptyfile operation. DBCC execution completed. If DBCC printed error messages, contact your system administrator. (Microsoft SQL Server, Error: 2555)

Secondary data file’lara non-data içerik aktarılamamasına rağmen data içeriği aktarıldığından secondary data file’lar da kullanımda olur. Dolaysı ile silmeye çalıştığınızda secondary data file’ın kullanımda olduğuna dair bir hata mesajı alırsınız.  Farklı disklerde konumlandırılan  secondary data file’lar bu seçenek ile shrink edilerek birden fazla data file yapısından tek bir data file yapısına dönüş yapılabilir. Bu seçenek ile shrink edilen secondary data file içeriğini diğer data file’lara aktardığından silinebilir hale gelir. Secondary data file’lar bu şekil shrink-delete işlemi ile silinerek sadece primary data file kalır.

Secondary Data Files
Secondary Data Files

T-SQL İle Shrink

DBCC SHOWFILESTATS  komutu ile veritabanının data dosyasının ayrıntılarını görebilirsiniz.

Data File Bilgileri
Data File Bilgileri

Görüldüğü gibi 10MB bir veritabanı toplamda  10X16 = 160 (1MB = 128 page = 16 extent) extente sahiptir. Kullanılan extent sayısı ise 22.

Bir veritabanı T-SQL ile aşağıdaki şekilde shrink edilebilir:

DBCC SHRINKDATABASE(TEST)

Shrink
Shrink

Burada gördüğünüz değerler page türündendir.  Extent olarak ifade etmek gerekirse CurrentSize = 1280/8  = 160, MinimumSize = 160, UsedPages 168/8 = 21, EstimatedPages 168/8 = 21 extenttir.

SHRINKDATABASE metodunun veritabanı ismi dışında iki parametresi vardır. Birincisi shrink işleminde sonra veritabanında olması istenen boş alan miktarının yüzdesi, ikincisi ise NOTRUNCATE/TRUNCATE değeri. NOTRUNCATE parametresi metoda geçildiğinde,  data dosyaları dosyanın sonundaki ayrılmış sayfalardan dosyanın başındaki ayrılmamış sayfalara taşınır. TRUNCATE parametresi metoda geçildiğinde ise dosyada kullanılmayan alanlar işletim sistemine release edilir. Herhangi bir data taşıması olmaz.

Bir data/log dosyası aşağıdaki T-SQL ile aşağıdaki şekilde shrink edilebilir:

DBCC SHRINKFILE(TEST)

SHRINKFILE metodunun veritabanı ismi dışında üç parametresi vardır; EMPTYFILE, NOTRUNCATE/TRUNCATE, target_size. Buradaki target_size, SHRINKDATABASE’deki gibi shrink sonrası olması istenen boş alan yüzdesi değil veritabanının MB olarak shrink edilmek istenen boyutudur. EMPTYFILE parametresi ise yukarıda shrink file altında belirtilen üçüncü seçenekte shrink işlemini gerçekleştirmek için kullanılır.

Log dosyalarını shrink etmek için veritabanının SIMPLE RECOVERY modunda olması gerekmektedir. Bunun için T-SQL ile log dosyalarını shrink ederken önce veritabanını SIMPLE RECOVERY moduna çekip, sonra shrink edip sonra tekrar FULL RECOVERY moda getirmemiz gerekecektir.

ALTER DATABASE TEST SET RECOVERY SIMPLE
GO
DBCC
SHRINKFILE (TEST_Log, 1)
GO
ALTER DATABASE
TEST SET RECOVERY FULL

Sonraki yazıda görüşürüz…

Reklamlar