2012-02-23

SQL Server’da Bir Kaydın Fiziksel Konumunu Bulma

Bu makalemde  undocumented komut ve fonksiyonlar yardımıyla SQL Server'da bir tablodaki bir kayıt satırının fiziksel konumunu nasıl bulunacağını ve fiziksel konumdan nasıl okunacağını aktaracağım. 


SQL Server veritabanı sisteminde her bir kayıt için  kayıtın tutulduğu file_id (dosya numarası), page_id(sayfa numarası) ve slot_id(slot numarası) üçlüsünden  oluşan RID(Row ID) bilgisi tutulmaktadır. Bu bilgiye SQL Server 2005 ile birlikte gelen %%lockres%%  komutu ile ulaşabiliyorduk.  Satırın bulunduğu fiziksel konumu bulmak için bir test veritabanı ve test tablosu oluşturalım:

--Veritabanı Oluşturma
create database test_dbcc
go
use test_dbcc
go

--Tablo Oluşturma
create table dbo.WebSites
(id int identity(1,1),
webadress varchar(64),
siteowner varchar(32))
go
insert into dbo.WebSites(webadress,siteowner) values('www.mehmetguzel.net','Mehmet Güzel')
go
insert into dbo.WebSites(webadress,siteowner) values('www.mehmetguzel.com','Mehmet Güzel')
go
insert into dbo.WebSites(webadress,siteowner) values('mehmetguzel.blogspot.com','Mehmet Güzel')
go


Oluşturduğumuz tablodaki kayıtların fiziksel konumuna bakalım:

select idwebadress, %%lockres%% FileId_PageId_SlotId
from dbo.WebSites



Yukarıdaki resimde; en sağdaki sütun bize ilgili kayıtın bulunduğu file_id, page_id ve slot_id numarasını vermektedir. 1. Satır için file_id 1, page_id 165 ve slot_id 0 değerlerine sahip.
  

SQL Server 2008 ile birlikte %%lockres%%  komutuna benzer işi yapan %%physloc%% komutu geldi. %%physloc%% komutu hex değer döndürür. WebSites tablosundaki kayıtların fiziksel adreslerini hex olarak bulalım:

select idwebadress, %%physloc%% HexAdress
from dbo.WebSites


HexAdress kolonun ilk 4 byte’ın kombinasyonu page_id değerini; sonraki 2 byte’ın kombinasyonu file_id değerini; en sondaki 2 byte’ın kombinasyonu ise slot_id değerini verir. Bu değerleri T-SQL ile bulalım:

select  cast(convert (binary (4), reverse (substring (%%physloc%%, 1, 4))) as int ) page_id
                    ,cast(convert (binary (2), reverse (substring (%%physloc%%, 5, 2))) as int) file_id
                    ,cast(convert (binary (2), reverse (substring (%%physloc%%, 7, 2))) as int) slot_id
from dbo.WebSites




%%physloc%% komutunun döndürdüğü hex değeri kolayca okuyabilmek için undocumented olan sys.fn_PhysLocFormatter() fonksiyonu da kullanılabilir:

select id,webadress%%physloc%% HexAdress, sys.fn_PhysLocFormatter(%%physloc%%) Adress
from dbo.WebSites




%%physloc%% komutunun döndürdüğü hex değerini okuyabileceğimiz undocumented bir diğer fonksiyonumuz sys.fn_physloccracker() fonksiyonudur. Aynı sorguyu sys.fn_physloccracker() fonksiyonunu kullanarak fiziksel adres bilgilerini bulalım:


select w.idw.webadress, %%lockres%% HexAdress, plc.file_idplc.page_id, plc.slot_id
from dbo.WebSites w
cross apply sys.fn_physloccracker(%%physloc%%)  plc





Data Page yapısını okumak için dbcc page komutu kullanılır.
 
Syntax:
 
dbcc page( {dbid|dbname}, pagenum [,print option] [,cache] [,logical] ) 

 
Parametreler:

   Dbid|dbname   : Veritabanı Id yada Veritabanı Adı
   Pagenum         : Page numarası
   Print option      : 0, 1, 2 veya 3 değerini alabilen içerik detayını görüntüleme seçenekleridir.
                  0 - (Default) :  Sadece page header bilgisi için
                  1 – Page Header ile birlikte her satırın hex bilgisi için
                  2 – Page Header ve Page seviyesinde detay bilgi için
                  3 – Page Header ve satır seviyesinde detay bilgi için
                      
                      
Şimdi ise  WebSites tablosunda id numarası 1 olan kayıtın fiziksel adresini bulup ilgili page içeriğine page header ve satır seviyesinde detaylı olarak bakalım:

declare @dbccpage varchar(128)

select @dbccpage = 'dbcc page(' + db_name() + ',' + cast(file_id as varchar) + ',' + cast(page_id as varchar) + ',3)'
from dbo.WebSites
cross apply sys.fn_physloccracker(%%physloc%%)
where id =1

dbcc traceon(3604)
exec (@dbccpage)
dbcc traceoff(3604)


Sorgu sonucu:


DBCC execution completed. If DBCC printed error messages, contact your system administrator.

PAGE: (1:165)


BUFFER:


BUF @0x05B227D0

bpage = 0x09334000                  bhash = 0x00000000                  bpageno = (1:165)
bdbid = 8                           breferences = 1                     bcputicks = 0
bsampleCount = 0                    bUse1 = 55342                       bstat = 0x9
blog = 0x1c9a                       bnext = 0x00000000                 

PAGE HEADER:


Page @0x09334000

m_pageId = (1:165)                  m_headerVersion = 1                 m_type = 1
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x8200
m_objId (AllocUnitId.idObj) = 85    m_indexId (AllocUnitId.idInd) = 256
Metadata: AllocUnitId = 72057594043498496                               
Metadata: PartitionId = 72057594039107584                                Metadata: IndexId = 0
Metadata: ObjectId = 261575970      m_prevPage = (0:0)                  m_nextPage = (0:0)
pminlen = 8                         m_slotCnt = 3                       m_freeCnt = 7941
m_freeData = 297                    m_reservedCnt = 0                   m_lsn = (33:210:2)
m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
m_tornBits = -1585932016            DB Frag ID = 1                     

Allocation Status

GAM (1:2) = ALLOCATED               SGAM (1:3) = ALLOCATED             
PFS (1:1) = 0x61 MIXED_EXT ALLOCATED  50_PCT_FULL                        DIFF (1:6) = CHANGED
ML (1:7) = NOT MIN_LOGGED          

Slot 0 Offset 0x60 Length 48

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 48                   
Memory Dump @0x1138A060

00000000:   30000800 01000000 03000002 00240030 00777777  0............$.0.www
00000014:   2e6d6568 6d657467 757a656c 2e6e6574 4d65686d  .mehmetguzel.netMehm
00000028:   65742047 fc7a656c                             et Güzel      

Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4

id = 1                             

Slot 0 Column 2 Offset 0x11 Length 19 Length (physical) 19

webadress = www.mehmetguzel.net    

Slot 0 Column 3 Offset 0x24 Length 12 Length (physical) 12

siteowner = Mehmet Güzel           

Slot 1 Offset 0x90 Length 48

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 48                   
Memory Dump @0x1138A090

00000000:   30000800 02000000 03000002 00240030 00777777  0............$.0.www
00000014:   2e6d6568 6d657467 757a656c 2e636f6d 4d65686d  .mehmetguzel.comMehm
00000028:   65742047 fc7a656c                             et Güzel      

Slot 1 Column 1 Offset 0x4 Length 4 Length (physical) 4

id = 2                              

Slot 1 Column 2 Offset 0x11 Length 19 Length (physical) 19

webadress = www.mehmetguzel.com    

Slot 1 Column 3 Offset 0x24 Length 12 Length (physical) 12

siteowner = Mehmet Güzel           

Slot 2 Offset 0xf4 Length 53

Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 53                   
Memory Dump @0x1138A0F4

00000000:   30000800 03000000 03000002 00290035 006d6568  0............).5.meh
00000014:   6d657467 757a656c 2e626c6f 6773706f 742e636f  metguzel.blogspot.co
00000028:   6d4d6568 6d657420 47fc7a65 6c                 mMehmet Güzel 

Slot 2 Column 1 Offset 0x4 Length 4 Length (physical) 4

id = 3                             

Slot 2 Column 2 Offset 0x11 Length 24 Length (physical) 24

webadress = mehmetguzel.blogspot.com

Slot 2 Column 3 Offset 0x29 Length 12 Length (physical) 12

siteowner = Mehmet Güzel           


DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.


Bu makalemde undocumented komut ve fonsiyonlar yardımıyla SQL Server’da bir kayıt satırının fiziksel page yapısını nasıl okuyacağımıza değindim. Bir sonraki makalede görüşmek dileğiyle.

Not: Makalede kullanılan SQL kodlar SQL Server 2012 RCO sürümünde yazılıp test edilmiştir.

Hiç yorum yok:

.::YASAL UYARI::.

©2004-2016 Mehmet GÜZEL, http://www.mehmetguzel.net/ & http://www.mehmetguzel.com/

Site içeriği kaynak gösterilmek koşuluyla yayınlanabilir. Yazılan yazı ve yorumlar sadece yazı ve yorum sahiplerini bağlar.