TL/DR;
查看数据库中的第一个 DCM 页时(哪些文档记录了哪些范围已被修改,以便 DIFF 备份过程不必扫描整个数据库以查找更改,但可以跳转到范围来扫描已更改的页面)下一个 DCM 页的位置记录在哪里?
我原本以为它会被记录在m_nextPage
页眉的属性中。但检查后发现情况似乎并非如此。
查找 DCM 页面
我正在指导我们的学徒差异备份包含什么以及 DBMS 如何记录各个页面以及合并 DCM 页面中的更改。
参考: 页面和范围体系结构指南(Microsoft Learn | SQL)
然后我开始处理一个非常大的数据库并启动以下命令:
DBCC TRACEON (3604);
DBCC PAGE ( 6, 1, 0, 3 ); -- File Header
这产生了以下输出:
PAGE: (1:0)
BUFFER:
BUF @0x000002CC7AC80780
bpage = 0x000002CC2D11E000 bhash = 0x0000000000000000 bpageno = (1:0)
bdbid = 6 breferences = 0 bcputicks = 0
bsampleCount = 0 bUse1 = 48700 bstat = 0x9
blog = 0x15a bnext = 0x0000000000000000 bDirtyContext = 0x0000000000000000
bstat2 = 0x0
PAGE HEADER:
Page @0x000002CC2D11E000
m_pageId = (1:0) m_headerVersion = 1 m_type = 15
m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0x208
m_objId (AllocUnitId.idObj) = 99 m_indexId (AllocUnitId.idInd) = 0 Metadata: AllocUnitId = 6488064
Metadata: PartitionId = 0 Metadata: IndexId = 0 Metadata: ObjectId = 99
m_prevPage = (0:0) m_nextPage = (0:0) pminlen = 0
m_slotCnt = 1 m_freeCnt = 7019 m_freeData = 3321
m_reservedCnt = 0 m_lsn = (2501578:318516:1) m_xactReserved = 0
m_xdesId = (0:0) m_ghostRecCnt = 0 m_tornBits = 1668847350
DB Frag ID = 1
Allocation Status
GAM (1:2) = ALLOCATED SGAM (1:3) = NOT ALLOCATED PFS (1:1) = 0x44 ALLOCATED 100_PCT_FULL
DIFF (1:6) = CHANGED ML (1:7) = NOT MIN_LOGGED
阅读输出后,我注意到底部附近的信息,并(正确地)假设 DCM 页面位于第 6 页(嗯,实际上是第 7 页,但是......)。
让我们来看看:
DBCC PAGE ( 6, 1, 6, 0 ); -- 1. DCM Page
是的,这似乎是第一个 DCM 页面:
PAGE: (1:6)
BUFFER:
BUF @0x000002CC7AC80300
bpage = 0x000002CC2D112000 bhash = 0x0000000000000000 bpageno = (1:6)
bdbid = 6 breferences = 1 bcputicks = 0
bsampleCount = 0 bUse1 = 48800 bstat = 0x9
blog = 0x7a7a7a7a bnext = 0x0000000000000000 bDirtyContext = 0x0000000000000000
bstat2 = 0x0
PAGE HEADER:
Page @0x000002CC2D112000
m_pageId = (1:6) m_headerVersion = 1 m_type = 16
m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0x200
m_objId (AllocUnitId.idObj) = 99 m_indexId (AllocUnitId.idInd) = 0 Metadata: AllocUnitId = 6488064
Metadata: PartitionId = 0 Metadata: IndexId = 0 Metadata: ObjectId = 99
m_prevPage = (0:0) m_nextPage = (0:0) pminlen = 90
m_slotCnt = 2 m_freeCnt = 6 m_freeData = 8182
m_reservedCnt = 0 m_lsn = (2501605:3132423:42) m_xactReserved = 0
m_xdesId = (0:0) m_ghostRecCnt = 0 m_tornBits = -431908416
DB Frag ID = 1
Allocation Status
GAM (1:2) = ALLOCATED SGAM (1:3) = NOT ALLOCATED PFS (1:1) = 0x44 ALLOCATED 100_PCT_FULL
DIFF (1:6) = CHANGED ML (1:7) = NOT MIN_LOGGED
DIFF_MAP: Header @0x000000B60C7FA064 Slot 0, Offset 96
status = 0x0
DIFF_MAP: Extent Alloc Status @0x000000B60C7FA0C2
(1:0) - (1:24) = CHANGED
(1:32) - (1:40) = NOT CHANGED
(1:48) - = CHANGED
(1:56) - (1:80) = NOT CHANGED
(1:88) - = CHANGED
(1:96) - (1:104) = NOT CHANGED
(1:112) - (1:128) = CHANGED
(1:136) - (1:152) = NOT CHANGED
(1:160) - (1:168) = CHANGED
(1:176) - = NOT CHANGED
(1:184) - (1:192) = CHANGED
(1:200) - (1:208) = NOT CHANGED
...
但是,查找下一个 DCM 页面需要反复试验。我在已有的 6 页基础上添加了 4'096'000 页(这是错误的,应该只有 512'000 页。感谢Martin Smith指出这一点),但得到的页码略高于下一个 DCM 页面。下一个 DCM 页面可以在标题信息中找到。
GAM (1:4089856) = ALLOCATED SGAM (1:4089857) = NOT ALLOCATED PFS (1:4092528) = 0x0 0_PCT_FULL
DIFF (1:4089862) = NOT CHANGED ML (1:4089863) = NOT MIN_LOGGED
下一个 DCM 页面未记录在标题信息中,因此我假设它应该位于第一个 DCM 页面的m_nextPage
末尾。bit
问题
我的假设是否正确,即 SQL Server 将下一个 DCM 页检测为第一个 DCM 页的最后一位?或者 SQL Server 是否有其他方法来查找第二、第三、第四等 DCM 页?
m_nextPage
在第一个 DCM 页的标题信息中记录下一个 DCM 页不是更有效率吗?