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无法处理的损坏数据库进行编程分析期间,以允许你作为最后的手段提取数据。

  • 相关阅读:
    mybatis+spring报错PropertyAccessException 1: org.springframework.beans.MethodInvocationException
    jQuery实现判断li的个数从而实现其他功能
    移动平台对 meta 标签的定义
    移动平台对 meta 标签的定义
    HTML5手机网站开发页面宽度解决方案
    HTML5手机网站开发页面宽度解决方案
    别做“不会思考的码农”
    别做“不会思考的码农”
    myeclipse+spket1.6+Extjs4.2开发环境搭建
    myeclipse+spket1.6+Extjs4.2开发环境搭建
  • 原文地址:https://www.cnblogs.com/VicLiu/p/15603667.html
Copyright © 2011-2022 走看看