Daftarkan halaman ROW_OVERFLOW_DATA untuk tabel tertentu


11

Saya mencoba mendapatkan daftar halaman untuk tabel yang memiliki baris dengan ROW_OVERFLOW_DATA. Saya bisa mendapatkan daftar halaman yang dialokasikan dari DMV tidak berdokumen sys.db_db_database_page_allocations, namun, tampaknya tidak ada halaman ROW_OVERFLOW_DATA yang tercantum dalam output DMV itu. Apakah ada DMV lain yang tidak bisa saya temukan?

Contoh minimal, lengkap, dan (mudah-mudahan!) Dapat diverifikasi:

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

Outputnya seperti:

╔════════╦════════╦══════════════╗
║ 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 ║
╚════════╩════════╩══════════════╝

Yang masuk akal, selain halaman ROW_OVERFLOW_DATA yang hilang. Kami memiliki halaman peta alokasi indeks tunggal, dan nilai penuh dari halaman data 8KB, dengan hanya satu halaman yang benar-benar dialokasikan.

Demikian pula, jika saya menggunakan sys.fn_PhysLocCrackerfungsi tidak berdokumen untuk menampilkan halaman tempat setiap baris, seperti pada:

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

Saya hanya melihat yang DATA_PAGEterdaftar:

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

Demikian juga, jika saya menggunakan DBCC IND(database, table, index)saya hanya melihat dua halaman yang tercantum:

DBCC IND (tempdb, t, 1);

Keluaran:

╔═════════╦═════════╦════════╦════════╦═══════════ ═╦═════════╦═════════════════╦════════════════════ ═╦════════════════╦══════════╦════════════╦═══════ ══════╦═════════════╦═════════════╦═════════════╦═ ═╗
║ PageFID ║ PagePID ║ IAMFID ║ IAMPID ║ ObjectID ║ IndexID ║ PartitionNumber ║ PartitionID ║ iam_chain_type ║ HalamanType ║ IndexLevel ║ NextPageFID ║ NextPagePID ║ PrevPageFID ║ PrevPagePID ║ ║
╠═════════╬═════════╬════════╬════════╬═══════════ ═╬═════════╬═════════════════╬════════════════════ ═╬════════════════╬══════════╬════════════╬═══════ ══════╬═════════════╬═════════════╬═════════════╬═ ═╣
║ 1 ║ 1598 ║ NULL ║ NULL ║ 2069582411 ║ 1 ║ 1 ║ 6989586877272752128 ║ Data dalam baris ║ 10 ║ NULL ║ 0 ║ 0 ║ 0 ║ 0 ║ ║ ║
║ 3 ║ 105368 ║ 1 ║ 1598 ║ 2069582411 ║ 1 ║ 1 ║ 6989586877272752128 ║ Data dalam baris ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ ║
╚═════════╩═════════╩════════╩════════╩═══════════ ═╩═════════╩═════════════════╩════════════════════ ═╩════════════════╩══════════╩════════════╩═══════ ══════╩═════════════╩═════════════╩═════════════╩═ ═╝

Jika saya melihat isi halaman yang sebenarnya, menggunakan DBCC PAGE, sepertinya saya masih tidak melihat apa-apa tentang halaman mana yang berisi ROW_OVERFLOW_DATA - saya yakin pasti ada di sana, saya mungkin tidak tahu harus melihat apa:

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

Hasilnya terlalu besar untuk muat di sini, jika saya memasukkan baris dump memori, tapi ini adalah output header:

╔══════════════╦════════════════════════════════╦═ ══════════════════════════════╦═══════════════════ ════════════╗
║ ParentObject ║ Obyek ║ Bidang ║ VALUE ║
╠══════════════╬════════════════════════════════╬═ ══════════════════════════════╬═══════════════════ ════════════╣
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bpage ║ 0x000002431A8A2000 ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bhash ║ 0x000000000000000000 ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bpageno ║ (3: 105368) ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bdbid ║ 2 ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ breferences ║ 0 ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bcputicks ║ 0 ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bsampleCount ║ 0 ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bUse1 ║ 63172 ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bstat ║ 0x10b ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ blog ║ 0x212121cc ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bnext ║ 0x000000000000000000 ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bDirtyContext ║ 0x000002435DA77160 ║
║ BUFFER: ║ BUF @ 0x000002437E86D5C0 ║ bstat2 ║ 0x0 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_pageId ║ (3: 105368) ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_headerVersion ║ 1 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_type ║ 1 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_typeFlagBits ║ 0x0 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_level ║ 0 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_flagBits ║ 0xc000 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_objId (AllocUnitId.idObj) ║ 3920762 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_indexId (AllocUnitId.idInd) ║ 512 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ Metadata: AllocUnitId ║ 144115445026914304 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ Metadata: PartitionId ║ 6989586877272752128 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ Metadata: IndexId ║ 1 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ Metadata: ObjectId ║ 2069582411 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_prevPage ║ (0: 0) ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_nextPage ║ (0: 0) ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ pminlen ║ 8 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_slotCnt ║ 1 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_freeCnt ║ 66 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_freeData ║ 8124 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_reservedCnt ║ 0 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_lsn ║ (36: 47578: 1) ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_xactRerverved ║ 0 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_xdesId ║ (0: 0) ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_ghostRecCnt ║ 0 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ m_tornBits ║ 0 ║
║ PAGE HEADER: ║ Halaman @ 0x000002431A8A2000 ║ DB Frag ID ║ 1 ║
║ PAGE HEADER: ║ Status Alokasi ║ GAM (3: 2) ║ ALOKASI ║
║ PAGE HEADER: ║ Status Alokasi ║ SGAM (3: 3) ║ TIDAK DIALOKASI ║
║ PAGE HEADER: ║ Status Alokasi ║ PFS (3: 105144) ║ 0x40 ALOKASI 0_PCT_FULL ║
║ PAGE HEADER: ║ Status Alokasi ║ DIFF (3: 6) ║ TIDAK BERUBAH ║
║ PAGE HEADER: ║ Status Alokasi ║ ML (3: 7) ║ TIDAK MIN_LOGGED ║
║ PAGE HEADER: ║ Slot 0 Offset 0x60 Panjang 8028 ║ Tipe Rekaman ║ PRIMARY_RECORD ║
║ PAGE HEADER: ║ Slot 0 Offset 0x60 Panjang 8028 ║ Catat Atribut ║ NULL_BITMAP VARIABLE_COLUMNS ║
║ PAGE HEADER: ║ Slot 0 Offset 0x60 Panjang 8028 ║ Ukuran Rekam ║ 8028 ║
╚══════════════╩════════════════════════════════╩═ ══════════════════════════════╩═══════════════════ ════════════╝

Jawaban:


10

Demo Anda terkena batasan REPLICATE :

Jika string_expression bukan dari tipe varchar (max) atau nvarchar (max), REPLICATE memotong nilai kembali pada 8.000 byte. Untuk mengembalikan nilai lebih dari 8.000 byte, string_expression harus secara eksplisit dilemparkan ke tipe data bernilai besar yang sesuai.

Jika saya melakukan ini:

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

Dan kemudian jalankan permintaan DMV Anda dari atas terhadap dm_db_database_page_allocations, saya mendapatkan halaman dengan PageTypeDesc dari TEXT_MIX_PAGE.

Saya kemudian dapat menjalankan PAGE DBCC dengan jejak bendera 3604 diaktifkan untuk melihat rincian halaman off-baris:

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

Outputnya besar, tetapi di dekat awal Anda akan melihat:

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

Dan kemudian, Anda tahu, banyak nilai A.


4
Bukankah lebih baik jika ada peringatan pemotongan atau sesuatu.
Max Vernon
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.