Oracle для профессионалов

         

Файлы данных


Файлы данных вместе с файлами журнала повторного выполнения являются наиболее важными в базе данных. Именно в них хранятся все данные. В каждой базе данных есть хотя бы один файл данных, но обычно их намного больше. Только самые простые, "тестовые" базы данных имеют один файл данных. В любой реальной базе данных должно быть минимум два файла данных: один — для системных данных (табличное пространство SYSTEM), другой — для пользовательских (табличное пространство USER). В этом разделе мы рассмотрим организацию файлов данных в Oracle и способы хранения данных в этих файлах. Но прежде надо разобраться, что такое табличное пространство, сегмент, экстент и блок. Все это — единицы выделения пространства под объекты в базе данных Oracle.

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

Сегменты, в свою очередь, состоят из одного или нескольких экстентов. Экстент — это непрерывный фрагмент пространства в файле. Каждый сегмент первоначально состоит хотя бы из одного экстента, причем для некоторых объектов требуется минимум два экстента (в качестве примера можно назвать сегменты отката). Чтобы объект мог вырасти за пределы исходного экстента, ему необходимо выделить следующий экстент. Этот экстент не обязательно должен выделяться рядом с первым; он может находиться достаточно далеко от первого, но в пределах экстента в файле пространство всегда непрерывно. Размер экстента варьируется от одного блока до 2 Гбайт.

Экстенты состоят из блоков. Блок — наименьшая единица выделения пространства в Oracle. В блоках и хранятся строки данных, индексов или промежуточные результаты сортировок. Именно блоками сервер Oracle обычно выполняет чтение и запись на диск. Блоки в Oracle бывают размером 2 Кбайта, 4 Кбайта или 8 Кбайт (хотя допустимы также блоки размером 16 Кбайт и 32 Кбайта).


Сегмент состоит из одного или более экстентов, а экстент — это группа следующих подряд блоков.

Размер блока в базе данных с момента ее создания — величина постоянная, поэтому все блоки в базе данных одного размера. Формат блока представлен ниже.

+---------------+ | | <---- заголовок +---------------+ | | <---- каталог таблиц +---------------+ |\\\\\\\\\\\\\\\| <---- каталог строк +---------------+ | | | | <---- свободное пространство | ... | +---------------+ |010101010101010| |010101010101010| |010101010101010| <---- данные |010101010101010| |010101010101010| +---------------+

Заголовок блока содержит информацию о типе блока (блок таблицы, блок индекса и т.д.), информацию о текущих и прежних транзакциях, затронувших блок, а также адрес (местонахождение) блока на диске. Каталог таблиц содержит информацию о таблицах, строки которых хранятся в этом блоке (в блоке могут храниться данные нескольких таблиц). Каталог строк содержит описание хранящихся в блоке строк. Это массив указателей на строки, хранящиеся в области данных блока. Вместе эти три части блока называются служебным пространством блока. Это пространство недоступно для данных и используется сервером Oracle для управления блоком. Остальные две части блока вполне понятны: в блоке имеется занятое пространство, в котором хранятся данные, и может быть свободное пространство.

Теперь, получив общее представление о сегментах, состоящих из экстентов, которые, в свою очередь, состоят из блоков, можно переходить к понятию "табличное пространство" и разбираться, где же в этой структуре место для файлов. Табличное пространство — это контейнер с сегментами. Каждый сегмент принадлежит к одному табличному пространству. В табличном пространстве может быть много сегментов. Все экстенты сегмента находятся в табличном пространстве, где создан сегмент. Сегменты никогда не переходят границ табличного пространства. С табличным пространством, в свою очередь, связан один или несколько файлов данных. Экстент любого сегмента табличного пространства целиком помещается в одном файле данных. Однако экстенты сегмента могут находиться в нескольких различных файлах данных. Графически это можно представить следующим образом:

...



Итак, здесь представлено табличное пространство USER_DATA. Оно состоит из двух файлов данных — user_data01 и user_data02. В нем выделено три сегмента: T1, T2 и I1 (вероятно, две таблицы и индекс). В табличном пространстве выделены четыре экстента, причем каждый показан как непрерывный набор блоков базы данных. Сегмент T1 состоит из двух экстентов (по одному экстенту в каждом файле). Сегменты T2 и I1 состоят из одного экстента. Если для табличного пространства понадобится больше места, можно либо увеличить размер файлов данных, уже выделенных ему, либо добавить третий файл данных.

Табличные пространства в Oracle — это логические структуры хранения данных. Разработчики создают сегменты в табличных пространствах. Они никогда не переходят на уровень файлов — нельзя указать, что экстенты должны выделяться из определенного файла. Объекты создаются в табличных пространствах, а об остальном заботится сервер Oracle. Если в дальнейшем администратор базы данных решит перенести файлы данных на другой диск для более равномерного распределения операций ввода-вывода по дискам, никаких проблем для приложения это не создаст. На работе приложения это никак не отразится.

Итак, иерархия объектов, обеспечивающих хранение данных в Oracle, выглядит так.

  • База данных, состоящая из одного или нескольких табличных пространств.


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


  • Сегмент (TABLE, INDEX и т.д.), состоящий из одного и более экстентов. Сегмент привязан к табличному пространству, но его данные могут находиться в разных файлах данных, образующих это табличное пространство.


  • Экстент — набор расположенных рядом на диске блоков. Экстент целиком находится в одном табличном пространстве и, более того, в одном файле данных этого табличного пространства.


  • Блок — наименьшая единица управления пространством в базе данных. Блок — наименьшая единица ввода-вывода, используемая сервером.


  • Прежде чем завершить описание файлов данных, давайте разберемся, как происходит управление экстентами в табличном пространстве. До версии 8.1.5 в Oracle был только один метод управления выделением экстентов в табличном пространстве. Этот метод называется управление табличным пространством по словарю. Т.е. место в табличном пространстве отслеживается в таблицах словаря данных (аналогично тому, как отслеживаются движения средств на банковских счетах с помощью пары таблиц DEBIT и CREDIT). В качестве дебета можно рассматривать выделенные объектам экстенты, в качестве кредита — свободные для использования экстенты. Когда для объекта необходим очередной экстент, он запрашивается у системы. При получении такого запроса сервер Oracle обращается к соответствующим таблицам словаря данных, выполняет ряд запросов, находит (или не находит) свободное место нужного размера, а затем изменяет строку в одной таблице (или удаляет ее) и вставляет строку в другую. При этом сервер Oracle управляет пространством примерно так же, как работают обычные приложения: он изменяет данные в таблицах.



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

    В прежних версиях Oracle этот метод управления пространством (и связанные с ним дополнительные расходы ресурсов на выполнение рекурсивных SQL-операторов) приводил к проблемам при работе с временными табличными пространствами (до появления "настоящих" временных табличных пространств). Речь идет о табличных пространствах, в которых необходимо часто выделять место (при этом надо удалить строку из одной таблицы словаря данных и вставить в другую) и освобождать его (помещая только что перенесенные строки туда, где они ранее были). Эти операции выполняются последовательно, что существенно снижает возможности одновременной работы и увеличивает время ожидания. В версии 7.3 СУБД Oracle для решения этой проблемы добавили временные пространства. Во временном табличном пространстве пользователь не мог создавать постоянные объекты. Это было единственным новшеством: управление пространством все равно выполнялось с помощью таблиц словаря данных. Однако после выделения экстента во временном табличном пространстве система его уже не освобождала. При следующем запросе экстента из временного табличного пространства сервер Oracle искал уже выделенный экстент в соответствующей структуре данных в памяти и, найдя, использовал повторно. В противном случае экстент выделялся как обычно. При этом после запуска и работы СУБД в течение некоторого времени соответствующий временный сегмент выглядел как заполненный, но фактически был просто "выделен". Свободными экстентами в нем управляли по-другому. При запросе сеансом временного пространства сервер Oracle искал его в структурах данных в памяти, а не выполнял дорогостоящие рекурсивные SQL-операторы.



    В версиях Oracle, начиная с 8.1.5, был сделан следующий шаг по сокращению расхода ресурсов на управление пространством. Кроме табличных пространств, управляемых по словарю данных, появились локально управляемые табличные пространства. Для всех табличных пространств стало можно делать то, что в Oracle 7.3 делалось для временных, т.е. не использовать словарь данных для управления свободным местом в табличном пространстве. В локально управляемом табличном пространстве для отслеживания экстентов используется битовая карта, хранящаяся в каждом файле данных. Теперь для получения экстента достаточно установить значение 1 для соответствующего бита в битовой карте. Для освобождения экстента — сбросить бит обратно в 0. По сравнению с обращениями к словарю данных, это выполняется молниеносно. Больше не требуется ждать завершения длительно выполняемой операции, на уровне базы данных последовательно выделяющей место во всех табличных пространствах. Очередность на уровне табличного пространства остается только для очень быстро выполняемой операции. Локально управляемые табличные пространства имеют и другие положительные качества, например устанавливают одинаковый размер всех экстентов, но это имеет значение только для администраторов баз данных.


    Содержание раздела