Руководство по архитектуре страниц и экстентов

Применимо к:SQL ServerAzure SQL DatabaseAzure Managed InstanceAzure Synapse Analytics AnalyticsPlatform System (PDW)

Страница является основной единицей хранилища данных в SQL Server. Экстент представляет собой коллекцию из восьми физически смежных страниц. Экстенты помогают эффективно управлять страницами. В этом руководстве описаны структуры данных, используемые для управления страницами и экстентами во всех версиях SQL Server. Понимание архитектуры страниц и экстентов важно для проектирования и разработки эффективных баз данных.

Страницы и экстенты

Основная единица хранения данных в SQL Server — это страница. Пространство на диске, выделенное файлу данных (MDF или NDF) в базе данных, логически делится на страницы, нумеруемые последовательно от 0 до n. Дисковые операции ввода-вывода выполняются на уровне страницы. Это означает, что SQL Server считывает или записывает целые страницы данных.

Экстент — это коллекция, состоящая из восьми физически непрерывных страниц; они используются для эффективного управления страницами. Все страницы организуются в экстенты.

Страницы

В обычной книге все содержимое написано на страницах. Как и в книге, SQL Server записывает все строки данных на страницах, и все страницы данных имеют одинаковый размер: 8 КБ. В книге большинство страниц содержат данные — основное содержимое книги, а некоторые страницы содержат метаданные о содержимом (например, оглавление и индекс). Опять же, SQL Server не отличается: большинство страниц содержат фактические строки данных, хранящиеся пользователями; они называются страницами данных и текстовыми и изображениями (для особых случаев). Страницы индекса содержат ссылки на индексы о том, где находится данные. Наконец, есть системные страницы , которые хранят различные метаданные о организации данных.

Каждая страница начинается с 96-байтового заголовка, который используется для хранения системных данных о странице. Эти данные включают номер страницы, тип страницы, объем свободного места на странице и идентификатор единицы распределения объекта, которому принадлежит страница.

В следующей таблице представлены типы страниц, используемые в файлах данных базы данных SQL Server.

Тип страницы Содержимое
Data Строки данных со всеми данными, кроме текста, ntext, image, nvarchar(max), varchar(max), varbinary(max)и XML-данных, если для текста в строке задано значение ON.
Индекс Содержимое индекса.
Текст и изображение Типы данных больших объектов: text, ntext, image, nvarchar(max), varchar(max), varbinary(max)и xml-данные.

Столбцы переменной длины, когда строка данных превышает 8 КБ: varchar, nvarchar, varbinary и sql_variant.
Глобальная карта распределения (GAM)

Общая глобальная карта распределения (SGAM)
Сведения о том, размещены ли экстенты.
Свободное место на страницах (PFS) Сведения о размещении страниц и доступном на них свободном месте.
Карта выделения индекса (IAM) Сведения об экстентах, используемых таблицей или индексом для единицы распределения.
Схема массовых изменений (Bulk Changed Map, BCM) Сведения об экстентах, измененных массовыми операциями со времени последнего выполнения инструкции BACKUP LOG для единицы распределения.
Схема разностных изменений (Differential Changed Map, DCM) Сведения об экстентах, измененных с момента последнего выполнения инструкции BACKUP DATABASE для единицы распределения.

Заметка

Файлы журналов не содержат страниц. Они содержат ряд записей журнала, которые не имеют фиксированного размера.

Строки данных хранятся на странице последовательно, начиная с заголовка. Таблица смещения строк начинается в конце страницы; каждая таблица смещения строк содержит одну запись для каждой строки на странице. Каждая запись смещения строки сохраняет байт первой байт строки с начала страницы. Таким образом, функция таблицы смещения строк заключается в том, чтобы SQL Server быстро найти строки на странице. Записи в таблице смещения строк находятся в обратном порядке относительно последовательности строк на странице.

Diagram of the SQL Server data page.

Поддержка больших строк

Строки не могут охватывать страницы; однако части строки могут быть перемещены со страницы строки, поэтому строка может быть очень большой. Максимальный объем данных и затрат, содержащихся в одной строке на странице, составляет 8 060 байт. Это не включает данные, хранящиеся в типе страницы текста или изображения.

Это ограничение непринуждается для таблиц, содержащих столбцы varchar, nvarchar, varbinary или sql_variant столбцов. Если общий размер строки всех фиксированных и переменных столбцов таблицы превышает ограничение на 8 060 байтов, SQL Server динамически перемещает один или несколько столбцов переменной длины на страницы в единице выделения ROW_OVERFLOW_DATA, начиная с столбца с наибольшей шириной.

Это действие выполняется всегда, когда в результате операций вставки или обновления общий размер строки выходит за предел в 8060 байт. Когда происходит перемещение столбца на страницу в единице распределения ROW_OVERFLOW_DATA, 24-байтовый указатель на исходной странице в единице распределения IN_ROW_DATA сохраняется. Если при последующей выполняемой операции размер строк уменьшается, SQL Server динамически перемещает столбцы обратно на исходную страницу данных.

Рекомендации по переполнению строк

Строка не может находиться на нескольких страницах и может переполнение, если совокупный размер полей типа данных переменной длины превышает ограничение в 8060 байтов. Чтобы проиллюстрировать, можно создать таблицу с двумя столбцами: один varchar(7000) и другой varchar (2000). По отдельности ни один столбец не превышает 8060 байт, но в сочетании они могли бы сделать это, если ширина каждого столбца заполнена. SQL Server может динамически переместить столбец переменной varchar(7000) на страницы в единице выделения ROW_OVERFLOW_DATA. При объединении столбцов типа varchar, nvarchar, varbinary или sql_variant или CLR, превышающих 8 060 байт на строку, рассмотрим следующее:

  • Перемещение больших записей на другую страницу осуществляется динамически, по мере удлинения записей при операциях обновления. Операции обновления, которые укорачивают записи, могут привести к возвращению записей на исходную страницу в единице распределения IN_ROW_DATA.

    Выполнение запросов и других операций выборки, например сортировки и соединения, в отношении больших записей с превышающими размер страницы данными строки, увеличивает время обработки, поскольку эти записи обрабатываются синхронно, а не асинхронно.

    Поэтому при разработке таблицы с несколькими столбцами типа varchar, nvarchar, varbinary или sql_variant или CLR, определяемых пользователем, учитывайте процент строк, которые, скорее всего, будут передаваться и частоту, с которой эти данные переполнения, скорее всего, будут запрашиваться. Если ожидаются частые запросы по многим превышающим размер страницы данным строки, рекомендуется нормализовать таблицу таким образом, чтобы некоторые столбцы переместились в другую таблицу. После этого запросы по таблице можно будет выполнять с помощью асинхронной операции JOIN.

  • Длина отдельных столбцов по-прежнему должна находиться в пределах 8 000 байт для столбцов типа varchar, nvarchar, varbinary или sql_variant и clR, определяемых пользователем. И только общая их длина может выходить за предел в 8 060 байт на строку таблицы.

  • Сумма других столбцов типа данных, включая данные char и nchar , должна соответствовать ограничению строки 8060 байтов. Данные больших объектов также могут выходить за предел в 8 060 байт на строку.

  • Ключ кластеризованного индекса не может включать в себя столбцы varchar, для которых существуют данные в единице размещения ROW_OVERFLOW_DATA. Если кластеризованный индекс создается для столбца типа varchar и существующие данные располагаются в единице размещения IN_ROW_DATA, то все последующие операции вставки или обновления для данного столбца, выталкивающие данные за пределы строки, будут завершаться ошибкой. Дополнительные сведения об единицах распределения см . в руководстве по архитектуре и проектированию индексов.

  • Пользователь может включить столбцы, которые содержат превышающие размер страницы данные строки, в качестве ключевых или неключевых столбцов некластеризованного индекса.

  • Максимальный размер записи в таблицах, в которых используются разреженные столбцы, составляет 8 018 байт. Если суммарная величина преобразуемых данных и существующих данных записи превышает 8 018 байт, то возвращается ошибка MSSQLSERVER ERROR 576. При преобразовании столбцов между разреженными и непарспарными типами ядро СУБД сохраняет копию текущих данных записи. В связи с этим удваивается количества места, которое требуется для хранения записи.

  • Для получения сведений о таблицах или индексах, которые могут содержать превышающие размер страницы данные строки, используется функция динамического управления sys.dm_db_index_physical_stats.

Экстенты

Экстенты являются основными единицами организации пространства. Экстент состоит из восьми непрерывных страниц или 64 КБ. Это означает, что базы данных SQL Server имеют 16 экстентов на мегабайт.

В SQL Server есть два типа экстентов.

  • Однородные экстенты принадлежат одному объекту, и все восемь страниц экстента может использовать только этот владеющий объект.
  • Смешанные экстенты могут находиться в общем пользовании максимум у восьми объектов. Каждая из восьми страниц в экстенте может находиться во владении разных объектов.

Diagram showing uniform and mixed extents.

Вплоть до SQL Server 2014 (12.x), ядро СУБД не выделяет целые экстенты в таблицах с небольшими объемами данных. Новая таблица или индекс обычно выделяет страницы из смешанных экстентов. При увеличении размера таблицы или индекса до восьми страниц эти таблица или индекс переходят на использование однородных экстентов для последовательных единиц распределения. При создании индекса для существующей таблицы, в которой содержится достаточно строк, чтобы сформировать восемь страниц в индексе, все единицы распределения для индекса находятся в однородных экстентах.

Начиная с SQL Server 2016 (13.x), по умолчанию для большинства выделений в пользовательской базе данных и tempdb используется единообразные экстенты, за исключением выделения, принадлежащие первым восьми страницам цепочки IAM. Выделения для masterбаз msdbmodel данных и баз данных по-прежнему сохраняют предыдущее поведение.

Заметка

В SQL Server вплоть до SQL Server 2014 (12.x) можно использовать флаг трассировки (TF) 1118, чтобы изменить выделение по умолчанию, чтобы всегда использовать универсальные экстенты. Дополнительные сведения об этом флаге трассировки см. в статье DBCC TRACEON — флаги трассировки (Transact-SQL).

Начиная с SQL Server 2016 (13.x), функции, предоставляемые TF 1118, автоматически включены для tempdb всех пользовательских баз данных. Для пользовательских баз данных это поведение управляется SET MIXED_PAGE_ALLOCATIONALTER DATABASEпараметром , при этом значение по умолчанию имеет значение OFF, а TF 1118 не влияет. Дополнительные сведения см. в статье Параметры ALTER DATABASE SET (Transact-SQL).

Начиная с SQL Server 2012 (11.x), системная sys.dm_db_database_page_allocations функция может сообщать сведения о выделении страниц для базы данных, таблицы, индекса и секции.

Внимание

Системная функция sys.dm_db_database_page_allocations не задокументирована и может быть изменена. Совместимость не гарантируется.

Начиная с SQL Server 2019 (15.x), системная функция sys.dm_db_page_info доступна и возвращает сведения о странице в базе данных. Функция возвращает одну строку, содержащую сведения о заголовке со страницы, включая object_id, index_idи partition_id. В большинстве случаев эта функция заменяет потребность в использовании DBCC PAGE.

Управление выделением экстентов и свободным пространством

Структуры данных SQL Server, управляющие размещением экстентов и отслеживанием свободного места, имеют сравнительно простую организацию. Учтите следующие преимущества:

  • Сведения о свободном месте плотно упакованы, поэтому эти данные содержат относительно небольшое количество страниц.

    Это повышает скорость, уменьшая количество операций чтения дисков, необходимых для получения сведений о выделении. Также увеличивается вероятность того, что страницы размещения будут оставаться в памяти и повторных операций чтения не потребуется.

  • Большая часть информации о выделении не объединяется. Это упрощает управление сведениями о размещении.

    Каждое действие по размещению или освобождению страницы может выполняться быстро. Это сокращает состязание между одновременными задачами размещения и освобождения страниц.

Управление выделением экстентов

SQL Server использует два типа карт размещения для записи размещения экстентов:

  • Глобальная карта распределения (GAM)

    На GAM-страницах записано, какие экстенты были размещены. В каждой карте GAM содержится 64 000 экстентов или почти 4 ГБ данных. GAM имеет 1 бит для каждого экстента в интервале, который он охватывает. Если бит имеет 1значение, степень свободна; если бит имеет значение 0, то выделяется экстент.

  • Общая глобальная карта распределения (SGAM)

    На SGAM-страницах записано, какие экстенты в текущий момент используются в качестве смешанных экстентов и имеют как минимум одну неиспользуемую страницу. В каждой карте SGAM содержится 64 000 экстентов или почти 4 ГБ данных. SGAM имеет 1 бит для каждого экстента в интервале, который он охватывает. Если бит имеет значение 1, экстент используется в качестве смешанной экстенты и имеет бесплатную страницу. Если бит имеет 0значение, экстент не используется в качестве смешанной экстенты или используется смешанный экстент и все его страницы.

Каждый экстент обладает следующими наборами битовых шаблонов в картах GAM и SGAM, основанными на его текущем использовании.

Текущее использование экстента Настройка битов карты GAM Настройка битов карты SGAM
Свободно, в текущий момент не используется 1 0
Однородный экстент или заполненный смешанный экстент 0 0
Смешанный экстент со свободными страницами 0 1

Это дает простые алгоритмы управления экстентами страниц.

  • Чтобы выделить единую степень, ядро СУБД выполняет поиск GAM для бита 1 и задает для него значение 0.
  • Чтобы найти смешанный экстент с бесплатными страницами, ядро СУБД выполняет поиск SGAM немного 1 .
  • Чтобы выделить смешанную степень, ядро СУБД выполняет поиск GAM для 1 бита, задает для него 0значение, а затем задает соответствующий бит в SGAM 1.
  • Чтобы освободить степень, ядро СУБД гарантирует, что для бита GAM задано значение , а для бита SGAM задано 1значение 0.

Алгоритмы, которые используются внутри ядра СУБД, более сложны, чем описано в этой статье, так как ядро СУБД равномерно распределяет данные в базе данных. Однако даже настоящие алгоритмы упрощаются из-за того, что отпадает необходимость управления цепочками сведений о размещении экстентов.

Отслеживание свободного места

Страницы Page Free Space (PFS) записывают состояние размещения каждой страницы, информацию о том, была ли размещена конкретная страница, а также количество свободного места на каждой странице. PFS имеет 1 байт для каждой страницы, записывая, выделяется ли страница, и если да, будь то пустая, от 1 до 50 процентов полной, 51 до 80 процентов полной, 81 до 95 процентов полной или 96 до 100 процентов полной.

После размещения экстента на объект ядро СУБД использует PFS-страницы для записи информации о том, какие страницы в экстенте размещены, а какие свободны. Эти сведения используются ядром СУБД при размещении новой страницы. Объем свободного места на странице сохраняется только для кучи и страниц текста или изображения. Это используется при поиске ядром СУБД страницы, имеющей свободное место, которого достаточно для сохранения в ней новой добавляемой строки. Индексы не требуют отслеживания свободного места на странице, так как точка вставки новой строки устанавливается значениями ключа индекса.

В файл данных добавляется новая страница PFS, GAM или SGAM для каждого дополнительного диапазона, который отслеживается. Таким образом, после первой PFS-страницы находится новая PFS-страница с 8088 страницами, а также дополнительные PFS-страницы с последующими интервалами в 8088 страниц. Допустим, страница с идентификатором 1 является PFS-страницей, страница с идентификатором 8088 является PFS-страницей, страница с идентификатором 16176 является PFS-страницей и т. д.

После первой GAM-страницы имеется новая GAM-страница с 64 000 экстентов, которая отслеживает 64 000 экстентов за ней. Последовательность продолжится с интервалом в 64 000. Аналогичным образом после первой SGAM-страницы стоит новая SGAM-страница с 64 000 экстентов, и SGAM-страницы добавляются каждые 64 000 экстентов.

На иллюстрации ниже показана последовательность страниц, используемая ядром СУБД для выделения экстентов и управления ими.

Diagram showing the sequence of pages for managing extents.

Управление пространством, используемым объектами

Страница карты распределения индекса (Index Allocation Map, IAM) сопоставляет экстенты в 4-гигабайтном фрагменте файла базы данных с единицей размещения, использующей этот фрагмент. Единица распределения может иметь один из трех типов.

  • IN_ROW_DATA

    Содержит секцию кучи или индекса.

  • LOB_DATA

    Содержит типы данных больших объектов (LOB), такие как xml, varbinary(max), и varchar(max).

  • ROW_OVERFLOW_DATA

    Содержит данные переменной длины, хранящиеся в varchar, nvarchar, varbinary или sql_variant столбцах, превышающих ограничение размера строки в 8 060 байтов.

В каждой секции кучи или индекса содержится по крайней мере одна единица распределения IN_ROW_DATA. Кроме того, в зависимости от схемы кучи или индекса, там могут содержаться единицы распределения LOB_DATA или ROW_OVERFLOW_DATA.

IAM-страница охватывает в файле диапазон 4 ГБ, то есть столько же, сколько и GAM- или SGAM-страница. Если в единице распределения содержатся экстенты из более чем одного файла или фрагмент файла размером более 4 ГБ, то несколько IAM-страниц будут объединены в IAM-цепочку. Таким образом, каждая единица распределения содержит как минимум одну IAM-страницу для каждого из файлов, в которых содержатся ее экстенты. Для файла может существовать несколько IAM-страниц, если размер экстентов файла, назначенного единице распределения, превышает объем, который может быть записан в одной IAM-странице.

Diagram showing the distribution of IAM pages.

IAM-страницы для каждой единицы распределения выделяются по необходимости и располагаются в файле в случайном порядке. Системное представление sys.system_internals_allocation_units указывает на первую страницу IAM единицы размещения. Все страницы IAM, относящиеся к одной единице размещения, объединяются в цепочку IAM.

Внимание

Системное представление sys.system_internals_allocation_units предназначено только для внутреннего использования и может быть изменено. Совместимость не гарантируется. Это представление недоступно в Базе данных SQL Azure.

Diagram showing IAM pages linked in a chain per allocation unit.

Страница IAM содержит заголовок, указывающий начальную степень диапазона экстентов, сопоставленных страницей IAM. IAM-страница также имеет большую битовую карту, в которой каждый бит представляет экстент. Первый бит схемы представляет первый экстент диапазона, второй бит — второй экстент и т. д. Если это немного 0, то степень, которую она представляет, не выделяется единицам выделения, принадлежащим IAM. Если бит имеет значение 1, то степень, которую она представляет, выделяется единицам выделения, принадлежащим странице IAM.

Когда ядро СУБД должно вставить новую строку и нет свободного места на текущей странице, она использует страницы IAM и PFS для поиска страницы выделения или для кучи или страницы текста или изображения, страницы с достаточным пространством для хранения строки. Ядро СУБД использует IAM-страницы для поиска экстентов, привязанных к единице распределения. Для каждого экстента ядро СУБД просматривает PFS-страницы, чтобы определить наличие страниц, которые можно использовать. Каждая страница IAM и PFS охватывает множество страниц данных, поэтому в базе данных есть несколько страниц IAM и PFS. Это означает, что IAM- и PFS-страницы обычно находятся в памяти буферного пула SQL Server и поиск в них осуществляется очень быстро. Для индексов точка вставки новой строки определяется ключом индекса, но если нужна новая страница, происходит описанный выше процесс.

Ядро СУБД выделяет новую степень единицы выделения только в том случае, если она не может быстро найти страницу в существующем экстенте с достаточным пространством для вставки строки.

Пропорциональное выделение заливки

Ядро СУБД выделяет экстенты из доступных в файловой группе с помощью алгоритма распределения пропорциональной заливки. В одной файловой группе с двумя файлами, если один файл имеет двойное свободное пространство, так как другой, два страницы будут выделены из файла с доступным пространством для каждой страницы, выделенной из другого файла. Это означает, что процент заполнения для каждого из файлов в группе будет примерно одинаковым.

Отслеживание измененных экстентов

SQL Server использует две внутренние структуры данных для отслеживания экстентов, измененных операциями массового копирования, и экстентов, измененных с момента последнего полного резервного копирования. Эти структуры данных существенно ускоряют разностные резервные копии. Они также ускоряют операции записи в журнал массового копирования, если база данных использует модель восстановления с неполным протоколированием. Как и страницы GAM и SGAM, эти структуры представляют собой растровые изображения, в которых каждый бит представляет один экстент.

  • Схема разностных изменений (Differential Changed Map, DCM)

    Эта схема отслеживает экстенты, которые были изменены со времени последнего выполнения инструкции BACKUP DATABASE. Если бит для экстента является 1, то степень была изменена с момента последнего BACKUP DATABASE оператора. Если бит имеет значение 0, экстент не был изменен.

    Чтобы определить, какие экстенты были изменены, разностные резервные копии считывают только страницы DCM. Это существенно сокращает количество страниц, которые должна просмотреть разностная резервная копия. Продолжительность выполнения разностной резервной копии пропорциональна количеству экстентов, измененных с момента последнего BACKUP DATABASE оператора, а не общему размеру базы данных.

  • Схема массовых изменений (Bulk Changed Map, BCM)

    Это отслеживает экстенты, которые были изменены операциями массового ведения журнала с момента последнего BACKUP LOG оператора. Если бит для экстента 1является, то степень была изменена операцией массового ведения журнала после последней BACKUP LOG инструкции. Если бит имеет значение 0, экстент не был изменен операциями с массовым ведением журнала.

    Несмотря на то, что страницы BCM существуют во всех базах данных, они соответствуют только в том случае, если база данных использует модель восстановления с неполным протоколированием. В этой модели восстановления при выполнении инструкции BACKUP LOG процесс резервного копирования проверяет схемы BCM на наличие измененных экстентов. Затем она включает в себя экстенты из резервной копии журнала. Это восстанавливает операции массового ведения журнала, если база данных восстанавливается из резервной копии базы данных и последовательности резервных копий журналов транзакций. Страницы BCM не относятся к базе данных, используюшей простую модель восстановления, так как операции массового ведения журнала не регистрируются. Они не относятся к базе данных, которая использует модель полного восстановления, так как эта модель восстановления обрабатывает операции массового ведения журнала как полностью зарегистрированные операции.

Интервал между DCM- и BCM-страницами равен интервалу между GAM- и SGAM-страницами — 64 000 экстентов. Страницы DCM и BCM находятся за страницами GAM и SGAM в физическом файле следующим образом:

Diagram showing the interval distribution of special pages.

См. также