Resumo/Resumo;
Ao analisar a primeira página do DCM em um banco de dados (que documenta quais extensões foram modificadas, para que o processo de backup DIFF não precise verificar todo o banco de dados em busca de alterações, mas possa pular para as extensões para verificar as páginas que foram alteradas), onde está o local da próxima página do DCM documentada?
Eu teria pensado que isso seria documentado no m_nextPage
atributo do cabeçalho da página. Mas ao verificar, isso não parece ser o caso.
Encontrando as páginas do DCM
Eu estava instruindo nosso aprendiz sobre o que os backups diferenciais contêm e como o DBMS documenta as alterações nas páginas individuais e depois na página consolidada do DCM.
Referência: Guia de arquitetura de páginas e extensões (Microsoft Learn | SQL)
Comecei então a brincar com um banco de dados muito grande e executei os seguintes comandos:
DBCC TRACEON (3604);
DBCC PAGE ( 6, 1, 0, 3 ); -- File Header
Isso produziu a seguinte saída:
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
Depois de ler o resultado, notei a informação perto do final e presumi (corretamente) que a página do DCM estaria localizada na página número 6 (bem, 7 na verdade, mas...).
Vamos dar uma olhada:
DBCC PAGE ( 6, 1, 6, 0 ); -- 1. DCM Page
Sim, estas parecem ser as primeiras páginas do 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
...
No entanto, encontrar a próxima página do DCM foi uma tentativa e erro. Adicionei 4'096'000 páginas às 6 que eu já tinha (o que está errado, deveria ser apenas 512'000 páginas. Obrigado Martin Smith por apontar isso), mas recebi um número de página um pouco maior do que a próxima página do DCM. A próxima página do DCM pode ser encontrada nas informações do cabeçalho.
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
A próxima página do DCM não está documentada nas m_nextPage
informações do cabeçalho, então presumo que ela deva estar na última página bit
da primeira página do DCM.
Questões
Minha suposição está correta de que o SQL Server detecta a próxima página do DCM como o último bit da primeira página do DCM? Ou o SQL Server tem outros meios de encontrar a segunda, terceira, quarta, etc. páginas do DCM?
Não seria mais eficiente documentar a próxima página do DCM nas
m_nextPage
informações de cabeçalho da primeira página do DCM?
Ele está localizado no mesmo deslocamento no próximo intervalo GAM que os DCMs por intervalo GAM, pois eles rastreiam extensões (que são aproximadamente 4 GB).
Observe que este é um intervalo conhecido (GAM) e é mais rápido calcular a localização com base no valor conhecido do que ler a página e obter o valor do próximo item.
Correto. Aqui está um exemplo concreto, o primeiro DCM está na 7ª página (número de página 6, pois é baseado em 0) e o intervalo GAM é 511232 páginas, então o próximo DCM está em 511232 + 6 = Página 511238. Captura de tela abaixo para saída de exemplo.