Belirli bir tablo için ROW_OVERFLOW_DATA sayfalarını listeleyin


11

ROW_OVERFLOW_DATA içeren satırları olan bir tablo için sayfaların listesini almaya çalışıyorum. sys.db_db_database_page_allocationsAyrılmamış DMV'den ayrılan sayfaların listesini alabilirim , ancak bu DMV'nin çıktısında listelenen ROW_OVERFLOW_DATA sayfası yok gibi görünüyor. Sadece bulamadığım başka bir DMV var mı?

Minimum, tam ve (umarım!) Doğrulanabilir örnek:

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

Çıktı şöyle görünür:

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

Bu, eksik ROW_OVERFLOW_DATA sayfası dışında bir anlam ifade ediyor. Tek bir dizin ayırma harita sayfamız ve 8 KB'lik veri sayfalarının tam bir uzantısına sahibiz.

Benzer şekilde, sys.fn_PhysLocCrackerher satırın bulunduğu sayfayı göstermek için belgesiz işlevini kullanırsam, olduğu gibi:

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

Sadece DATA_PAGElistelenenleri görüyorum :

╔════════╦═════════════╦═════════════════════╦════ ═════╦═════════╦═════════╗
║ rownum ║ on_row_data ║ off_row_data ║ dosya_kimliği ║ sayfa_kimliği ║ slot_id ║
╠════════╬═════════════╬═════════════════════╬════ ═════╬═════════╬═════════╣
║ 1 ║ on_row_data ║ AAAAAAAAAAAAAAAAAAA ║ 3 ║ 105368 ║ 0 ║
╚════════╩═════════════╩═════════════════════╩════ ═════╩═════════╩═════════╝

Benzer şekilde, kullanırsam DBCC IND(database, table, index)yalnızca listelenen iki sayfayı görüyorum:

DBCC IND (tempdb, t, 1);

Çıktı:

╔═════════╦═════════╦════════╦════════╦═══════════ ═╦═════════╦═════════════════╦════════════════════ ═╦════════════════╦══════════╦════════════╦═══════ ══════╦═════════════╦═════════════╦═════════════╦═ ═╗
║ PageFID ║ PagePID ║ IAMFID ║ IAMPID ║ ObjectID ║ Dizin Kimliği ID PartitionNumber ║ PartitionID ║ iam_chain_type ║ PageType ║ DizinSeviyesi ║ NextPageFID ║ NextPagePID ║ PrevPageFID ║ PrePPagePID ║ ║║
╠═════════╬═════════╬════════╬════════╬═══════════ ═╬═════════╬═════════════════╬════════════════════ ═╬════════════════╬══════════╬════════════╬═══════ ══════╬═════════════╬═════════════╬═════════════╬═ ═╣
║ 1 ║ 1598 ║ NULL ║ NULL ║ 2069582411 ║ 1 ║ 1 ║ 6989586877272752128 ║ Satır içi veriler ║ 10 ║ NULL ║ 0 ║ 0 ║ 0 ║ 0 ║ ║
║ 3 ║ 105368 ║ 1 ║ 1598 ║ 2069582411 ║ 1 ║ 1 ║ 6989586877272752128 ║ Satır içi veriler ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ ║
╚═════════╩═════════╩════════╩════════╩═══════════ ═╩═════════╩═════════════════╩════════════════════ ═╩════════════════╩══════════╩════════════╩═══════ ══════╩═════════════╩═════════════╩═════════════╩═ ═╝

Kullanarak gerçek sayfa içeriğine bakarsanız, hala hangi sayfanın ROW_OVERFLOW_DATA içerdiği hakkında bir şey görmüyorum DBCC PAGEgibi görünüyor - orada olması gerektiğine eminim, muhtemelen sadece neye bakacağımı bilmiyorum:

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

Bellek dökümü satırlarını dahil edersem sonuçlar buraya sığmayacak kadar büyük, ancak bu başlık çıktısı:

╔══════════════╦════════════════════════════════╦═ ══════════════════════════════╦═══════════════════ ════════════╗
║ ParentObject ║ Nesne ║ Alan ║ DEĞER ║
╠══════════════╬════════════════════════════════╬═ ══════════════════════════════╬═══════════════════ ════════════╣
║ ARABELLEĞİ: ║ BUF @ 0x000002437E86D5C0 ║ bpage ║ 0x000002431A8A2000 ║
║ ARABELLEK: ║ BUF @ 0x000002437E86D5C0 ║ bhash ║ 0x0000000000000000 ║
║ TAMPON: ║ BUF @ 0x000002437E86D5C0 0 bpageno ║ (3: 105368) ║
║ ARABELLEĞİ: ║ BUF @ 0x000002437E86D5C0 ║ bdbid ║ 2 ║
║ ARABELLEĞİ: ║ BUF @ 0x000002437E86D5C0 ferences breferences ║ 0 ║
║ TAMPON: ║ BUF @ 0x000002437E86D5C0 ║ bcputicks ║ 0 ║
║ TAMPON: ║ BUF @ 0x000002437E86D5C0 ║ bsampleCount ║ 0 ║
║ ARABELLEĞİ: ║ BUF @ 0x000002437E86D5C0 ║ bUse1 ║ 63172 ║
║ ARABELLEĞİ: ║ BUF @ 0x000002437E86D5C0 ║ bstat ║ 0x10b ║
║ TAMPON: ║ BUF @ 0x000002437E86D5C0 ║ blog ║ 0x212121cc ║
║ ARABELLEĞİ: ║ BUF @ 0x000002437E86D5C0 ║ bnext ║ 0x0000000000000000 ║
║ ARABELLEĞİ: ║ BUF @ 0x000002437E86D5C0 ║ bDirtyContext ║ 0x000002435DA77160 ║
║ ARABELLEK: ║ BUF @ 0x000002437E86D5C0 ║ bstat2 ║ 0x0 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_pageId ║ (3: 105368) ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_headerSürüm ║ 1 ║
║ PAGE HEADER: ║ Sayfa @ 0x000002431A8A2000 ║ m_type ║ 1 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_typeFlagBits ║ 0x0 ║
║ PAGE HEADER: ║ Sayfa @ 0x000002431A8A2000 ║ m_level ║ 0 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_flagBits ║ 0xc000 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_objId (AllocUnitId.idObj) ║ 3920762 ║
║ PAGE HEADER: ║ Sayfa @ 0x000002431A8A2000 ║ m_indexId (AllocUnitId.idInd) ║ 512 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ Meta veriler: AllocUnitId ║ 144115445026914304 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ Meta veriler: PartitionId ║ 6989586877272752128 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ Meta veriler: IndexId ║ 1 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ Meta veriler: ObjectId ║ 2069582411 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_prevPage ║ (0: 0) ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_nextSayfa ║ (0: 0) ║
║ PAGE HEADER: ║ Sayfa @ 0x000002431A8A2000 ║ pminlen ║ 8 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_slotCnt ║ 1 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_freeCnt ║ 66 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_freeData ║ 8124 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_reservedCnt ║ 0 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_lsn ║ (36: 47578: 1) ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_xactReserved ║ 0 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_xdesId ║ (0: 0) ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ m_ghostRecCnt ║ 0 ║
║ PAGE HEADER: ║ Sayfa @ 0x000002431A8A2000 ║ m_tornBits ║ 0 ║
║ SAYFA BAŞLIĞI: ║ Sayfa @ 0x000002431A8A2000 ║ DB Parça Kimliği ║ 1 ║
║ SAYFA BAŞLIĞI: ║ Tahsis Durumu ║ GAM (3: 2) ║ TAHSİSLİ ║
AGE SAYFA BAŞLIĞI: ║ Tahsis Durumu ║ SGAM (3: 3) ║ TAHSİS EDİLMİYOR ║
║ SAYFA BAŞLIĞI: ║ Tahsis Durumu ║ PFS (3: 105144) ║ 0x40 TAHSİSLİ 0_PCT_FULL ║
║ SAYFA BAŞLIĞI: ║ Tahsis Durumu ║ DİFF (3: 6) ║ DEĞİŞTİRİLMEMİŞ ║
║ SAYFA BAŞLIĞI: ║ Tahsis Durumu ║ ML (3: 7) ║ MIN_LOGGED DEĞİL ║
║ SAYFA BAŞLIĞI: ║ Yuva 0 Ofset 0x60 Uzunluk 8028 ║ Kayıt Türü ║ PRIMARY_RECORD ║
║ SAYFA BAŞLIĞI: ║ Yuva 0 Ofset 0x60 Uzunluk 8028 ║ Kayıt Özellikleri ║ NULL_BITMAP VARIABLE_COLUMNS ║
║ SAYFA BAŞLIĞI: ║ Yuva 0 Ofset 0x60 Uzunluk 8028 ║ Kayıt Boyutu ║ 8028 ║
╚══════════════╩════════════════════════════════╩═ ══════════════════════════════╩═══════════════════ ════════════╝

Yanıtlar:


10

Demonuz REPLICATE sınırlamasıyla vuruluyor :

String_expression, varchar (max) veya nvarchar (max) türünde değilse, REPLICATE dönüş değerini 8.000 bayt olarak keser. 8.000 bayttan büyük değerleri döndürmek için, string_expression ifadesinin açıkça uygun büyük değer veri türüne dönüştürülmesi gerekir.

Bunu yaparsam:

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

Ve sonra DMV sorgunuzu yukarıdan dm_db_database_page_allocations karşı çalıştırın, PageTypeDesc ile sayfalar olsun TEXT_MIX_PAGE.

Daha sonra bu off-line sayfanın ayrıntılarını görmek için izleme bayrağı 3604 etkin DBCC PAGE çalıştırabilirsiniz:

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

Çıktı büyük, ancak başlangıca yakın bir yerde göreceksiniz:

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

Ve sonra, bilirsiniz, bir grup A.


4
Bir kesme uyarısı ya da bir şey olsaydı, güzel olmaz mıydı.
Max Vernon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.