Формат блока в ORACLE

dbstalker, 06 июня

Как на самом низком физическом уровне хранятся данные в СУРБД ORACLE? Какой размер блока? Какова структура и специфика информации содержащейся в блоке? Как распределяется пространство в блоке при создании таблицы? PCTFREE и PCTUSED - для чего это? Как оракл выделяет блоки для записи информации? Об этом данная статья

На самом низком уровне данные ORACLE хранит в блоках данных (логические блоки, блоки ORACLE, страницы). Блок данных содержит фиксированное число байт физического пространства на диске. Размер блока данных устанавливается для каждой базы данных ORACLE при ее создании. Этот размер кратен размеру блока операционной системы. И что особенно важно, база данных распределяет свободное пространство блоками данных ORACLE, в отличие от операционной системы, где распределение пространства проводится в байтах. То есть ORACLE управляет пространством в файлах данных наименьшей единицей ввода-вывода - блоком данных.

Очень красиво и доступно на эту тему материал изложен у Тома Кайта. Поэтому я имею наглость привести выдержку из его книги:

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

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

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

Для работы с данными очень важно знать, что такое PCTFREE и PCTUSED и как с ними бороться. Эти параметры указываются при создании и изменении таблиц (команды alter и create) и позволяют управлять свободным пространством блока данных. PCTFREE можно также указывать при создании или изменении индексов.

Параметр PCTFREE устанавливает процент памяти блока, оставляемой свободной для будущих обновлений строк, которые уже находятся в блоке.

Например, если в команде CREATE TABLE указан PCTFREE 10, то это значит, что 10% пространства в каждом блоке данных будет оставаться свободным и предназначаться для обновлений тех строк, которые есть в блоке.

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

Например, если в команде CREATE TABLE указано PCTUSED 40, то после заполнения блока данных до PCTFREE, он не будет использоваться для вставки новых записей, пока процент занятой памяти в блоке не упадет до 39% или ниже.

Таким образом, мы имеет следующую картину:

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

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

Когда необходимо выполнить INSERT, ORACLE ищет в свободном списке первый доступный блок и использует его. Если свободного пространства в этом блоке становится мало, чтобы сделать INSERT, то этот блок удаляется из списка.

Когда выполняются DELETE и UPDATE, ORACLE проверяет, если используемое место становится меньше чем PCTUSED, то блок передвигается в начало списков свободных блоков.

Память, которая освобождается после delete или update (если значение изменяется на меньшее), доступна для INSERT в текущей или зафиксированной транзакции.

Освобождаемое пространство не всегда граничит с областью свободного пространства в блоке. Сжатие свободного пространства происходит только тогда,когда UPDATE или INSERT использует блок, содержащий достаточно свободного места, для размещения новых данных, но нет непрерывного участка блока. Так реализовано для того, чтобы не снижать производительность системы от ненужных сжатий.

Есть еще такое понятие как цепочки строк между блоками данных: строка не умещается в один блок данных (имеющие, например, столбцы с большими типами объектов). В таких случаях цепочки избежать невозможно.

Если строка обновляется так, что не помещается в блоке и свободное пространство в блоке заполнено, то строка переносится в новый блок данных (мигрирующая строка). А на прежнем месте записывается указатель на новый блок. ROWID строки при этом не меняется.

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

21 комментарий

Прокоментировать

VladimirVll
5 мая 2008 г. в 10:19

Интересный блог.
Первый вопрос. Цитата: "списки свободных для вставки блоков, т.е. таких блоков, у которых процент свободной памяти больше, чем PCTFREE", но ранее: "данные вставляться не будут в этот блок до тех пор, пока процент используемого пространства не станет меньше, чем указано в параметре PCTUSED". Все ли здесь верно?
Второй вопрос-предложение. Нельзя ли поподробнее про "Сжатие свободного пространства"?
И третий вопрос. "чтение цепочек блоков и мигрирующих строк снижает производительность ввода-вывода, так как в этих случаях приходиться читать больше одного блока для выборки строки. С этим нужно по возможности бороться". А как? Есть конкретные предложения от самого Оракла?

dbstalker
5 мая 2008 г. в 14:33

Ответ на первый Ваш вопрос:
PCTFREE - процент пространства блока для выполнения команд update для данных, которые уже находятся в этом блоке. Если блок находится в списке свободных блоков, то в блок вставляются строки (insert новых данных) до тех пор, пока в блоке данные не будет занимать место в процентном отношении равное 100%- PCTFREE (если пренебречь служебным пространством). Например, если PCTFREE=10%, пренебрегаем служебным пространством, то вставлять данные в блок будем до тех пор, пока они не займут 90% блока. После того как данные будут занимать все 90%, блок будет выкинут из списка свободных блоков, т.е. новые данные вставляться в него не будут. Но если будет необходимость обновить данные, которые уже есть в этом блоке, то оставшиеся 10% могут быть использованы для этого (размер данных после обновления может быть больше, чем до него)

PCTUSED - минимальный процент пространства блока, не менее которого мы хотим, чтобы был занят каждый блок. Если блок в свое время был выкинут из списка свободных блоков (занятое пространство – 90%), а затем из него удалили данные, и процент занятого пространства стал ниже заданного pctused (по умолчанию 40%) , то блок снова вносится в список свободных блоков. Таким образом, в него снова можно вставлять новые данные.

Проще говоря:
Если занятого пространства так много, что оно составляет 90% - вставлять новые данные нельзя.
Если занятого простанства стало так мало, что меньше 40% - в него снова можно вставлять данные.
Таким образом, противоречия я не вижу.

Anonymous
5 мая 2008 г. в 15:07

Понял. Большое спасибо!
А что насчет остальных вопросов? Может быть, оформите в виде отдельных статей? И еще. У меня есть практические вопросы (в смысле - возникающие из практики работы с Ораклом). Могу я с ними поделиться здесь? Возможно, кому-либо пригодится обсуждение или готовый опыт.

dbstalker
5 мая 2008 г. в 16:08

Ответы на остальные два вопроса сейчас маленькими постами оформляю. Вопросы задавайте любые - буду стараться отвечать. А если хотите поделиться своим опытом, то пока на it-blogs.com.ua нет возможности каждому заводить блоги. Но я с радостью размещу ваши материалы с указанием вашего авторства.

Anonymous
5 мая 2008 г. в 17:38

Вот задачка, с которой я столкнулся.
Есть промежуточная табличка (назовем ее для краткости "буфером", так как кол-во строк мал'о), из которой записи при клиентском обращении перемещаются в другую таблицу (назовем ее для краткости "логом"). Буфер не должен пустовать, а потому в него нужно закидывать записи из третьей таблицы (назовем ее для краткости "источником"). Можно "повесить" подброс записей из источника в буфер на джоб, но частота клиентских обращений может быть неравномерной, поэтому есть вероятность буферу остаться пустым. Поэтому остановились на методе вызова отдельной процедуры. Правда, есть одно "но", ведь работа этой процедуры будет задерживать клиентский процесс ее вызвавший. Тут и встает вопрос: как можно выделить подброс данных (в случае необходимости, по некоему сигналу, например) из источника в буфер в отдельный процесс? Кроме как немедленного выполнения джоба мне придумать ничего не удается..

dbstalker
6 мая 2008 г. в 16:07

Первое, что пришло в голову: повесить на "буфер" триггер на событие "delete" (т.е. когда записи переносятся в "лог"), который будет добавлять записи из "источника". Может быть, на время вставки нужно будет заблокировать "буфер". Вот такое предложение, если условия задачи мною поняты правильно.

Anonymous
6 мая 2008 г. в 16:37

По правде говоря, вопрос больше заключался в том, не знаете ли Вы способов, когда в текущей сессии можно выделить в отдельный процесс (отдельную "ответвленную" транзакцию, либо еще каким-то способом) некоторую последовательность действий (например, выполнения операторов DML)? Автономные транзакции не подходят, так как включены (состоят) в текущую(-ей), и, следовательно их продолжительность включена в продолжительность текущей транзакции, как и
любой триггер - продолжение текущей транзакции. Поэтому в качестве примера решения я привел немедленный запуск джоба. Но может, есть решение красивее?

dbstalker
7 мая 2008 г. в 11:01

Первое,если у Вас вопросы не по теме поста, то будет лучше, если Вы будете писать мне на E-mail. Второе, по-прежнему видно не понимаю сути проблемы. Поэтому совет чисто интуитивный: ройте в сторону пакетов dbms_alert и dbms_pipe.

dbstalker
8 мая 2008 г. в 10:09

Это ответ на третий Ваш вопрос о мигрирующих строках: http://my-oracle.it-blogs.com.ua/post-237.aspx

microbash
9 февраля 2009 г. в 15:32

возьмем
PCTFREE=10%
PCTUSED=40%

пусть блок заполнен на 50%. можно ли в него вставлять данные?
А по вашим ответам получаестя вот что:
1) "Если блок находится в списке свободных блоков, то в блок вставляются строки (insert новых данных) до тех пор, пока в блоке данные не будет занимать место в процентном отношении равное 100%- PCTFREE (если пренебречь служебным пространством). Например, если PCTFREE=10%, пренебрегаем служебным пространством, то вставлять данные в блок будем до тех пор, пока они не займут 90% блока."
ТУТ получается, чтоб блок доступен на ИНСЕРТ
2) "Проще говоря: Если занятого пространства так много, что оно составляет 90% - вставлять новые данные нельзя. Если занятого простанства стало так мало, что меньше 40% - в него снова можно вставлять данные. Таким образом, противоречия я не вижу."
ТУТ получается, что блок не досутпен на ИНСЕРТ

dbstalker
9 февраля 2009 г. в 16:45

в ответе на ваш вопрос ключевым будет "список свободных блоков". Упрощенно:совершенно пустой блок попадает в этот список и заполняется до тех пор, пока не будет заполнен на 100%-PCTFREE, то есть на 90% в нашем случае. после чего он из списка удаляется. то есть новые записи в него не будут попадать до тех пор пока он снова не попадет в список свободных блоков. а попадет он в этот список только тогда, когда заполненого места в нем станет мало, меньше , чем PCTUSED. вывод: будут ли вставлятся записи в блок зависит от PCTFREE,PCTUSED, заполненности и нахождения в списке свободных блоков.

microbash
10 февраля 2009 г. в 07:05

хм :))) тыда еще раз...
возьмем PCTFREE=10% PCTUSED=40% пусть блок заполнен на 50%. можно ли в него вставлять данные (INSERT)?
Да или Нет ?

dbstalker
10 февраля 2009 г. в 09:08

Да - если он в списке свободных блоков. Нет - если он отсутствует в списке свободных блоков.

microbash
10 февраля 2009 г. в 09:50

ОК пасиб )
теперь картина действительно исчерпывающая

microbash
10 февраля 2009 г. в 09:55

получается интересная картина, что по заполнености данными блока нельзя сказатьс вободен он илил нет. нужно смотреть есть ли он в списке свободных блоков...а как это сделать?
как бы посомтреть (зная номер блока) в списке он или уже нет?

dbstalker
10 февраля 2009 г. в 10:17

Это тема для статейки. Ждите - напишу.

dbstalker
8 мая 2008 г. в 15:09

Полным ответом на Ваш второй вопрос может служить статья Скулкина Дмитрия "Управление пространством внутри блока данных". А так же мой очень-очень упрощенный пост "Очистка блоков данных" "Очистка блоков данных"

Vladimir
8 мая 2008 г. в 16:18

Большое спасибо за внимание к моим вопросам! Обязательно почитаю.

Николай
14 июля 2008 г. в 17:34

Ну наверное неплохо было бы рассказать про ASSM

dbstalker
14 июля 2008 г. в 17:40

Бесспорно! Напишите статью и пришлите нам - мы разместим её в разделе 'Посты наших читателей'

Ирина
21 сентября 2010 г. в 14:53

Спасибо за статью!!Наконец-таки разобралась с pctfree и pctused

 

Новый комментарий

Я не спамер: введите суму 1+2



 

От авторов блога

О Блоге - прочитай перед началом.

Задать вопрос и получить ответ - уже решено 94 вопросов

Глоссарий - список терминов и сокращений


 
 

Бизнес форум

Последние темы:

Нужен поставщик Дропшиппинг
10 декабря, 1 ответа
КИНО КАФЕ!!!!!!!!!!!!!!!!
10 декабря, 1 ответа