AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 217660
Accepted
Hannah Vernon
Hannah Vernon
Asked: 2018-09-15 11:21:05 +0800 CST2018-09-15 11:21:05 +0800 CST 2018-09-15 11:21:05 +0800 CST

列出特定表的 ROW_OVERFLOW_DATA 页

  • 772

我正在尝试获取具有 ROW_OVERFLOW_DATA 行的表的页面列表。我可以从未记录的 DMV 中获取已分配页面的列表sys.db_db_database_page_allocations,但是,该 DMV 的输出中似乎没有列出 ROW_OVERFLOW_DATA 页面。还有其他一些我根本找不到的 DMV 吗?

最小的、完整的和(希望!)可验证的示例:

USE tempdb;

IF OBJECT_ID(N'dbo.t', N'U') IS NOT NULL
DROP TABLE dbo.t;
GO

CREATE TABLE dbo.t
(
    rownum int NOT NULL IDENTITY(1,1)
        PRIMARY KEY CLUSTERED
    , on_row_data varchar(30) NOT NULL
        DEFAULT ('on_row_data')
    , off_row_data varchar(MAX) NOT NULL
        DEFAULT REPLICATE('A', 20000) --PLENTY BIG ENOUGH!
) WITH (DATA_COMPRESSION = NONE); --not compressing those pages!

INSERT INTO dbo.t DEFAULT VALUES;

DECLARE @ObjectID int = (SELECT o.object_id FROM sys.objects o WHERE o.name = 't');
DECLARE @PageID int;
DECLARE @PageTypeDesc varchar(100);

SELECT FileID = dpa.allocated_page_file_id
    , PageID = dpa.allocated_page_page_id
    , PageTypeDesc = dpa.page_type_desc
FROM sys.dm_db_database_page_allocations(DB_ID(), @ObjectID, NULL, NULL, 'DETAILED') dpa

输出看起来像:

╔════════╦════════╦══════════════╗
║ 文件 ID ║ 页面 ID ║ PageTypeDesc ║
╠════════╬════════╬══════════════╣
║ 1 ║ 1598 ║ IAM_PAGE ║
║ 3 ║ 105368 ║ DATA_PAGE ║
║ 3 ║ 105369 ║ 空 ║
║ 3 ║ 105370 ║ 空 ║
║ 3 ║ 105371 ║ 空 ║
║ 3 ║ 105372 ║ 空 ║
║ 3 ║ 105373 ║ 空 ║
║ 3 ║ 105374 ║ 空 ║
║ 3 ║ 105375 ║ 空 ║
╚════════╩════════╩══════════════╝

这是有道理的,除了缺少 ROW_OVERFLOW_DATA 页面。我们有一个单独的索引分配映射页面,以及一个完整的 8KB 数据页面,其中只有一个实际分配了页面。

同样,如果我使用未记录的sys.fn_PhysLocCracker函数来显示每行所在的页面,如:

SELECT *
FROM dbo.t
CROSS APPLY sys.fn_PhysLocCracker(%%PHYSLOC%%)

我只看到DATA_PAGE列出的:

╔════════╦═════════════╦═════════════════════╦════ ═════╦═════════╦═════════╗
║ rownum ║ on_row_data ║ off_row_data ║ file_id ║ page_id ║ slot_id ║
╠════════╬═════════════╬═════════════════════╬════ ═════╬═════════╬═════════╣
║ 1 ║ on_row_data ║ AAAAAAAAAAAAAAAAAAA ║ 3 ║ 105368 ║ 0 ║
╚════════╩═════════════╩═════════════════════╩════ ═════╩═════════╩═════════╝

同样,如果我使用,DBCC IND(database, table, index)我只会看到列出的两个页面:

DBCC IND (tempdb, t, 1);

输出:

╔═════════╦═════════╦════════╦════════╦═══════════ ═╦═════════╦═════════════════╦════════════════════ ═╦════════════════╦══════════╦════════════╦═══════ ══════╦═════════════╦═════════════╦═════════════╦═ ═╗
║ PageFID ║ PagePID ║ IAMFID ║ IAMPID ║ ObjectID ║ IndexID ║ PartitionNumber ║ PartitionID ║ iam_chain_type ║ PageType ║ IndexLevel ║ NextPageFID ║ NextPagePID ║ PrevPageFID ║ PrevPagePID ║ ║
╠═════════╬═════════╬════════╬════════╬═══════════ ═╬═════════╬═════════════════╬════════════════════ ═╬════════════════╬══════════╬════════════╬═══════ ══════╬═════════════╬═════════════╬═════════════╬═ ═╣
║ 1 ║ 1598 ║ NULL ║ NULL ║ 2069582411 ║ 1 ║ 1 ║ 6989586877272752128 ║ 行内数据 ║ 10 ║ NULL ║ 0 ║ 0 ║ 0 ║ 0 ║
║ 3 ║ 105368 ║ 1 ║ 1598 ║ 2069582411 ║ 1 ║ 1 ║ 6989586877272752128 ║ 行内数据 ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ ║
╚═════════╩═════════╩════════╩════════╩═══════════ ═╩═════════╩═════════════════╩════════════════════ ═╩════════════════╩══════════╩════════════╩═══════ ══════╩═════════════╩═════════════╩═════════════╩═ ═╝

如果我查看实际页面内容,使用DBCC PAGE,看起来我仍然看不到关于哪个页面包含 ROW_OVERFLOW_DATA 的任何信息 - 我确定它一定在那里,我可能只是不知道要看什么:

DBCC PAGE (tempdb, 3, 105368 , 3) WITH TABLERESULTS;

如果我包括内存转储行,结果太大而不适合这里,但这是标头输出:

╔══════════════╦════════════════════════════════╦═ ══════════════════════════════╦═══════════════════ ════════════╗
║ 父对象 ║ 对象 ║ 字段 ║ 值 ║
╠══════════════╬════════════════════════════════╬═ ══════════════════════════════╬═══════════════════ ════════════╣
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ bpage ║ 0x000002431A8A2000 ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ bhash ║ 0x0000000000000000 ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ bpageno ║ (3:105368) ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ bdbid ║ 2 ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ 参考 ║ 0 ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ bcputicks ║ 0 ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ bsampleCount ║ 0 ║
║ 缓冲器: ║ BUF @0x000002437E86D5C0 ║ bUse1 ║ 63172 ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ bstat ║ 0x10b ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ 博客 ║ 0x212121cc ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ bnext ║ 0x0000000000000000 ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ bDirtyContext ║ 0x000002435DA77160 ║
║ 缓冲区: ║ BUF @0x000002437E86D5C0 ║ bstat2 ║ 0x0 ║
║ 页眉: ║ 页@0x000002431A8A2000 ║ m_pageId ║ (3:105368) ║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ m_headerVersion ║ 1 ║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ m_type ║ 1 ║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ m_typeFlagBits ║ 0x0 ║
║页眉:║页@0x000002431A8A2000║m_level║0║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ m_flagBits ║ 0xc000 ║
║ 页眉: ║ 页@0x000002431A8A2000 ║ m_objId (AllocUnitId.idObj) ║ 3920762 ║
║ 页眉: ║ 页@0x000002431A8A2000 ║ m_indexId (AllocUnitId.idInd) ║ 512 ║
║页眉:║页面@0x000002431A8A2000║元数据:AllocUnitId║144115445026914304║
║页眉:║页面@0x000002431A8A2000║元数据:PartitionId║6989586877272752128║
║ 页眉:║ 页 @0x000002431A8A2000 ║ 元数据:IndexId ║ 1 ║
║页眉:║页面@0x000002431A8A2000║元数据:ObjectId║2069582411║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ m_prevPage ║ (0:0) ║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ m_nextPage ║ (0:0) ║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ pminlen ║ 8 ║
║ 页眉: ║ 页@0x000002431A8A2000 ║ m_slotCnt ║ 1 ║
║ 页眉: ║ 页@0x000002431A8A2000 ║ m_freeCnt ║ 66 ║
║ 页眉: ║ 页@0x000002431A8A2000 ║ m_freeData ║ 8124 ║
║ 页眉: ║ 页@0x000002431A8A2000 ║ m_reservedCnt ║ 0 ║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ m_lsn ║ (36:47578:1) ║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ m_xactReserved ║ 0 ║
║ 页眉: ║ 页@0x000002431A8A2000 ║ m_xdesId ║ (0:0) ║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ m_ghostRecCnt ║ 0 ║
║ 页眉: ║ 页@0x000002431A8A2000 ║ m_tornBits ║ 0 ║
║ 页眉: ║ 页 @0x000002431A8A2000 ║ 数据库片段 ID ║ 1 ║
║ 页眉: ║ 分配状态 ║ GAM (3:2) ║ 已分配 ║
║ 页眉: ║ 分配状态 ║ SGAM (3:3) ║ 未分配 ║
║ 页眉: ║ 分配状态 ║ PFS (3:105144) ║ 0x40 ALLOCATED 0_PCT_FULL ║
║ 页眉: ║ 分配状态 ║ 差异 (3:6) ║ 未更改 ║
║ 页眉: ║ 分配状态 ║ ML (3:7) ║ NOT MIN_LOGGED ║
║ PAGE HEADER: ║ Slot 0 Offset 0x60 Length 8028 ║ Record Type ║ PRIMARY_RECORD ║
║ PAGE HEADER: ║ Slot 0 Offset 0x60 Length 8028 ║ Record Attributes ║ NULL_BITMAP VARIABLE_COLUMNS ║
║ 页眉: ║ 槽 0 偏移量 0x60 长度 8028 ║ 记录大小 ║ 8028 ║
╚══════════════╩════════════════════════════════╩═ ══════════════════════════════╩═══════════════════ ════════════╝
sql-server database-internals
  • 1 1 个回答
  • 306 Views

1 个回答

  • Voted
  1. Best Answer
    Josh Darnell
    2018-09-15T12:10:45+08:002018-09-15T12:10:45+08:00

    您的演示受到REPLICATE 限制的影响:

    如果 string_expression 不是 varchar(max) 或 nvarchar(max) 类型,REPLICATE 会将返回值截断为 8,000 字节。要返回大于 8,000 字节的值,必须将 string_expression 显式转换为适当的大值数据类型。

    如果我这样做:

    INSERT INTO dbo.t (off_row_data) VALUES (REPLICATE(CAST('A' as varchar(max)), 20000));
    

    然后从上方针对 dm_db_database_page_allocations 运行您的 DMV 查询,我得到 PageTypeDesc 为TEXT_MIX_PAGE.

    然后,我可以在启用跟踪标志 3604 的情况下运行 DBCC PAGE,以查看该行外页面的详细信息:

    DBCC TRACEON (3604);
    GO
    DBCC PAGE (TestDB, 1, 20696 , 3) -- your page will be different :)
    

    输出很大,但在开始附近您会看到:

    Blob row at: Page (1:20696) Slot 0 Length: 3934 Type: 3 (DATA)
    

    然后,你知道,一堆 A。

    • 10

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve