SQL Server Page數(shù)據(jù)庫(kù)結(jié)構(gòu)深入分析
SQL Server存儲(chǔ)數(shù)據(jù)的基本單元是Page,每一個(gè)Page的大小是8KB,數(shù)據(jù)文件是由Page構(gòu)成的。在同一個(gè)數(shù)據(jù)庫(kù)上,每一個(gè)Page都有一個(gè)唯一的資源標(biāo)識(shí),標(biāo)識(shí)符由三部分組成...
SQL Server存儲(chǔ)數(shù)據(jù)的基本單元是Page,每一個(gè)Page的大小是8KB,數(shù)據(jù)文件是由Page構(gòu)成的。在同一個(gè)數(shù)據(jù)庫(kù)上,每一個(gè)Page都有一個(gè)唯一的資源標(biāo)識(shí),標(biāo)識(shí)符由三部分組成:db_id,file_id,page_id,例如,15:1:8733,15是數(shù)據(jù)庫(kù)的ID,1是數(shù)據(jù)文件的ID,8733是Page的編號(hào),Page的編號(hào)從0依次遞增。8個(gè)連續(xù)的Page組成一個(gè)區(qū)(Extent),數(shù)據(jù)文件中已分配(Allocated)的空間被分割成區(qū)的整數(shù)倍。一次磁盤(pán)IO操作作用于Page級(jí)別,而空間分配的最小單元是區(qū)。
Page是用于存儲(chǔ)數(shù)據(jù)的,不同類型的Page存儲(chǔ)的數(shù)據(jù)是不同的,Page的結(jié)構(gòu)也是不同的。有些Page是用于存儲(chǔ)數(shù)據(jù)的,叫做Data Page,有些Page是用于存儲(chǔ)索引結(jié)構(gòu)中的中間節(jié)點(diǎn)的,叫做Index Page,有些Page是SQL Server存儲(chǔ)引擎使用的,用于管理Page的,叫做系統(tǒng)頁(yè)。本文關(guān)注的是Data Page和Index Page,跟數(shù)據(jù)表有關(guān)。
日志文件沒(méi)有Page結(jié)構(gòu),它是由一系列的日志記錄構(gòu)成的。
一,Page的結(jié)構(gòu)
每一個(gè)Page都由 頭部(Header),內(nèi)容(Content)和行偏移量(Offset)組成,頭部是在Page的開(kāi)始處,占用96Bytes,用于存儲(chǔ)Page的編號(hào),Page的類型,分配單元(Allocation Unit)等系統(tǒng)信息。注:在單個(gè)Page中最多存儲(chǔ)8060Bytes的數(shù)據(jù)。
The maximum amount of data and overhead that is contained in a single row on a page is 8,060 bytes (8 KB).
數(shù)據(jù)行存儲(chǔ)在Page Header之后,數(shù)據(jù)行在Page中的物理存儲(chǔ)是無(wú)序的,行的邏輯順序是由行偏移(Row Offset)確定的,行偏移存儲(chǔ)在Page的末尾,每一個(gè)行偏移是一個(gè)Slot,占用2B。行偏移連續(xù)排列在Page的末尾,稱作槽數(shù)組(Slot Array)。行偏移以倒序方式存儲(chǔ)行的偏移量,這意味著,從Page末尾向Page 開(kāi)頭計(jì)數(shù),第一行的偏移量存儲(chǔ)在Page的末尾Slot中,第二行的偏移量存儲(chǔ)在Page末尾的第二個(gè)Slot中。
二,查看Page頭部信息
Page頭部信息存儲(chǔ)的是Page的系統(tǒng)信息,可以使用非正式的命令來(lái)查看:?
DBCC PAGE(['database name'|database id], file_id, page_number, print_option = [0|1|2|3] )
參數(shù):file_id是數(shù)據(jù)庫(kù)文件的ID;page_number是Page在當(dāng)前文件中的編號(hào);print_option是指打印信息的詳細(xì)程度,默認(rèn)值是0,只打印Page Header。
例如,查看資源標(biāo)識(shí)符:15:1:8777733 Page的頭部信息:?
dbcc traceon(3604)
dbcc page(15,1,8777733)
在我的數(shù)據(jù)庫(kù)中,該P(yáng)age的頭部信息(移除Buffer的數(shù)據(jù))如下所示,?
PAGE: (1:8777733)
PAGE HEADER:
Page @0x0000005188B02000
m_pageId = (1:8777733) m_headerVersion = 1 m_type = 1
m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0x220
m_objId (AllocUnitId.idObj) = 28503 m_indexId (AllocUnitId.idInd) = 256
Metadata: AllocUnitId = 72057595905900544
Metadata: PartitionId = 72057594059423744 Metadata: IndexId = 1
Metadata: ObjectId = 1029578706 m_prevPage = (1:8777732) m_nextPage = (1:8777734)
pminlen = 16 m_slotCnt = 2 m_freeCnt = 4513
m_freeData = 3675 m_reservedCnt = 0 m_lsn = (1212327:16:558)
m_xactReserved = 0 m_xdesId = (0:799026688) m_ghostRecCnt = 0
m_tornBits = -1518328013 DB Frag ID = 1
Allocation Status
GAM (1:8690944) = ALLOCATED SGAM (1:8690945) = NOT ALLOCATED
PFS (1:8775480) = 0x40 ALLOCATED 0_PCT_FULL DIFF (1:8690950) = CHANGED
ML (1:8690951) = NOT MIN_LOGGED
Page 頭部中各個(gè)字段的含義:
1,Page的編號(hào)
m_pageId = (1:8777733),該P(yáng)age所在的File ID 和Page ID
2,Page的類型
m_type = 1,Page的類型,常見(jiàn)的類型是數(shù)據(jù)頁(yè)和索引頁(yè):
1 – data page,用于表示:堆表或聚集索引的葉子節(jié)點(diǎn)
2 – index page,用于表示:聚集索引的中間節(jié)點(diǎn)或者非聚集索引中所有級(jí)別的節(jié)點(diǎn)
其他Page類型(系統(tǒng)頁(yè)是管理Page的Page,例如,GAM,IAM等)如下:
3 – text mix page,4 – text tree page,用于存儲(chǔ)類型為文本的大對(duì)象數(shù)據(jù)
7 – sort page,用于存儲(chǔ)排序操作的中間數(shù)據(jù)結(jié)果
8 – GAM page,用于存儲(chǔ)全局分配映射數(shù)據(jù)GAM(Global Allocation Map),每一個(gè)數(shù)據(jù)文件被分割成4GB的空間塊(Chunk),每一個(gè)Chunk都對(duì)應(yīng)一個(gè)GAM數(shù)據(jù)頁(yè),GAM數(shù)據(jù)頁(yè)出現(xiàn)在數(shù)據(jù)文件特定的位置處,一個(gè)bit映射當(dāng)前Chunk中的一個(gè)區(qū)。
9 – SGAM page,用于存儲(chǔ)SGAM頁(yè)(Shared GAM)
10 – IAM page,用于存儲(chǔ)IAM頁(yè)(Index Allocation Map)
11 – PFS page,用于存儲(chǔ)PFS頁(yè)(Page Free Space)
13 – boot page,用于存儲(chǔ)數(shù)據(jù)庫(kù)的信息,只有一個(gè)Page,Page的標(biāo)識(shí)符是:db_id:1:9,
15 – file header page,存儲(chǔ)數(shù)據(jù)文件的數(shù)據(jù),數(shù)據(jù)庫(kù)的每一個(gè)文件都有一個(gè),Page的編號(hào)是0。
16 – diff map page,存儲(chǔ)差異備份的映射,表示從上一次完整備份之后,該區(qū)的數(shù)據(jù)是否修改過(guò)。
17 – ML map page,表示從上一次備份之后,在大容量日志(bulk-Logged)操作期間,該區(qū)的數(shù)據(jù)是否被修改過(guò),This is what allows you to switch to bulk-logged mode for bulk-loads and index rebuilds without worrying about breaking a backup chain.
18 – a page that's be deallocated by DBCC CHECKDB during a repair operation.
19 – the temporary page that ALTER INDEX … REORGANIZE (or DBCC INDEXDEFRAG) uses when working on an index.
20 – a page pre-allocated as part of a bulk load operation, which will eventually be formatted as a ‘real' page.
3,Page在索引中的級(jí)數(shù)
數(shù)據(jù)頁(yè)在索引中的索引級(jí)數(shù),m_level=0,表示處于Leaf Level。
對(duì)于堆表(Heap),m_level=0表示的是Data Page;
對(duì)于聚集索引,m_level=0表示的是Data Page;
對(duì)于非聚集索引,m_level=0表示的是葉子節(jié)點(diǎn)
4, Page的元數(shù)據(jù)
Page的元數(shù)據(jù)十分重要,不僅能夠查看處Page所在的Object,甚至能夠查看該P(yáng)age所在的分配單元和分區(qū)ID,在死鎖進(jìn)行故障排除時(shí)十分有用
Metadata: AllocUnitId =72057595905900544,該P(yáng)age所在的分配單元ID(allocation_unit_id)
Metadata: PartitionId =72057594059423744,該P(yáng)age所在的分區(qū)的分區(qū)ID(partition_id)
Metadata: IndexId = 1,該P(yáng)age所在的索引ID
Metadata: ObjectId = 1029578706,用于表示Page所屬對(duì)象的object_id
5,page的鏈指針
由于數(shù)據(jù)表的Page并不是單獨(dú)存在的,而是通過(guò)雙向鏈?zhǔn)浇Y(jié)構(gòu)連接在一起的,
m_prevPage = (1:8777732) :用于表示前一個(gè)page (FileID : PageID)
m_nextPage = (1:8777734) :用于表示下一個(gè)page (FileID:PageID)
6, 其他頭部字段
m_slotCnt = 2 :頁(yè)面中Slot的數(shù)量,用于Page中存儲(chǔ)的數(shù)據(jù)行數(shù)
m_freeCnt = 4513 :頁(yè)面中剩余的空間,單位是字節(jié),還剩83字節(jié)的空間
m_reservedCnt = 0 :為活動(dòng)事務(wù)保留的存儲(chǔ)空間,單位是字節(jié)
m_ghostRecCnt = 0 :頁(yè)面中存在的幽靈記錄的總數(shù)(ghost record count)
關(guān)于Page頭部的信息,可以閱讀《Inside the Storage Engine: Anatomy of a page》;
三,利用Page的元數(shù)據(jù)排除死鎖
Page的元數(shù)據(jù)包含分區(qū)ID,索引ID和對(duì)象ID,用戶可以使用這些元數(shù)據(jù),分析死鎖產(chǎn)生的原因。系統(tǒng)追蹤到產(chǎn)生死鎖的資源,可能是一個(gè)Page的資源標(biāo)識(shí)符,如果能夠確認(rèn)發(fā)生死鎖是由于數(shù)據(jù)表或索引的分區(qū)不合理導(dǎo)致的,那么可以重新設(shè)置分區(qū)列,或者設(shè)置分區(qū)邊界值,把單個(gè)分區(qū)拆分成多個(gè)分區(qū),這樣就能把競(jìng)爭(zhēng)的臨界資源分配到不同的分區(qū)中,避免查詢請(qǐng)求對(duì)資源的競(jìng)爭(zhēng),進(jìn)而減少死鎖的發(fā)生。
Metadata: PartitionId ,該P(yáng)age所在的分區(qū)的分區(qū)ID(partition_id);
Metadata: IndexId ,該P(yáng)age所在索引ID;
Metadata: ObjectId,用于表示對(duì)象的object_id;
原文鏈接:http://www.cnblogs.com/ljhdo/p/4803095.html
- 基于Sql server數(shù)據(jù)庫(kù)的四種分頁(yè)方式總結(jié)
- SQL Server 2016數(shù)據(jù)庫(kù)快照代理過(guò)程詳解
- SQL Server 全文搜索功能、全文索引方式介紹
- 關(guān)于SQL Serve數(shù)據(jù)庫(kù)r帳號(hào)被禁用的處理方法
- SQL數(shù)據(jù)庫(kù)查詢優(yōu)化技巧提升網(wǎng)站訪問(wèn)速度的方法
- SQL數(shù)據(jù)庫(kù)開(kāi)發(fā)中的SSIS 延遲驗(yàn)證方法
- SQL Server數(shù)據(jù)庫(kù)建立新用戶及關(guān)聯(lián)數(shù)據(jù)庫(kù)的方法教程
- Oracle數(shù)據(jù)庫(kù)多條sql執(zhí)行語(yǔ)句出現(xiàn)錯(cuò)誤時(shí)的控制方式
- Oracle數(shù)據(jù)庫(kù)基礎(chǔ):程序中調(diào)用sqlplus的方式
- oracle數(shù)據(jù)庫(kù)通過(guò)sqlplus連接的幾種方式介紹
基于Sql server數(shù)據(jù)庫(kù)的四種分頁(yè)方式總結(jié)
下面小編就為大家分享一篇基于sqlserver的四種分頁(yè)方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧。...
SQL Server 2016數(shù)據(jù)庫(kù)快照代理過(guò)程詳解
本文我們通過(guò)SQL Server 2016一個(gè)實(shí)例數(shù)據(jù)表,給大家詳細(xì)分析了快照代理過(guò)程遇到的問(wèn)題和解決辦法,并對(duì)快照生成過(guò)程做了詳細(xì)說(shuō)明,以下是全部?jī)?nèi)容:...
SQL Server 全文搜索功能、全文索引方式介紹
SQL Server 的全文搜索(Full-Text Search)是基于分詞的文本檢索功能,依賴于全文索引。全文索引不同于傳統(tǒng)的平衡樹(shù)(B-Tree)索引和列存儲(chǔ)索引,它是由數(shù)據(jù)表構(gòu)成的,稱作倒轉(zhuǎn)索引(Invert Index),存儲(chǔ)分詞和行的唯一鍵的映射關(guān)系。...
關(guān)于SQL Serve數(shù)據(jù)庫(kù)r帳號(hào)被禁用的處理方法
若發(fā)現(xiàn)SQL Serve所有帳號(hào)不小心被禁用了,這個(gè)時(shí)候怎么辦?用重裝嗎?不用,仔細(xì)看小白是怎么一步一步解開(kāi)這個(gè)謎題的。首先需要Windows帳號(hào)設(shè)置里重新添加一個(gè)新帳號(hào)。并將其添加到...
SQL數(shù)據(jù)庫(kù)查詢優(yōu)化技巧提升網(wǎng)站訪問(wèn)速度的方法
在這篇文章中,我將介紹如何識(shí)別導(dǎo)致性能出現(xiàn)問(wèn)題的查詢,如何找出它們的問(wèn)題所在,以及快速修復(fù)這些問(wèn)題和其他加快查詢速度的方法。 你一定知道,一個(gè)快速訪問(wèn)的網(wǎng)站能讓用...
SQL數(shù)據(jù)庫(kù)開(kāi)發(fā)中的SSIS 延遲驗(yàn)證方法
驗(yàn)證是一個(gè)事件,該事件在Package執(zhí)行時(shí),第一個(gè)被觸發(fā),驗(yàn)證能夠避免SSIS引擎執(zhí)行一個(gè)有異常的Package或Task。延遲驗(yàn)證(DelayValidation)是把驗(yàn)證操作延遲到Package真正運(yùn)行(run-ti...
SQL Server數(shù)據(jù)庫(kù)建立新用戶及關(guān)聯(lián)數(shù)據(jù)庫(kù)的方法教程
本文講的是SQLserver數(shù)據(jù)庫(kù)創(chuàng)建新用戶方法以及賦予此用戶特定權(quán)限的方法,非常的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下...
Oracle數(shù)據(jù)庫(kù)多條sql執(zhí)行語(yǔ)句出現(xiàn)錯(cuò)誤時(shí)的控制方式
多條sql執(zhí)行時(shí)如果在中間的語(yǔ)句出現(xiàn)錯(cuò)誤,后續(xù)會(huì)不會(huì)直接執(zhí)行,如何進(jìn)行設(shè)定,以及其他數(shù)據(jù)庫(kù)諸如Mysql是如何對(duì)應(yīng)的,這篇文章將會(huì)進(jìn)行簡(jiǎn)單的整理和說(shuō)明。環(huán)境準(zhǔn)備使用Oracle的精簡(jiǎn)...
Oracle數(shù)據(jù)庫(kù)基礎(chǔ):程序中調(diào)用sqlplus的方式
通過(guò)sqlplus可以連接數(shù)據(jù)庫(kù)根據(jù)用戶權(quán)限進(jìn)行數(shù)據(jù)或者設(shè)定操作,但是需要交互操作并返回結(jié)果,這篇文章介紹一下如何在程序中使用sqlplus。環(huán)境準(zhǔn)備使用Oracle的精簡(jiǎn)版創(chuàng)建docker...
oracle數(shù)據(jù)庫(kù)通過(guò)sqlplus連接的幾種方式介紹
分享一篇關(guān)于Oracle通過(guò)sqlplus連接數(shù)據(jù)庫(kù)的方式,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧...