Data Page, Extent, GAM, SGAM, IAM, PFS (SQL Server Mimarisi – II)

SQL Server veritabanı mimarisi ile ilgili önceki yazıda SQL Server’in bağlantı sağlama, sorgu çalıştırma ve kaynak yönetme motorlarından bahsetmiştik. Bu yazıda fiziksel ve mantıksal mimarinin temel bileşenleri olan aşağıdaki kavramları detaylandırıyor olacağız.
Page
Extent
Database File
Database File Group
Data Page, Extent, GAM, SGAM, IAM

SQL Server üzerinde oluşturduğumuz her veritabanına ait veri dosyası (data file) ve günlük dosyası (log file) bulunur. Bu dosyalar birden fazla olabilir. Veri dosyalarının uzantısı genellikle .mdf (Primary data files) veya .ndf (Secondary data files) olur, log dosyalarının uzantısı da .ldf olarak belirlenmiştir. Ancak bu uzantılar çok önem arz etmemektedir. Veriler fiziksel olarak data file’da tutulur, o veriler üzerinde yapılmış işlemlere ait sorgular da log file’da kayıt altına alınır. SQL Server’de database’lere ait fiziksel dosya isim ve konumları master database ‘de kayıt edilir. Aşağıda gösterildiği bir veritabanını en basit haliyle oluştururken bu veritabanına ait fiziksel dosyaları da konumlarıyla birlikte belirtiriz.

CREATE DATABASE [AdventureWorks]
 CONTAINMENT = NONE
 ON  PRIMARY 
( NAME = N'AdventureWorks_Data', FILENAME = N'C:\AdventureWorks_Data.mdf' )
 LOG ON 
( NAME = N'AdventureWorks_Log', FILENAME = N'C:\AdventureWorks_Log.ldf' )

Data File ve database object’leri kolay yönetim için Database Filegroup’ların içerisinde gruplandırılabilir. Sistem nesneleri ve primary data file Primary Filegroup’ta tutulur.

Data file fiziksel olarak “Page” denilen birimlere bölünmüştür. Page, SQL Server’in temel depolama birimi olup büyüklüğü 8KB’dir (8192 byte). Yani SQL Server her 1MB data için 128 adet page içerir. Disk I/O (okuma, yazma) işlemleri page seviyesinde gerçekleştirilir. Log dosyasında Page bulunmamaktadır.

Önceki paragrafta bahsettiğimiz Data File’lar SQL Server tarafından ardışık olarak numaralandırılır. Her page bulunduğu dosya numarası ve kendi numarasıyla (Database ID : File ID : Page Number) tanımlanır. Aşağıdaki örnek 4MB’lık Primary Data File ve 1MB’lık Secondary Data File’a sahip bir veritabanındaki sayfa numalarını gösteriyor.

Her file’ın içindeki ilk page, file ile ilgili attribute bilgisini içeriyor olup “File Header Page” olarak tanımlanır.

8 adet Page’in oluşturduğu gruba Extent denilir. Her extent 64 KB büyüklüğüne sahiptir. MDF içerisinde nesneleri yer ayırma, boş alan yönetimi, shrink için extent’ler kullanılır. Eğer bir extent içerisinde sadece 1 tabloya ait veri varsa buna Uniform (Dedicated) Extent, eğer başka tabloya da ait veri varsa buna da Mixed Extent denilir. SQL Server yeni bir table veya index oluşturulacağı zaman yani yeni bir allocation ihtiyacı olduğu zaman sadece o objeye bir extent tahsis etmek yerine mixed extent’den yer ayrırır. Zamanla o table veya index, 8 page’i aşacak kadar büyürse o nesne için bir sonraki allocationda uniform extent kullanılır. Önemli olan o nesne için 8 page’in yetiyor olmasıdır. Eğer o anda uygun yani boş yeri olmayan bir mixed extent varsa yeni bir extent oluşturulur; mixed olarak işaretlenir ve ona göre SGAM sayfaları güncellenir. Buradaki amaç her küçük tablo için yeni extent oluşturmaktan kaçınılmasıdır. Örneğin en az 8 sayfayı aşan bir tablo üzerinde bir index rebuild edileceği zaman index data için bir uniform extent atanır.

Her page, 96-byte’lık başlık (header) alanıyla başlar. Bu alan, sayfa numarası, sayfa türü, sayfadaki boş alan, ayrıma birimi numarası (page number, page type, the allocation unit ID) ve önceki ve sonraki sayfa (index page ise – next and previous pages) gibi o sayfadaki sistem bilgilerini içerir. Bu header alanı ayrıca bir Page Corruption durumunda o sayfanın bellekten diske doğru yazılıp yazılmadığıno kontrol etmek (Torn Page Detection / Page Checksum) için de kullanılır. Header alanının altında veri satırları (data row / row section) bulunur.

MSDN’den alınmış olan aşağıdaki görüntüde data page’in yapısı gösterilmektedir.

Bir page, en fazla 8060 byte ‘lık veri içerebilir. Kaç satır olacağı satırların büyüklüğüne bağlıdır. Bir page doluyken yeni kayıt geldiği zaman yeni bir page oluşturulur. Tabiki page içerisindeki row ‘ların uzunluğu görüntüdeki gibi sabit ve aynı olmayabilir. Her row farklı uzunlukta olup page’in herhangi bir yerinde olabilir. Örneğin INT (4byte) ve CHAR(100) türünde iki kolonlu bir tabloya yeni bir kayıt eklendiğinde o satırın uzunluğu 108byte olur. Peki SQL Server bir data row’un nerede başlayıp nerede bittiğini nasıl biliyor? Her row’un sahip olduğu 2 byte’lık bir row offset bulunur. Bu offset alanı data row’un ilk byte’ını saklar yani o satırın sayfanın başına olan uzaklığını nerden başladığını belirtir. Row’lar ait offset’ler görüntüde görüldüğü gibi Page’in en alt kısmında bulunmaktadır. Offset listesi 36 byte’lıktır.

Bu büyüklükler aşağıdaki gibi formül ile gösterilebilir.

Page (8 KB/8192 byte) = Page header (96 byte) + Veri Satırları (büyüklüğü herneyse) + Row offset (her row için 2 byte).

Buradaki mantık bir page içerisine daha fazla row kaydedebilmektir. Bu nedenle mümkün olduğunca doğru veri tiplerini (data types) tercih etmeliyiz.

Örneğin aşağıdaki gibi bir tablo oluşturmaya çalıştığımızda hata mesajı alırız.

CREATE TABLE Deneme(
	C1 CHAR(8000),
	C2 CHAR(54)
)

Msg 1701, Level 16, State 1, Line 44
Creating or altering table ‘Deneme’ failed because the minimum row size would be 8061, including 7 bytes of internal overhead. This exceeds the maximum allowable table row size of 8060 bytes.

SQL Server tarafında kullanım amacına bağlı olarak birçok farklı sayfa türü bulunmaktadır. Genel olarak System Pages (Store Engine tarafından verileri yönetmek için kullanılan sayfalar) ve Data & Index Pages (Kullanıcının oluşturduğu tablo ve index leri tutarlar) olarak sınıflandırılabilir. Örneğin kullanıcının girdiği dataları saklamak için Data Page kullanılırken sistem konfigürasyonu dataları ise IAM Page, Index Page gibi sayfa türlerinde tutulur. Şimdi bunların bir kısmını paylaşalım.

Sayfa Türü Açıklama
Data Page Ana ham verilerin bulunduğu sayfalardır. text, ntext, image, nvarchar(max), varchar(max), varbinary(max) ve xml türündeki veriler bu sayfada tutulmaz.
Index Page Index verilerini içerir.
Text/Image text, ntext, image, nvarchar(max), varchar(max), varbinary(max) ve xml gibi large object türlerini içerir. Ayrıca 8KB’dan büyük varchar, nvarchar, varbinary ve sql_variant türlerini de içerir.
File Header Page Önceki paragraflarda belirtildiği gibi Data File içerisindeki ilk sayfa olup o file hakkındaki bilgileri içerir.
Global Allocation Map (GAM)
Shared Global Allocation Map (SGAM)
Index Allocation Map (IAM)
SQL Server bu sayfaların extent’lerin allocation (kullanım) durumlarını izlemek için kullanılır. Her bir sayfa 64000 extent ‘i (yaklaşık 4GB) track eder (adresler) yani onlara ait metadatayı içerir. Track işlemini bit değeri olarak saklar. Bu nedenle bu sayfalara bitmaps page denilir. Data File’in 4GB’yı geçtiği durumlarda bu sayfalardan birer tane daha oluşturulur. 7GB’lık bir data file’da 2 tane GAM Page bulunur.
GAM’de ilgili bit’in “1” göstermesi extent’in free (boş) olduğunu “0” göstermesi allocated (başka bir veritabanı nesnesinin kullanımına tahsis) edildiğini belirtir.
SGAM ise bu extent’in mixed extent olup olmadığını ve boş sayfa olup olmadığını belirtir. Flag bit’in “1” olması mixed extent olduğunu ve boş sayfalara sahip olduğunu, “0” olması ise extent mixed olarak kullanılmadığını veya mixed extent olarak kullanılıyor fakat boş sayfa olmadığını belirtir.
IAM ise extent’in bir tablo veya index tarafından kullanıldığı bilgisini belirtir. Yani bir tablo ve index’e hangi extent veya page’in ait olduğunu tutar. Her table ve index en az bir IAM Page’a sahiptir.

GAM ve SGAM sayfalarındaki sözkonusu bit’in olası değerleri aşağıdaki tabloda gösterilmiştir.

Yani GAM ve SGAM page’leri Database Engine’e extent yönetimi için yardımcı olur. Bir extent’i allocate etmek için GAM=1 olan extent aranılır onu “0” olarak set eder. Eğer o extent mixed olarak işaretleniyorsa ilgili SGAM biti “1” olarak güncellenir. Eğer o extent uniform extent olarak işaretleniyorsa ilgili SGAM bitinde herhanbir güncelleme yapılmasına ihtiyaç duyulmaz. İçinde boş sayfa bulunan bir mixed extent’i aramak için SGAM=1 filtresi kullanılır. Bir extent’in serbest bırakılması (deallocate an extent) durumunda GAM=1 ve SGAM=0 olarak set edilir.

Page Free Space (PFS) Bir extent içerisindeki sayfaların boş alan miktarını tutarak hangi sayfaların dolu hangisinin boş olduğunu belirtir. Dolayısıyla yeni bir kayıt geldiği zaman Database Engine, PFS’yi sorgulayarak sorgulayarak yeni bir sayfa ihtiyacının olup olmadığına karar verir. Bir PSF sayfası, yaklaşık 8.088 sayfayı (yaklaşık 64MB data) kapsar, onların bilgisini tutar. PSF sayfası, data file içerisinde File Header Page’dan sonra yer alır (page number 1).
Index Allocation Map
Bulk Changed Map (BCM) Son BACKUP LOG’dan sonrası bulk copy işlemleri (BULK INSERT, CREATE INDEX, SELECT INTO, BCP …) sonucu değiştirilmiş Extent lerin bilgisini tutar. Extent değiştiği zaman ilgili bit=1 olarak güncellenir. Bu sayfalar ancak o database, bulk-logged recovery model olarak işaretlendiği zaman anlamlı olur. Simple recovery model veya full recovery model durumlarında kullanılmaz. Çünkü simple modunda bulk logged operasyonları loglanmaz. Full modunda ise bulk logged işlemleri, full loglama sürecinin bir parçası olarak gerçekleşir.
Differential Changed Map (DCM) En son Full veya Differential Backup işleminden sonra değişmiş extent bilgisini tutar. O extent için bit=1 ise en son BACKUP DATABASE ifadesinden değiştiğini belirtir. bit=0 olması onu değişmediğini bildirir. Böylece sonraki Differential backup işleminde doğrudan DCM sayfalarına bakarak hangi extent’lerin değiştiğine karar verir ve daha az page taramış olur. BCM ve DCM sayfaları, GAM-SGAM sonrasında konumlanmıştır.

Bir veritabına ait Extent, Page ile ilgili bilgi almak için bugüne kadar DBCC EXTENTINFO, DBCC IND ve DBCC PAGE isimli undocumented command’lar kullanılıyordu. Ama SQL Server 2012 itibariyle bu ve daha fazla detayı artık DMV’lerden (Dynamic Management Function) alıyor olacağız. sys.dm_db_database_page_allocations() isimli DMV, aşağıdaki parametreleri alarak table, index ve partition için ayrılmış olan extent ve page hakkında bilgi döndürür.

sys.dm_db_database_page_allocations(@DatabaseId , @TableId , @IndexId , @PartionID , @Mode)

DBCC IND
(
[‘database name’|database id], — the database to use
table name, — the table name to list results
index id, — an index_id from sys.indexes; -1 shows all indexes and IAMs, -2 just show IAMs
)

databaseId – database id [not null]
tableId – object id veya NULL
indexId – index id veya NULL
partitionId – partition id veya NULL
Mode – LIMITED veya DETAILED

Şimdi yazdıklarımızı bir örnek üzerinde uygulayalım. Aşağıdaki gibi BLOG isimli veri tabanı üzerinde MUSTERI isimli bir table oluşturup içerisine 2 kayıt ekledim.

CREATE TABLE MUSTERI(MusteriId INT, AdSoyad CHAR(50), Sehir CHAR(20))
INSERT MUSTERI VALUES(1,'Ahmet Kaymaz','İstanbul')
INSERT MUSTERI VALUES(2,'Ali','Adana')

Şimdi bu tablodaki extent ve page durumunu inceleyelim. Aşağıdaki şekilde hem DMV hem de DBCC komutuyla tablonun bağlı olduğu page’leri listeleyelim.

SELECT
allocated_page_file_id AS PageFID
,allocated_page_page_id AS PagePID
,allocated_page_iam_file_id AS IAMFID
,allocated_page_iam_page_id AS IAMPID
,object_id AS ObjectID
,index_id AS IndexID
,partition_id AS PartitionNumber
,rowset_id AS PartitionID
,allocation_unit_type_desc AS iam_chain_type
,page_type AS PageType
,page_level AS IndexLevel
,next_page_file_id AS NextPageFID
,next_page_page_id AS NextPagePID
,previous_page_file_id AS PrevPageFID
,previous_page_page_id AS PrevPagePID
FROM sys.dm_db_database_page_allocations(DB_ID('BLOG'), OBJECT_ID('MUSTERI'), NULL, NULL, 'DETAILED')
GO
DBCC IND (0,'MUSTERI',1)

Bu tablo için 1 adet IAM Page ve 1 adet DATA Page kullanılmaktadır. Page’leri dump etmek için DBCC PAGE komutu kullanılır.

DBCC PAGE ( {‘dbname’ | dbid}, filenum, pagenum [, printopt={0|1|2|3} ]);Printopt:
0 – print just the page header
1 – page header plus per-row hex dumps and a dump of the page slot array
2 – page header plus whole page hex dump
3 – page header plus detailed per-row interpretation

IAM Page’in header alanını görmek için DBCC PAGE (‘BLOG’, 1, 93, 0); komutunu yazmamız yeterli olacaktır. DBCC PAGE komutu için 3604 nolu trace’i aktifleştirmek gerekiyor. 90 nolu data page’in body kısmına bakalım.

DBCC TRACEON(3604)
GO
DBCC PAGE ('BLOG', 1, 90, 3);
GO
DBCC TRACEOFF(3604)

Tablodaki bir satır 4+50+20=74 byte yer kaplıyor. Her iki satırın uzunluğu 74+7=81byte görünmektedir. Burada +7 byte Row-Overhead bilgisinden kaynaklanmaktadır. Bu bilginin içerisinde record yani ilgili satırla ilgili bilgiler (Record Attributes) bulunur. Bu attribute’ler arasında o satır içerisinde gibi özellikler bulunur. Konuyla ilgili Paul Randal’in Inside the Storage Engine: Anatomy of a record yazısı okunabilir.

DBCC TRACEON(3604)
GO
DBCC PAGE ('BLOG', 1, 90, 1);
GO
DBCC TRACEOFF(3604)

DBCC PAGE komutunun üçüncü parametresini “1” girip page’deki offset dizisine bakalım.

Son olarak “0” parametresini girip sadece Header bölümüne göz atalım.

Header alanındaki m_type alanı Page Type’i belirtir. (1:Data Page, 2:Index Page, 8:GAM Page, 9:SGAM Page, 10:IAM Page …)
m_slotCnt alanı page’daki kayıt sayısını belirtir. Header alanına baktığımızda data page içerisinde 7930 byte boş alan (m_freeCnt) olduğunu belirtmektedir. Bu hesabı kendimiz yapalım;

(8*1024)- 96-(2 * 74)-(2*7)-(2*2) = 7930

  • 8*1024 = Bir Page’deki toplam byte
  • 96 = Page Header büyüklüğü
  • 2*74 = INT+CHAR(50)+CHAR(20) satır uzunluğu * 2 kayıt
  • 2*7 = Kayıt Sayısı * row overhead
  • 2*2 = Kayıt Sayısı * Row-Offset büyüklüğü

Şu ana kadar 2 kayıt girildiği için bu tabloya 1 page’a (8KB) çok rahat sığabilmektedir. Çok eski bir prosedür olan sp_spaceused aracılığıyla tablonun büyüklüğüne baktığımızda datanın 8KB’lık yer kapladığını görürüz.

reserved alanında +8KB olması IAM index page’den kaynaklanmaktadır. Tablonun mixed mi yoksa uniform extent ‘ten geldiğini görmek için de DBCC EXTENTINFO komutunu kullanacağız. Bu komut, veritabanı adı, tablo adı ve index adı olmak üzere 3 parametre alır. Üçüncü parametreye -1 yazılması tablo üzerindeki tüm indexlerin bilgisini döndürür. Bu komut her allocation için bir satır döndürür. O obje için ext_size=1 olması o objenin mixed extent’ten geldiğini ext_size=8 olması uniform extent’ten geldiğinin belirtir.

DBCC TRACEON(3604)
GO
DBCC EXTENTINFO ('BLOG','MUSTERI')
GO
DBCC TRACEOFF(3604)

Bu tablo için şu anda ext_size=1 görünüyor yani bu tablo mixed extent’ten geliyor. Şimdi bir extenti kısa sürede dolduracak bir tablo oluşturalım. Yani bir kaydı 8K’ya yakın olması için yüksek büyüklükte tip tanımlamış olacağız. Aşağıdaki tabloda her satır 8000 byte yer kaplıyor. İlk başlarda hep mixed extent tarafına yazıyor olacak.

CREATE TABLE ExtentOrnek(
	C1 CHAR(7000),
	C2 CHAR(1000)
)

INSERT ExtentOrnek VALUES('ABC','XYZ')
GO 10

Fakat 9.kayıttan sonra 8*8K’yı aşıyor olacak. Bu durumda Database Engine, bu yeni page için uniform extent allocate edecek. Yani ext_size=8 olacak.

DBCC TRACEON(3604)
GO
DBCC EXTENTINFO ('BLOG','ExtentOrnek')
GO
DBCC TRACEOFF(3604)

8 page dolduktan sonra 232 nolu yeni bir page oluşturulmuş ve bunun uniform extent’ten gelmesi sağlanmıştır. Yani bu extent içerisinde tüm page’ler bu tabloya ayrılmıştır. pg_alloc =2 alanı bu extent içerisinde sadece 2 page’in kullanıldığını gösteriyor. Eğer kayıt eklemeye devam edersek dolu page sayısı artmış olur. Hangi extent ve page’lerin allocate edilip edilmeyeceğine GAM ve SGAM page’i sorgulayarak öğrenir.

EXTENTINFO komutu sadece IAM Page’i (bu örnek için PageId=145) göstermiyor. Şimdi 8 page’in detayını listeleyelim.

SELECT allocated_page_page_id "Sayfa No",extent_page_id "Extent İlk Sayfası", allocated_page_iam_page_id,
is_allocated,is_mixed_page_allocation,page_type,page_type_desc
FROM sys.dm_db_database_page_allocations(DB_ID('BLOG'), OBJECT_ID('ExtentOrnek'), NULL, NULL, 'DETAILED')

Bu sorgunun sonucunda hem IAM Page hem de Page’lerin allocation bilgisi gelmiş oldu. Extent’ler o extent’i başlatan ilk Data Page üzerinden takip edilir. Hangi sayfanın hangi extent’ten geldiğini o extent’in ilk sayfası yani bu DMV’nin döndürdüğü extent_page_id alanı üzerinden takip edeceğiz. Örneğin bu örnek için 232-239 aralığındaki sayfalar 232 ile başlamış olan extent içerisinde bulunuyor. Bu uniform extent (8 sayfa olduğu için) içerisinde sadece 2 sayfa dolu kullanılıyor. 156 nolu sayfa, ilk sayfası=152 olan extent içerisinde bulunuyor. 152 nolu sayfa bu tabloya ait değil aşağıdaki kod ile bu sayfanın kime ait olduğuna baktığımızda başka bir objenin olduğunu görürüz. Yani o mixed extent içerisinden farklı database object var. Aslında bir tablo için ardışık giden sayfaların aynı extent’in geldiğini söyleyebiliriz. Yukarıdaki şekilde 232-239 aralığındaki sayfalar aynı extent’ten (single extent) geliyor.

SELECT OBJECT_NAME(object_id) FROM sys.dm_db_database_page_allocations(DB_ID('BLOG'), NULL, NULL, NULL, 'DETAILED')
WHERE allocated_page_page_id=152

Tablonun büyüklüğünü tahmin edelim. Tabloya ait 1 adet IAM Page, 10 adet Data Page ve 6 adet kullanılmayan Page var. 17x8KB=136KB rezerve edilmiştir. Data için de 10x8KB=80KB ayrılmıştır. 6x8KB=48KB da kullanılmayan page mevcut. Bu rakamların doğruluğunu kontrol etmek için EXEC sp_spaceused ExtentOrnek, @updateusage = true sorgusunu çalıştırdığımızda aşağıdaki sonucu elde etmiş oluruz.

Bir nesnenye ait IAM Page’i bulmak için sys.system_internals_allocation_units isimli DMV kullanılabilir. Aşağıdaki JOIN sorgusu bize “(1:145:0)” değerini döndürüyor olacak. Bu tablo için birden fazla IAM Page olsaydı onlar da listelenmiş olurdu.

select sys.fn_PhysLocFormatter(first_iam_page) from sys.system_internals_allocation_units sau
JOIN sys.partitions pt on sau.container_id = pt.partition_id and pt.object_id = object_id('ExtentOrnek')

BLOG isimli bir veri tabanı için GAM ve SGAM sayfalarını da DUMP edip yorumlayalım.

DBCC TRACEON(3604)
GO
--GAM (1:2)
DBCC PAGE ('BLOG', 1, 2, 3);
GO
DBCC TRACEOFF(3604)

Buradaki ilk satır şunu anlatıyor; 0 ve 208 aralığındaki Page’ler ile başlayan extent’lerin allocate edilmiştir. 0-215 arasındaki sayfalar bu extent’lerin içerisinde bulunmaktadır. İkinci satır, Sayfa Numara=216 ile başlayan extent’in allocated edilmediğini göstermektedir. 212 ve 216 sayfaları için DBCC PAGE komutunu çalıştıralım.

DBCC PAGE('BLOG',1,212,1)
DBCC PAGE('BLOG',1,216,1)

DBCC TRACEON(3604)
GO
--SGAM (1:3)
DBCC PAGE ('BLOG', 1, 3, 3);
GO
DBCC TRACEOFF(3604)

İlk satır, 0 – 112 aralığındaki sayfalarla başlayan extent’lerin allocate edilmediğini belirtmektedir. Yani ya bu aralıktaki extent’lerin hepsi allocate edilmemiş uniform extent veya boş yeri olmayan mixed extent’dir. İkinci satır’daki 120 ile başlayan extent, mixed extent olup en az bir boş sayfası vardır.

Son olarak fragmention analizi için kullandığımız DBCC SHOWCONTIG komutu veya sys.dm_db_index_physical_stats DMV aracılığıyla da bir tablonun Page, Row, Extent sayılarını öğrenebiliriz.

DBCC SHOWCONTIG ('ExtentOrnek') WITH TABLERESULTS
--Veya
SELECT * FROM sys.dm_db_index_physical_stats (DB_ID(N'BLOG'), OBJECT_ID(N'ExtentOrnek'), NULL, NULL , 'DETAILED')

Konuyu aşağıdaki maddelerde özetleyelim;

  • MDF, NDF yani data file’lar her biri 8KB olan Page isimli mantıksal birimlerden oluşur. 8 adet bitişik Page’in oluşturduğu gruba extent (64KB)denilir.
  • Bir table veya index oluşturulacağı zaman öncelikle uygun bir extent bulunarak veya oluşturularak datayı fiziksel olarak saklayacak bir Page oluşturulur.
  • MDF içerisinde fazla parçalanma olmaması için 8x8KB büyüklüğünde olmayan bir tablo oluşturulduğu zaman öncelikle mixed extent içerisine alınır. Ardından büyüme durumuna göre uniform extent tercih edilir.
  • SQL Server’de bir satırda (data row) en fazla 8060 byte saklanır. Daha fazlası için In-Row Data, Row-Overflow Data birimleri kullanılır. Bu kavramları sonraki makalelerde yazıyor olacağım.
  • Sayfa sıralaması aşağıdaki gibidir;
    Page 0 : File Header
    Page 1 : Page Free Space (PFS)
    Page 2 : Global Allocation Map (GAM)
    Page 3 : Shared Global Allocation Map (SGAM)
    Page 6 : Differential Changed Map (DCM)
    Page 7 : Bulk Changed Map (BCM)
  • GAM ve SGAM sayfaları extent’lerin allocate bilgisini ve türünü belirtir.
  • Bir veri tabanının extent page listesini görmek için DBCC EXTENTINFO, herhangi bir page’i dump etmek için de DBCC PAGE komutu kullanılır. Bu komutların çalışabilmesi için DBCC TRACEON(3604) komutuyla 3604 trace flag’in açılması gerekir.
  • Bir database’in extent sayısını öğrenmek için DBCC SHOWFILESTATS kullanılır. Bu komut File Group bazında ayrılmış ve kullanılan extent sayısını listeler.
  • Bir database’i shrinki yapmak için DBCC SHRINKDATABASE() çalıştırılır. Komut çalıştıktan sonra mevut page sayısı bilgisini listeler.

SQL Server mimarisi konulu bu seride aşağıdaki konuları detaylandırmaya çalışıyorum.

SQL Server’in mimarisi nasıldır?
SQL Server veri tabanı mimarisi, disk yönetim mimarisi?
SQL Server, verileri nasıl saklar, kayıt eder?
Sql Server storage architecture, storage engine, storage internals
Page, Extent, Allocation Unit, IAM Page, PFS, GAM, SGAM Pages, Row Offset Nedir?
SQL Server bellek yönetimi, memory management
SQL Server işlemci yönetimi, CPU management
SQL Server disk space, disk usage
Sql Server IO performance

Data Page, Extent, GAM, SGAM, IAM, PFS (SQL Server Mimarisi – II)” hakkında 3 yorum

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir