特定のテーブルのROW_OVERFLOW_DATAページを一覧表示する


11

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

出力は次のようになります。

╔════════╦════════╦══════════════╗
║FileID║PageID║PageTypeDesc║
╠════════╬════════╬══════════════╣
║1║1598║IAM_PAGE║
║3║105368║DATA_PAGE║
║3║105369║NULL║
║3║105370║NULL║
║3║105371║NULL║
║3║105372║NULL║
║3║105373║NULL║
║3║105374║NULL║
║3║105375║NULL║
╚════════╩════════╩══════════════╝

行方不明のROW_OVERFLOW_DATAページを除いて、これは理にかなっています。インデックス割り当てマップページが1つあり、エクステント相当の8KBデータページがあり、実際に割り当てられているページは1つだけです。

同様に、ドキュメント化されていない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)、2つのページのみが表示されます。

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║0║║
╚═════════╩═════════╩════════╩════════╩═══════════ ═╩═════════╩═════════════════╩════════════════════ ═╩════════════════╩══════════╩════════════╩═══════ ══════╩═════════════╩═════════════╩═════════════╩═ ═╝

私が使用して、実際のページの内容を見ればDBCC PAGE、私は同じように、それが見えまだページがROW_OVERFLOW_DATA含まれているかについては何も表示されない-私はおそらくちょうどを見ているかわからない、それが存在しなければならないと確信していました:

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

メモリダンプ行を含めると、結果が大きすぎてここに収まりませんが、これはヘッダー出力です。

╔══════════════╦════════════════════════════════╦═ ══════════════════════════════╦═══════════════════ ════════════╗
║ParentObject║Object║Field║VALUE║
╠══════════════╬════════════════════════════════╬═ ══════════════════════════════╬═══════════════════ ════════════╣
║バッファ:║BUF @ 0x000002437E86D5C0║bページ║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║DBフラグメントID║1║
ページヘッダー:║割り当てステータス║GAM(3:2)║割り当て済み║
ページヘッダー:║割り当てステータス║SGAM(3:3)ALL割り当てられていない║
║ページヘッダー:║割り当てステータス║PFS(3:105144)║0x40 ALLOCATED 0_PCT_FULL║
║ページヘッダー:║割り当てステータス║DIFF(3:6)║変更なし║
║ページヘッダー:║割り当てステータス║ML(3:7)║MIN_LOGGEDではない║
║ページヘッダー:║スロット0オフセット0x60長さ8028║レコードタイプ║PRIMARY_RECORD║
║ページヘッダー:║スロット0オフセット0x60長さ8028║レコード属性║NULL_BITMAP VARIABLE_COLUMNS║
║ページヘッダー:║スロット0オフセット0x60長さ8028║レコードサイズ║8028║
╚══════════════╩════════════════════════════════╩═ ══════════════════════════════╩═══════════════════ ════════════╝

回答:


10

あなたのデモは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の束。


4
切り捨ての警告や何かがあった場合、それは素晴らしいことではないでしょうか。
Max Vernon
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.