SQL SERVER – Page Yapısı

PAGE NEDİR?   Bilgisayarımın karşısına oturdum ve index mantığını anlatmak üzere yazmaya başladım. Ancak farkettim ki herşey page yapısını anlamak ile başlıyor. İşte bu yüzden şuan yazacaklarım SQL ENGINE’ı anlamak ve onun gibi düşünmeye başlamak için bir rehber niteliğinde. Ayrıca bu şekilde bir yazı dizisi yapmayı düşünüyorum. Eğer SQL ENGINE’ı gerçekten anlamak istiyorsanız takipte kalsanız iyi edersiniz. Nasıl maddenin en küçük yapı taşı atom ise SQL SERVER’ın da en küçük yapı taşı pagelerdir. Bir kitapta tüm içerik sayfalara yazıldığı gibi SQL SERVER’da da tüm içerik pagelere yazılır. Her bir page en fazla 8KB data içerebilir. Normal bir kitabın içerisinde bilgi içeren safalar olduğu gibi meta data içeren sayfalar da vardır. Örneğin içindekiler sayfası gibi. SQL SERVER’da durumlar çokta farklı değil, içerisinde data bulunan sayfalar, metadata bulunan sayfalar image/text bulunan sayfalar gibi sayfalar vardır. Her page 96byte boyutunda bir header ile başlar. Bu headerin içerisinde page numarası, page tipi, page içerisindeki […]

SQL SERVER – Page Yapısı
İçindekiler

PAGE NEDİR?

 

Bilgisayarımın karşısına oturdum ve index mantığını anlatmak üzere yazmaya başladım. Ancak farkettim ki herşey page yapısını anlamak ile başlıyor. İşte bu yüzden şuan yazacaklarım SQL ENGINE’ı anlamak ve onun gibi düşünmeye başlamak için bir rehber niteliğinde. Ayrıca bu şekilde bir yazı dizisi yapmayı düşünüyorum. Eğer SQL ENGINE’ı gerçekten anlamak istiyorsanız takipte kalsanız iyi edersiniz.

Nasıl maddenin en küçük yapı taşı atom ise SQL SERVER’ın da en küçük yapı taşı pagelerdir. Bir kitapta tüm içerik sayfalara yazıldığı gibi SQL SERVER’da da tüm içerik pagelere yazılır. Her bir page en fazla 8KB data içerebilir.

Normal bir kitabın içerisinde bilgi içeren safalar olduğu gibi meta data içeren sayfalar da vardır. Örneğin içindekiler sayfası gibi. SQL SERVER’da durumlar çokta farklı değil, içerisinde data bulunan sayfalar, metadata bulunan sayfalar image/text bulunan sayfalar gibi sayfalar vardır.

Her page 96byte boyutunda bir header ile başlar. Bu headerin içerisinde page numarası, page tipi, page içerisindeki boşluk miktarı ve allocation unit id si bulunur.

Veri satırları, başlıktan hemen sonra başlayarak sayfada birbiri ardına yazılarak saklanır. Satır ofseti tablosu sayfanın sonunda başlar (footer diyebiliriz) ve satır ofseti tablosu, sayfadaki her satır için bir kayıt içerir. Her satır ofseti kaydı, satırın ilk baytının sayfanın başından ne kadar uzakta olduğunu bilgisini tutar. Satır ofset tablosunun işlevi, SQL Server’ın bir sayfadaki satırları hızlı bir şekilde bulmasına yardımcı olmaktır. Satır ofset tablosundaki girişler, sayfadaki satırların dizilişinden ters sıradadır.

Satırlar sayfalara yayılamaz, bir satır maksimum bir page içerisinde olabilir! Muhtemelen bu noktada aklınıza şu soru gelecek: sqlde makisumum satır büyüklüğüm sadece 8kb mı olabilir? (Hem EVET hemde HAYIR)

Bir tablodaki tüm sütunların toplam satır boyutu 8.060 bayt sınırlamasını aştığında, SQL Server, en büyük genişliğe sahip sütundan başlayarak, bir veya daha fazla sütunu ROW_OVERFLOW_DATA ayırma birimindeki sayfalara taşır. Bu işlem sadece insert edilen data için değil update edilen data içinde dinamik olarak yapılır. Bir sütun ROW_OVERFLOW_DATA birimine taşındığında orijinal sayfasına sütunun yerini belirten 24baytlık bir pointer koyulur bu sayede satır çok daha büyük olabilir.

Örneğin iki kolondan oluşan bir satırımız olsun, kolonlarımızı varchar(6000) ve varchar(3000) boyutunda ve dolu olarak farz edelim. Kolonlar tek başlarına 8.060 byte limitini geçmiyor ancak birlikte oldukları zaman bu limiti aşıyorlar. Böyle bir durumda varchar(3000) boyutundaki kolon page içerisinde kalır ancak varchar(6000) boyutlu kolon ROW_OVERFLOW_DATA birimlerine taşınarak pointer’ı page içerisine eklenir.

Bu taşıma işlemleri direkt olarak eş zamanlı olarak yapılır ve eş zamanlı yapıldığı için ilgili tablonun sorgulanma performansını düşürür. Bu noktada büyük kolonlara sahip tabloları normalize edebilir, birkaç tabloya ayırabiliriz.

Large Object Data (BLOB) dediğimiz veriler varbinary(MAX), varchar(MAX), IMAGE, TEXT gibi kolonlar bu 8,060 byte sınırından muaftır. Bu kolonlarda bulunan veriler hâlihazırda satırın bulunduğu page içerisinde tutulmaz LOB_DATA page yapılarında saklanır ve aynı şekilde pointer’ı page içerisine eklenir.

Bu kadar kavramsal bilgi yeter şimdi SQL SERVER içerisinde ufak bir uygulama ile pekiştirelim.

Basit bir tablo oluşturuyorum.

 

CREATE TABLE [dbo].[PageTest](

[Id] [int] NULL,

[varchar3000] [varchar](3000) NULL,

[varchar6000] [varchar](6000) NULL,

[varcharMAX] [varchar](max) NULL

) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

 

Sonra bu tabloya sadece tek bir satır veri ekleyeceğim.

insert into PageTest

Select 1, replicate('x',3000),replicate('x',6000),replicate('x',9000)

 

Varchar3000 isimli alana 3000 adet x ekledim 6000 olana 6000 adet ve son olarak varcharmax alana 9000 adet ekledim. Peki bu verinin page üzerinde dağılımı nasıl oldu dersiniz?

 

Bunu da sys.dm_db_index_physical_stats fonksiyonu ile görebiliriz.

 

 

SELECT OBJECT_NAME([object_id]) AS TableName,
alloc_unit_type_desc,
record_count,
page_count,
round(avg_page_space_used_in_percent,0) as avg_page_space_used_in_percent ,
min_record_size_in_bytes,
max_record_size_in_bytes
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED')
WHERE OBJECT_NAME([object_id]) LIKE 'PageTest'

 

 

 

Yukarda gördüğünüz gibi bir kolonumuz ROW_OVERFLOW_DATA kısmına aktarılmış. Bu kolonumuz varchar6000 kolonumuz oluyor. LOB_DATA kısmına aktarılan ise varcharmax kolonumuzdur. Hatta bu kaydı update ettiğimizde oluşacak değişikliği de görebiliriz.

 

Update PageTest SET [varcharMAX]= replicate('x',1)

Varcharmax alana sadece tek bir x karekteri olarak update ettik. Ve sonuç :

 

Update PageTest SET [varchar6000]= replicate('x',4000)

Varchar6000 alanının içinde bulunan kaydı 4000 karakter yaptığımızda ise satırın toplam boyutu 8KB’ı geçmeyeceği için ROW_OVERFLOW_DATA kısmına taşınmayacaktır.

 

 

Böylelikle SQL SERVER’ın en temelde veriyi nasıl depoladığı konusunu işlemiş olduk. Muhtemelen sıradaki yazım extendler ile alakalı olacaktır. Bu kısımlar ilk etapta sıkıcı gelebilir. Ama temel mekanikleri öğrenmek size çok şey katar. SQL ile alakalı bir problem yaşadığınızda hiç görmediğiniz bir sorun olsa dahi, muhtemelen şu sebeptendir diyebilmek için bu arkadaki mekanizmayı iyi bilmelisiniz.

Benzer Yazılar

SQL SERVER SERViS RESTART HATASI

SQL Server 2 hafta önce

Bu haftaki yazımızda karşılan bir hata üzerindeki; logları ve çözümünü anlatacağım. Aşağıdaki GÖRSEL-1’de görüldüğü üzere SQL servisini restart ettiğimiz sırada bir hata ile karşılaşıyoruz. Servis running state’e geçemiyor. “The request failed or the service did not respond in a timely fashion. Consult the event log or other applicable error logs for details” şeklinde bir uyarı veriyor. Hatanın çözümüne doğru ilerlerken farklı servis hesaplarıyla veya “Local System” hesabı ile restart etmeye çalıştığınızda servis ilginç bir şekilde ayağa kalkıyor. Ancak Always on sistem çalışıyorsanız farklı servis hesaplarını kullandığınızda always on size haberleşme izni vermiyor. Aynı hesabın şifresi ile ilgili sorunlar olduğu düşünüp hesabın şifresini de değiştirdiğiniz de yine sonuç alamıyorsunuz. Burdan yola çıkıldığında sıkıntı servis hesabında gibi görünüyor olabilir ancak çözüme geçildiğinde regedit üzerinde yapacağımız bir işlem ile sorunu çözüyoruz. Servis hesabının kaydının olduğu regedit kaydını siliyoruz. Regedit üzerindeki servis hesap bilgisi güncellendiğinde sorun çözülmüş olmakta. GÖRSEL-1  Servis restart edildiğinde SQL’in verdiği Error […]

SQL’DE İKİ NODE’UN RESOLVING DURUMA DÜŞMESİ VE ÇÖZÜMÜ

SQL Server 1 ay önce

Bu yazımızda failover olma işlemi esnasında karşılaşılan bir durumdan kısaca bahsedeceğim. Kısa bir yazı olacak ama önemli olduğunu düşünüyorum. Bazen failover olmak istediğinizde cluster secondary’e node’a failover olamaz, hem secondary hem de primary node’unuz resolving durumuna geçer. Bu durumla daha çok otomatik failover olma durumlarında karşılaşılır çünkü sistem failover’a aslında hazır değildir ancak cluster bunu bir şekilde bilemez. Failover olma gerçekleşemez bir anlamda sql cluster askıda kalır ve hiçbir sunucu da sql engine çalışmaya devam edemez. (GÖRSEL-1) GÖRSEL-1 GÖRSEL-1 üzerinde gördüğünüz üzere availability group resolving duruma düşer. Availability replica’lar üzerinde de gördüğünüz üzere primary ve secondary tüm node’lar resolving state’e düşer. Böyle bir durumunda iki farklı çözüm yolumuz var;   Çözüm: ikinci node’a sunucu restart’ı atmak. Bu noktada secondary sql node’a servis restart atmak işe yaramıyor. Zaten db’ler iki taraflı resolving modda. O sebeple ancak sunucu restart atıldığında cluster ayakta olan sunucuyu görüyor ve askıda kalma durumundan ilk başta primary […]

Query Store Nedir?

SQL Server 1 ay önce

Query Store ile birlikte execution planın seçimi ve bu sürecin performansa etkisini anlayabiliriz. SQL Server içerisinde bulunan Query Store özelliği, çalıştırılan sorguların execution planını ve bu sırada oluşan istatistiklerini otomatik olarak yakalar. Böylece query plan değişikliği ile oluşan problemleri de hızlı ve kolay şekilde fark edebiliriz. Elinizde bulunan bir sorguya ait query plan zamanla değişebilir. Bunun birçok sebebi vardır. Tablo yapısına yeni bir column eklenmesi Veri tipinin değiştirilmesi Sorgularda yeni parametrelerin eklenip çıkarılması Verilerde, schemalarda veya sorgu parametrelerindeki değişiklik Burada önemli olan ise bazen bu değişimler sorgunun yavaş çalışmasına neden olur. Query Store ile beraber bu yavaşlığın kök nedenine inmek daha kolay oldu. Ayrıca query store sayesinde ilgili sorguya ait read-write bilgileri ve cpu tüketimi bilgilerine de erişebilirsiniz. Query Store’u veritabanı seviyesinde aktif edebiliyoruz. Veritabanı üzerine sağ tıklayarak properties diyoruz ve Query Store sekmesine geliyoruz. Operation Mode alanından Read Write’ı seçiyoruz. Böylelikle Query Store gerekli bilgiyi toplayabilir ve size ilgili sonuçları […]

0 Yorum

Yorum Yaz

Rastgele