22.12.25

Любопытный случай… с object ID 99

Автор: Paul Randal, The Curious Case of… object ID 99

Сегодня я отвечал на вопрос под тегом #sqlhelp в Twitter и упомянул об использовании значения object ID 99, потому что SQL Server никогда не присвоит таблице идентификатор объекта 99. И я подумал, что это станет хорошей темой для небольшой записи в блоге.

Так что же такое object ID 99? Это зарезервированный идентификатор объекта, который механизм хранения (Storage Engine) использует для любых страниц файла данных, которые являются частью системы распределения и не принадлежат реальной таблице. Список таких страниц включает, например, страницы заголовка файла, страницы PFS, страницы GAM, загрузочную страницу и так далее — страницы, используемые системой распределения для отслеживания того, что происходит на уровне базы данных. Он не включает страницы IAM, так как они являются частью таблицы.

Подробнее о различных страницах распределения можно прочитать в моей статье GAM, SGAM, PFS и другие карты распределения.

Давайте посмотрим на заголовок страницы GAM:

DBCC TRACEON (3604);
DBCC PAGE (N'master', 1, 2, 0); -- имя базы, ID файла, ID страницы, стиль дампа
-- Страница (1,2) — это первая страница GAM в файле данных
-- Стиль дампа 0 = только заголовок страницы
GO
Page @0x00000002F83A6000

m_pageId = (1:2)                    m_headerVersion = 1                 m_type = 8
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x0
m_objId (AllocUnitId.idObj) = 99    m_indexId (AllocUnitId.idInd) = 0   Metadata: AllocUnitId = 6488064
Metadata: PartitionId = 0           Metadata: IndexId = 0               Metadata: ObjectId = 99
m_prevPage = (0:0)                  m_nextPage = (0:0)                  pminlen = 90
m_slotCnt = 2                       m_freeCnt = 6                       m_freeData = 8182
m_reservedCnt = 0                   m_lsn = (5081:482:5)                m_xactReserved = 0
m_xdesId = (0:0)                    m_ghostRecCnt = 0                   m_tornBits = 39122617
DB Frag ID = 1

Вы можете видеть, что значение m_objId равно 99. С момента выхода SQL Server 2005 страницы распределения — это единственные страницы, где m_objId является фактическим идентификатором объекта. Во всех остальных случаях m_objId и m_indexId являются производными от идентификатора единицы распределения, к которой принадлежит страница, а идентификатор единицы распределения, выводимый командой DBCC PAGE, рассчитывается как:

(m_objId << 16) | (m_indexId << 48)

(где << означает сдвиг влево, а | — логическое ИЛИ)

Подробнее об этом можно прочитать в моём посте Как вычисляются идентификаторы единиц распределения?.

Единственный другой «нереальный» идентификатор объекта, который вы можете увидеть, — это значение 0, о котором сообщает DBCC CHECKDB, когда он не может определить, какому объекту действительно принадлежит страница. Подробности см. в Disaster recovery 101: Object ID 0, index ID -1, partition ID 0.




Комментариев нет:

Отправить комментарий