zoukankan      html  css  js  c++  java
  • SQL Server 如何计算分配单元 ID?

    如何根据存储在每个页面标题中的 m_objId 和 m_indexId 字段计算分配单元 ID。

    当 DBCC PAGE 转储页头的内容时,它会进行必要的计算和元数据查找,以便能够告诉您分配单元 ID、分区 ID、关系对象 ID 和关系索引 ID。基本上,下面的 DBCC PAGE 输出中以“元数据:”为前缀的所有内容都不会存储在页面本身上:

    Page @0x00000004ED8A2000
    
    m_pageId = (1:445) m_headerVersion = 1 m_type = 1
    m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0xa000
    m_objId (AllocUnitId.idObj) = 97 m_indexId (AllocUnitId.idInd) = 256
    Metadata: AllocUnitId = 72057594044284928
    Metadata: PartitionId = 72057594039304192 Metadata: IndexId = 0
    Metadata: ObjectId = 599673184 m_prevPage = (0:0) m_nextPage = (0:0)
    pminlen = 8 m_slotCnt = 1 m_freeCnt = 8069
    m_freeData = 121 m_reservedCnt = 0 m_lsn = (225:443:22)
    m_xactReserved = 0 m_xdesId = (0:0) m_ghostRecCnt = 0
    m_tornBits = 0 DB Frag ID = 1

    公式如下:

    • 取m_indexId并左移 48,得出值 A
    • 取m_objId并左移 16,得出值 B
    • AllocUnitId = A | B(其中 | 是逻辑 OR 运算)

    使用上面的页面:

    A = 256 << 48 = 72057594037927936
    B = 97 << 16 = 6356992
    AllocUnitId = 72057594044284928

    使用 SQL Server 使用POWER函数执行此操作,因为 X 位的左移与乘以 2 的幂次 X 相同:

    SELECT 256 * CONVERT (BIGINT, POWER (2.0, 48)) | 97 * CONVERT (BIGINT, POWER (2.0, 16));

    然后您可以使用sys.system_internals_allocation_units和sys.partitions执行查找,如下所示:

    SELECT
    [a].[container_id] AS [Partition ID],
    [p].[object_id] AS [Object ID],
    [p].[index_id] AS [Index ID]
    FROM sys.system_internals_allocation_units [a]
    JOIN sys.partitions [p]
    ON [p].[partition_id] = [a].[container_id]
    WHERE
    [a].[allocation_unit_id] = 72057594044284928;
    GO
    
    Partition ID          Object ID   Index ID
    -------------------- ----------- -----------
    72057594039304192     599673184    0

    可以看到这些值与DBCC PAGE输出相匹配。

    要将分配单元 ID 转换为在DBCC PAGE输出中看到的内容:

    m_indexId = AllocUnitId >> 48
    m_objId = ( AllocUnitId – ( m_indexId << 48)) >> 16

    用于此的 T-SQL 涉及浮点数学,因为我们需要使用POWER的倒数:

    DECLARE @alloc BIGINT = 72057594044284928;
    DECLARE @index BIGINT;
    
    SELECT @index =
    CONVERT (BIGINT,
    CONVERT (FLOAT, @alloc)
    * (1 / POWER (2.0, 48)) -- right shift, reciprocal of left shift
    );
    SELECT
    CONVERT (BIGINT,
    CONVERT (FLOAT, @alloc - (@index * CONVERT (BIGINT, POWER (2.0, 48))))
    * (1 / POWER (2.0, 16)) -- right shift, reciprocal of left shift
    ) AS [m_objId],
    @index AS [m_indexId];
    GO
    m_objId               m_indexId
    -------------------- --------------------
    97                    256

    这可以作为对DBCC CHECKDB无法处理的损坏数据库进行编程分析期间,以允许你作为最后的手段提取数据。

  • 相关阅读:
    Qt中暂停线程的执行(主线程和工作线程共用一把锁,一旦主线程将它锁上,工作线程就无法运行了,这也是一个办法)
    罗振宇 知识就是力量:怎样逼自己成为一个上进的人
    GammaRay 是一个允许你查看 Qt 应用程序甚至在某种程度上修改它的独特应用,可谓是 Debugger 的良好补充
    VSCode高效开发插件
    微软白板Excel xls列号数字转字母
    如何渡过中年危机
    增量数据同步中间件
    N位N进制里有多少个N
    Orchard Core学习一
    Consul做服务发现
  • 原文地址:https://www.cnblogs.com/VicLiu/p/15603667.html
Copyright © 2011-2022 走看看