Page Index Kayıt Ekleme Çıkarma – Page Split

Üzerinde index bulunan bir tabloya kayıt eklendiğinde Page ve Row konumları nasıl etkilenir? Page Split ne zaman oluşur?

Birçok yerde indexlenmiş tabloya yeni kayıt eklendiğinde veya mevcut kayıt silindiğinde kayıtların adreslerinin fiziksel olarak değişip değişmediği sorusu gelmektedir. Bunu basit bir örnekle açıklayalım. UYE isminde bir tablo oluşturalım. ID alanı üzerinde Clustered Index oluşturalım. İlk kayıt olarak ID=4 olarak “D” ifadesini ekleyelim.

CREATE TABLE UYE(UyeId INT PRIMARY KEY, AdSoyad VARCHAR(2000))

INSERT UYE VALUES(6,REPLICATE('G',1000))

DBCC IND(‘BLOG’, ‘UYE’, -1) komutuyle sayfalarını listelediğimizde 144 nolu bir data page’in oluştuğunu görüyoruz. Bu sayfanın içeriğine DBCC PAGE(BLOG,1,144,1) komutuyla bakalım. Eklenen satırın konumuna bakmak için Page içerisinde “OFFSET TABLE:” bölümüne baktığımızda bu kaydın adresinin 96 olarak görüyoruz.


Okumaya devam et

SP, View, Function, Trigger, System Base Tables (SQL Server Mimarisi – VI)

Bundan önce SQL Server mimarisini anlattığımız yazılardan table ve index datasının içeriğinin nasıl depolandığını biliyoruz. Peki Stored Procedure, View, Function, Trigger benzeri nesneler nerede store ediliyor. Bunlar tabiki MDF içerisinde aynı mantıkta Page’ler içerisinde saklanmaktadır. Bu nesneler System Base Tables olarak tanımlanan sistem tablolarında tutulmaktadır. Bu tablolar mevcut veri tabanlarına ait metadata bilgisini saklar. Bu tablolar kullanıcı erişimi için değil SQL Server Database Engine tarafından kullanılır. Bu tablolar ancak Dedicated Administrator Connection (DAC) bağlantısıyla erişilebilir. Okumaya devam et

Boot Page, DBCC DBINFO (SQL Server Mimarisi – V)

Boot Page Nedir? Birçok kişi SQL Server’da Boot Page bozulma sorununu yaşamıştır. Her veri tabanı kendisi hakkında kritik bilgileri içeren bir Page’a sahiptir. Bu page FileId=1 ve PageId=9 olarak oluşturulur. Bu sayfanın en önemli özelliği sözkonusu veri tabanını başlangıcını temsil ediyor olmasıdır. Bu sayfanın bozulması durumunda hiçbir şekilde o veri tabanı ayağa kaldırılamaz, DBCC CHECKDB gibi yöntemler de fayda sağlamaz. Page (1:9)’da corrupt oluşması durumunda yapılacak tek şey elimizdeki yedekten Restore işlemi yapmaktır.

DBCC PAGE(BLOG, 1, 9, 3) komutu aracılığıyla BLOG isimli veri tabanının başlangıç sayfasını dump etmiş oluruz. Page’in içeriğinde veri tabanının ilk oluşturulduğu versiyonu, şu anki sunucunun versiyonu (dbi_Version ve dbi_CreateVersion), son (Full, Log, Differential) backup alma zamanı, yedeğin alındığı LSN numarası (Log Sequence Numbers), dirty pages LSN numarası, DBCC CHECKDB en son ne zaman başarıyla çalıştığı (dbi_DBCCLastKnownGood) gibi bilgiler bulunmaktadır.

Bu bilgilere aynı zamanda DBCC DBINFO komutuyla da erişebiliriz.

DBCC DBINFO('BLOG') 
--veya
DBCC DBINFO('BLOG') WITH TABLERESULTS

Boot Page’in bozulması durumunda aşağıdaki gibi bir hata mesajı ile karşılaştırız.

SQL Server detected a logical consistency-based I/O error: incorrect checksum (expected: 0xcdee22fa; actual: 0xcb6ea2fa). It occurred during a read of page (1:9) in database ID 19 at offset 0x00000000013000 in file ‘C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\BLOG.mdf’. Additional messages in the SQL Server error log or system event log may provide more detail. This is a severe error condition that threatens database integrity and must be corrected immediately. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online.

Table, Index, Clustered, NonClustered, Columnstore (SQL Server Mimarisi – IV )

SQL Server veri tabanı mimarisi serisinin dördüncü bölümünde Table ve Index nesnelerinin nasıl oluşturulduğu, MDF içerisinde nasıl konumlandırıldığını detaylandıracağız. Bu amaçla temel olarak aşağıdaki kavramları incelemiş olacağız.

SQL Server Table, Heap, B-Tree (Balanced Search Tree), Index
Clustered Index,
NonClustered Index,
Columnstore Index

Okumaya devam et

Allocation Unit, IN_ROW_DATA, LOB_DATA, ROW_OVERFLOW_DATA, IAM Page (SQL Server Mimarisi – III)

SQL Server veri tabanı mimarisi serisinin üçüncü bölümünde de SQL Server underground dünyasını detaylandırmaya devam ediyoruz. Bu yazıda fiziksel ve mantıksal mimarinin temel bileşenleri olan aşağıdaki kavramları detaylandırıyor olacağız.

Allocation Unit (IAM)
IN_ROW_DATA Allocation Unit
LOB_DATA Allocation Unit
ROW_OVERFLOW_DATA Allocation Unit

Önceki makalelere aşağıdaki linklerden ulaşabilirsiniz;

SQL Server mimarisi – II (Data Page, Extent, GAM, SGAM, IAM)
SQL Server Mimarisi – I (Database Engine, Storage Engine, SQLOS)

SQL Server verileri fiziksel olarak her biri 8KB olan data page’lerde depolanır. Page’ler veri olarak ya doğrudan tablo datasını veya ona referans veren index datasını saklar. SQL Server üzerinde bir table veya index oluşturduğumuzda otomatik olarak bu nesnelerin altında bir partition oluşturulur. Sonraki yazılarda detaylandıracağımız Partition kavramı temel olarak yönetim kolaylığı ve performans açısından verilerin belli alan(-lar) bazında küçük kümelere bölümlendirilmesidir. Bir tablo bir veyda fazla partition’a içerir. Partition lar da Heap veya Clustered Index yapısında Data Row’ları içerir. Heap veya Clustered Index’a ait Page’ler kolonların verip tipine göre bir veya daha fazla Allocation Unit içerisinde yönetilir. Partition’lar kendisine ait page’leri kolonların tipine göre gruplandırır ve bunların her birine Allocation Unit denilir. “Allocation Unit” kavramını disk mimarisinden hatırlayabiliriz. Allocation Unit, disk üzerindeki sektör kümesini temsil eder yani yönetilebilir en küçük disk alanıdır. SQL Server’de de aynı amaç için kullanılmaktadır.

Okumaya devam et

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

Okumaya devam et

Database Engine, Storage Engine, SQLOS (SQL Server Mimarisi – I)

SQL Server bir makalede anlatılamayacak kadar detaylı bir mimariye sahiptir. Bu makalede hem yeni başlayanlar hem de deneyimli olanlar SQL Server mimarisinin genel yapısını aktarıyor olacağım. Makalede mimariyi anlatmakla birlikte birçok eğitim ve yazıda geçen kavramları da (Database Engine, Storage Engine, SQLOS) netleştirmiş olacağız. Microsoft’un kaynaklarında SQL Server mimarisi ile ilgili aşağıdaki diyagram bulunmaktadır.

Bu diyagrama baktığımızda karşımıza SQL Server veritabanı mimarisi ile ilgili 3 temel bileşen (component) çıkar.

1. SQL Server Network Interface (SNI)
2. Database Engine
  2.1. Relational Engine
  2.2. Storage Engine
3. SQL OS
Okumaya devam et

Identity Değerini Güncellemek – CHECKIDENT

Üzerinde IDENTITY alanı bulunan bir tabloda o alandaki sayılar verilmiş ritmik değere göre ardışık gider. Her yeni kayıtta bu sayı artar. Bu kayıtlardan biri silindiği zaman o satıra ait IDENTITY değeri bir daha kullanılmaz. Dolayısıyla bir süre sonra silmelerden dolayı bu sayı dizisinde çok fazla atlamalar söz konusu olur. Bazı durumlarda bu alanı baştan numaralandırma durumumuz olabilir mi. Bu tablonun başka bir tabloyla ilişkili olması da göz önünde bulundurularak bir güncelleme işlemi yapılabilir.

Veya bir tablodaki kayıtları başka bir tabloya aktardığımızda yeni tablodaki IDENTITY alanını yeniden düzenlemek isteyebiliriz. DBCC CHECKIDENT komutu bu işlemi yapmamızı sağlar.

DBCC CHECKIDENT (‘Tablo Adı’,RESEED, Başlangıç Sayısı)

Aşağıdaki örnekte üzerinde IDENTITY alanı bulunan geçici bir tablo oluşturulmuş ve içerisine sysobjects tablosundaki kayıtlar aktarılmış ardından tablodaki satırların çoğunluğu silinmiş. ID alanı 10 üzerinde olan tüm kayıtlar silindiği için yeni bir kayıt eklendiğinde bu numara

-- IDENTITY bulunan bir tablo oluşturalım
SELECT 
     ID = IDENTITY(INT,1,1)
    ,name
INTO ##T
FROM dbo.sysobjects 
-- 87 kayıt eklendi

-- 10 üzerindeki tüm satırları silelim
DELETE FROM ##T WHERE ID > 10
--77 kayıt silindi

--Tablodaki identity kolonundaki en yüksek değeri okuyalım
SELECT IDENT_CURRENT('##T')
--Bu örnek için 87 döndü. Yani yeni bir kayıt ekleyecek olursa ona 88 değeri verilecek. 
--Oysa tabloda şu anda 10 kayıt var ve 11 ile başlaması daha mantıklı olacaktır.

-- Tabloyu table scan yapıp max identity değerini alalım. Tablodaki en yüsek ID'yi bir değişkene atayalım
DECLARE @maxIdentityValue INT = (SELECT MAX(ID) FROM ##T)
--Bu sorgu 10 değerini döndürecek

-- IDENTITY kolonunun başlangıcını 10 olarak set edeli
DBCC CHECKIDENT('##T', RESEED, @maxIdentityValue)

-- Test amaçlı yeni kayıt ekleyelim. Bu kaydın değeri 11 olarak oluşturulacak
INSERT INTO ##T VALUES('Yeni Kayıt')

SQL Server CONTEXT_INFO Kullanımı

SQL Server ile programlamada bazı durumlarda oturuma özel bir yönlendirme yapma ihtiyacı doğabilir. Bunu yapabilmek için oturumun tekilliğini sağlamak gerekiyor. Bunun yapmanın en basit mantığı o oturumu özelleştirmek için bir parametre gibi bir alan kullanılabilir. Ardından SQL Server tarafında o parametrenin değerine göre koşul yazılabilir. Fakat bunu yapabilmek için her kod parçacığında bu şekilde ek bir parametre veya alan oluşturmak gerekiyor. İşte bu noktada SQL Server’in sunduğu Session Context Information alanı kolaylık sağlamaktadır. Session context information, 128 byte boyutunda bir değer tanımlanmasına izin vererek aynı oturumda multiple batche, stored procedure, triggers veya user-defined function gibi objeler tarafından bu değere otomatik olarak erişilmesini sağlar. O an bu değeri oluşturmak için SET CONTEXT_INFO ifadesi kullanılır. Bu değere o oturumda erişmek için CONTEXT_INFO() fonksiyonu kullanılır. Ayrıca sys.dm_exec_requests, sys.sysprocesses ve sys.dm_exec_sessions DMV’lerde session context’in binary değeri okunabilir. Böylece bu değere göre arama yaparak o oturuma ait talebin yürütülme durumu takip edilebilir.
Okumaya devam et

Tüm Veri Tabanlarından Erişilebilen Prosedür

Tüm veri tabanlarından erişilebilen prosedür yazmak için küçük bir düzenleme yapılması yeterlidir.

Birçok makalede SQL Server’de Stored Procedure isimlendirilmesinden “sp_” ile başlamaması tavsiye edilir. Bunun temel sebebi bu ön ek ile başlayan bir prosedür tam path bilgisiyle çalıştırılmadığı zaman öncelikle sisteme ait bir prosedürmüş gibi aranılır yani master veritabanının altında arama yapılır. Bu da zaman kaybı olduğu için “sp_” ile başlamaması tavsiye edilir.

Bu küçük detayı kendimiz için bir avantaja dönüştürebiliriz. Tüm veri tabanlarından erisilebilecek bir prosedür hazırlamak istersek master veritabanının altında “sp_” ile başlayacak şekilde isimlendirip CREATE etmemiz yeterli olacaktır.