Pctfree oracle что это

Обновлено: 06.07.2024

Этот выпуск посвящен спискам свободных мест, которые используются для управления свободным пространством в таблицах СУБД Oracle. К этой классической теме (первоначальный ответ был дан еще в 2001) Том Кайт уже возвращался в 2003 году.

Что такое список свободных мест?

Что такое список свободных мест?
Что такое группа списков свободных мест?
В чем отличие между списком свободных мест транзакции (transaction freelist), списком свободных мест процесса (process freelist) и основным списком свободных мест (master freelist)?

Ответ Тома Кайта

Все это будет проще понять, если большинство алгоритмов проигнорировать.

В каждой таблице есть свободное пространство. Свободное пространство размещается либо ДО отметки максимального уровня (high water mark - HWM) (точки, в которой данные вставлялись в таблицу), либо ПОСЛЕ HWM. Блоки после отметки HWM "просто есть" - они не отслеживаются ни в каком списке свободных мест. Просто известно, что каждый блок в данном экстенте, начиная с блока N, находится выше отметки максимального уровня (и, следовательно, свободно может быть использован).

Свободное пространство ДО отметки HWM отслеживается в списках свободных мест. По умолчанию сегмент содержит один список свободных мест. Все блоки сегмента, имеющие достаточно свободного места, попадают в этот список свободных мест (когда блок попадает в список свободных мест и удаляется из него зависит от параметров pctfree и pctused ). При вставке новой строки с помощью оператора INSERT (или когда строка переносится вследствие изменения), сервер обращается к этому списку свободных мест для поиска блока, в который можно будет вставить эту строку. Если в результате вставки в блоке останется меньше свободного места, чем задано параметром pctfree , этот блок удаляется из списка свободных мест, иначе он там остается.

Теперь учтите, что удаление блоков из списка свободных мест - строго последовательный процесс. Чтобы несколько процессов могли одновременно обращаться к этому списку и изменять его, следует гарантировать, что в каждый момент времени его изменяет только один сеанс. Поэтому в системе с большим количеством операций вставки/изменения единственный список свободных мест может стать причиной конфликтов, поскольку одна стркутура данных используется для ВСЕХ вставляющих сеансов. Вот почему используют несколько списов свободных мест. Сервер Oracle берет список свободных мест и разбивает его на несколько. Сеансу определенным образом назначается списко свободных мест в сегменте, а другие сеансы будут использовать другие списки свободных мест в том же сегменте (примерно так же транзакции распределяются по сегментам отата). Теперь, вместо использования одной структуры данных для 5 одновременных вставок в таблицу, можно создать пять структур данных и избежать конфликтов вообще.

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

Итак, вот что происходит для одного экземпляра Oracle - мы берем один список свободных мест для сегмента и разбиваем его на несколько списков свободных мест в сегменте, увеличивая степень параллелизма. Теперь давайте рассмотрим конфигурацию Oracle Parallel Server, когда несколько экземпляров открывают и монтируют одну и ту же базу данных. Именно для этой конфигурации вступают в игру группы списков свободных мест .

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

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

Комментарий читателя от 7 февраля 2002 года

Спасибо за прекрасное разъяснение. Теперь я понимаю все намного лучше. Однако, есть вопрос. В среде хранилища данных (на сервере HP N-класса с ОС HP UX 11 и 64-битовой версией Oracle 8.1.7 с SGA размером 20 Гбайт) я наблюдаю очень медленную (сравнительно. ) загрузку данных. АБД говорит, что может увеличить значение FREELISTS , но мне хотелось бы знать максимальное значение этого параметра, после которого дальнейший рост производительности не наблюдается. Кажется, я где-то читал, что при интенсивных вставках его оптимальное значение - 20. Что ты думаешь по этому поводу и как вычислить необходимые значения параметров FREELIST (и, возможно, INITRANS )? Предполагается, что только 5 пользователей используют хранилище данных (размером порядка терабайта) и только один пользователь вставляет данные (500 миллионов записей) в НЕ ФРАГМЕНТИРОВАННУЮ таблицу.

Ответ Тома Кайта

Значение FREELIST должно быть равным количеству процессов, загружающих данные (так что совет установить его равным 20 ошибочен, ЕСЛИ ТОЛЬКО не используется именно столько процессов загрузки).

Загрузка данных в хранилище обычно выполняется в непосредственном режиме (direct path mode), так что списки свободных мест вообще не учитываются и не используются. Используйте непосредственную загрузку и забудьте о конфликтах при доступе к спискам свободных мест (и процесс загрузки пройдет быстрее).

Если один пользователь загружает 500 миллионов записей количество списков свободных мест НЕ ИМЕЕТ ЗНАЧЕНИЯ.

Комментарий читателя от 9 февраля 2002 года

  1. Хотелось бы знать название книги, упомянутой в ответе.
  2. Если свободное пространство распределяется поровну между списками свободных мест, что, если кому-то понадобиться больше пространства, чем есть в списке?
  3. Объясните, пожалуйста, подробнее следующее: "Если в результате вставки в блоке останется меньше свободного места, чем задано параметром pctfree , этот блок удаляется из списка свободных мест, иначе он там остается."

Ответ Тома Кайта

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

3) Ну, тут все просто. Если в блоке "свободным" для изменений должно оставаться 10% пространства и при вставке свободного пространства остается менее 10%, этот блок удаляется из списка свободных мест - он больше не подходит для последующих вставок и не рассматривается. После удаления или изменения данных (приводящего к уменьшению длины строки), блок снова может быть помещен в список свободных мест, если в нем свободно более pctused пространства.

Комментарий читателя от 23 октября 2002 года

Чтобы вставить как можно больше строк в таблицу фактов хранилища данных, в которой не будет дальнейших изменений и удалений, надо ли следить за тем, чтобЁ не перестараться, увеличивая значение параметра pctused ?

Пусть, например, при данном размере блока в табличном пространстве и данной длине строки блок таблицы не может быть заполнен болеее чем на 98.5%. Предполагается, что при установке параметру pctused значения 99, во многие блоки в списке свободных мест нельзя будет вставить ни одной строки, что потенциально может привести к снижению производительности при вставке (кроме выполняемой операторами INSERT /*+ APPEND */ , конечно). Надо ли проверять, что количество блоков в списке (списках) свободных мест таких таблиц не слишком велико?

Ответ Тома Кайта

Это не проблема, если только данные после вставки не изменяются. Блок один раз будет удален из списка и больше в него не попадет. Рассмотрим следующий простой пример:

Обратили внимание, что блоки после вставки в список свободных мест не попали, ПОКА не был выполнен оператор update ?

Комментарий читателя от 23 окрября 2002 года

Прекрасный пример. Я выполнил ваш сценарий и получил практически таой же результат, причем, при добавлении следующей сотни строк значение Free Blocks снова уменьшилось:

Вот как я это понимаю - возможно, вы подтвердите, правильно ли.

i) Если блок находится в списке свободных мест, но сервер Oracle определяет, что в нем нет места для добавления строки, такой блок удаляется из списка свободных мест.

ii) В ходе последующего изменения выявляется, что "фактическое" значение pctused меньше, чем заданное для таблицы pctused 99, и блоки, затронутые изменением, снова попадают в список свободных мест.

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

Ответ Тома Кайта

Да, а если использовать механизм ASSM (auto segment space mgmt - автоматическое управление пространством в сегменте) в версии 9i все проблемы вообще снимаются, поскольку используются абсолютно другие алгоритмы управления свободным пространством ;)

Комментарий читателя от 14 января 2003 года

Не могли бы вы подробнее объяснить следующее:

"Чтобы несколько процессов могли одновременно обращаться к этому списку и изменять его, следует гарантировать, что в каждый момент времени его изменяет только один сеанс. Поэтому в системе с большим количеством операций вставки/изменения единственный список свободных мест может стать причиной конфликтов, поскольку одна стркутура данных используется для ВСЕХ вставляющих сеансов."

1. Когда два или более сенаса конфликтуют, как долго продолжается этот конфликт? Я предполагаю, что сеанс оценивает, сколько блоков ему надо для вставки и ждет, пока другой сеанс не освободит список свободных мест для вставки? Надесь, он н ждет, пока первый сеанс полность закончит вставку.

2. Могут ли вызывать конфликты сеансы, удаляющие данные. Или такие сеансы не изменяют список свободных мест, поскольку освободившиеся блоки возвращаются в пул?

Ответ Тома Кайта

1) Конфликт продожается недолго. Не до конца транзакции - достаточно подождать, пока другой сеанс получит свободный блок, изменит его и позволит другим его использовать.

2) При вставке/изменении блоки выбираются из списка свободных мест. При удалении блоки просто помещаются в основной список свободных мест. Конфликты при удалении - да, бывают, но поскольку речь идет просто о помещении в список свободных, они очень непродолжительны.

Оригинал обсуждения этого вопроса можно найти здесь.

Copyright © 2003 Oracle Corporation

Табличные пространства для сегментов отката. Очередной перевод Тома Кайта. Следите за новостями на сайте проекта Open Oracle.

Итак, давайте попробуем разобраться, с самой фундаментальной частью БД Oracle, которая называется "блок БД". Блоки являются самой элементарной единицей выборки данных. И стоят на самом нижнем уровне организации собственно самой БД. Блоки хранят всю информацию, из которой собственно и состоит ваша БД. Сразу оговариваюсь, не путайте блоки БД с блоками файловой системы, какая бы она не была на вашем сервере, FAT, FAT32, NTFS и т.д. Блоки БД, естественно базируются на блоках файловой системы, но с последними ничего общего не имеют. :) Хотя блоки БД, должны быть, кратны блокам файловой системы. Например, для UNIX это 8192, 16384 и т.д. Выбирать, размер блока БД можно самостоятельно при создании экземпляра БД, либо система задает этот параметр сама. В том случае как мы с вами устанавливали БД, размер блока у вас, скорее всего будет 2048 байт. В этом легко убедиться, проверив значение параметра db_block_size, в уже известном вам файле init.ora. Естественно при чтении данных из БД, считывается столько байт, сколько входит в один блок или кратное этому числу, в зависимости от количества информации, например, в запросе. Так же запомните сразу, единожды установленный размер блока БД, в процессе уже не может быть изменен. Если вы, по какой либо причине захотите изменить, размер блока БД, то необходимо сохранить ваши данные, затем удалить ваш экземпляр БД, и создать его вновь с новым значением блока БД! Что же представляет из себя блок БД? На рисунке представлено схематичное изображение блока.

Цифрой "1" обозначен заголовок блока, в нем хранится информация о том, к какому сегменту БД, принадлежит блок, количество одновременных транзакций и т.д. Цифрой "2" обозначено пространство, зарезервированное параметром PCTFREE для дальнейших обновлений данных в блоке. Что это за параметр мы сейчас разберем. Цифра "3" и "4" это пространство готовое к использованию, а вот цифра "5" показывает границу параметра PCTUSED. Что, это за параметры? PCTFREE - указывает какое количество (в процентах) пространства будет зарезервировано для дальнейших обновлений данных в блоке, а PCTUSED задает часть объема блока, которое должно освободиться прежде чем БД включит его в список доступных для ввода новых строк. Давайте разберем это все, так чтобы стало понятно! Например, вы создали таблицу MYTABLE, в которую поместили скажем 100 записей, ваша таблица заняла, фигурально один блок. Теперь, при создании БД параметр PCTFREE, в нашем случае, имел значение 10%, а параметр PCTUSED имел значение 40%. Что, это значит? Теперь ваш блок, имеет 10% пространства для обновления находящейся в нем таблицы, а 90% пространства отводятся под саму таблицу. То есть, если ваша таблица заполнила 90% процентов блока, то он вычеркивается самой БД из списка доступных для ввода новых строк БД. Но, те 10% процентов так и остались в блоке, для обновления вашей MYTABLE. Теперь скажем, вы обновили данные в вашей MYTABLE таким образом, что она стала занимать не 90% процентов пространства блока, а скажем 49% блока. Итак, 90%-49% = 41%, а параметр PCTUSED = 40%, замечательно, блок снова включается в список для записи новых строк! Теперь сюда можно поместить, скажем, таблицу NEWTABLE! Вот таким образом эти два параметра работают и управляют блоками БД. При этом ни один из параметров никогда не должен иметь значение 100%! С помощью PCTFREE и PCTUSED можно регулировать производительность самой БД. Забегая немного вперед скажу, что экземпляры БД имеют два типа при построении. Так называемые OLTP и DSS системы, первая это БД рассчитанная на тысячи активных транзакций, а вторая это хранилище данных используемое в основном для чтения, так вот правильная настройка блоков и их размер обязательно необходимое условие для производительного функционирования обоих типов БД! Посмотреть ваши параметры настройки блоков, как я уже говорил, можно в файле init.ora в секции db_block_size, например:

А значение параметров PCTFREE и PCTUSED можно посмотреть, войдя пользователем SYS или SYSTEM в SQL*Plus и написав такой запрос:

Как видно, в нашем случае PCTFREE = 10% и PCTUSED = 40%, в чем мы с вами и убедились! В дальнейшем мы еще, вернемся к этой теме, так как она еще далеко не полностью раскрыта. Но пока на этом с системными объектами БД мы закончили. Советую, еще раз все осмыслить и хорошенечко и запомнить на будущее.

Начиная с Oracle 11 размер любой партиции, представленной на диске, по умолчанию равен 8МБ, даже если она не имеет в себе никаких данных (До 11 версии размер по умолчанию был 65КБ).
Отсюда важность указания STORAGE INITIAL при создании партиционированной таблицы.

Рассмотрим на примере. Таблица из 80 млн записей партиционирована RANGE-INTERVAL по месяцу и субпартиционирована LIST по региону. Месячные интервалы с 2013 года - это 6+12=18, и каждая партиция по 100 субпартиций регионов.

Отсюда не сложно высчитать минимальный размер такой таблицы 18*100*8МБ= 140ГБ.
Что явный перебор при исходном размере таблицы без секций = 2ГБ.

  • Сложность переноса бд (экспорта/импорта) - база будет весить терабайты.
  • Ограниченность tablespace по размеру: Таблиц много, в DWH такая таблица должна быть продублирована несколько раз (Таблица источник - зеркало, Преобразованная таблица, Итоговая фактическая таблица). Доступное пространство быстро закончится.
  • !Увеличение времени чтения партиции с диска при сканировании по партициям.

Размер партиции можно взять с небольшим запасом (1МБ):

Минимальный размер такой таблицы вырастет в сравнении с плоской незначительно на (1-0,68/1)*100% = 32%

Замечу один минус:
Совсем маленькой партиции тоже не стоит делать - это увеличить число физических обращений к диску. Т.к. для сканирования секции понадобится не одно обращение, а несколько.

2. Настройка параметров PCTFREE и PCTUSED для уменьшения размера таблицы
Размер таблицы можно значительно уменьшить, если задать эти параметры:
PCTFREE - % блока под резерв изменений. Если таблица редко обновляется (или только чистится и заполняется заново), то этот параметр можно ставить близким к 0.
PCTUSED - % блока под данные, если размер данных в блоке превышает этот %, то новые данные туда не будут вставляться. Если опять же данные редко обновляются, то для максимального уплотнения этот параметр можно ставить ближе к 100%.

+ Уменьшение размера таблицы сопоставимо изменению параметров PCTFREE/PCTUSED
- При update строки с увеличением его размера, в случае нехватки свободного места в блоке (PCTFREE) строка целиком будет перенесена из текущего блока в новый. В старом блоке будет проставлена ссылка на новое расположение. Т.е. при чтении данных из таблицы нужно будет выполнить дополнительное рекурсивное чтение, что значительно увеличит стоимость запроса.
- При большом числе параллельных сессии к одному блоку сильно разрастается информация о заинтересованных сессиях к строкам блока (ITL). Если место в блоке закончится, то невозможно будет расширить ITL, что приведет к ошибке обновления блока.


3. Быстрое обновление таблиц через PARTITION EXCANGE.

Частая задача в DWH - инкрементальное обновление данных. Допустим нужно залить новые данные за прошедший месяц.
Традиционный способ INSERT /*+ APPEND */ достаточно медленный.
Есть альтернативный, выполняющийся доли секунды.

Для этого нужна вспомогательная таблица, куда будет класться очередная порция для обновления.
У таблиц должна совпадать полностью структура, включая размерности и последовательность столбцов.
После этого можно перекинуть из этой таблицу в целевую партиционированную одной командой.

Пример перекидки из промежуточной таблицы в RANGE-INTERVAL партиционированную таблицу.

Этой командой произойдет обмен данными между таблицами: партиция заполнится данными таблицы T_TBL_PT, а таблица данными пустой партиции T_TBL.

Аналогично можно делать обмены с субпартициями


4. Узнать имя партиции по произвольному фильтру
Такое может понадобится, допустим, для сбора статистики только по нужной секции, т.к. в dbms_stat нужно указать физическое имя.
Если известно значение в колонке секций, то нужно воспользоваться конструкцией:
5. System партицирование
Нет указания колонки при создании, из-за этого нужно указывать конкретную партицию при вставке или выборке

7. Изменение параметров партиции на основании статистики использования
На основании статистики использования партиций (DBA_HEAT_MAP_SEG_HISTOGRAM) можно включить компрессию

tkyte@TKYTE816> create table t (x int, у char(1000) default x) pctfree 10 2 pctused 80;

tkyte@TKYTE816> exec measure usage;

первое же изменение вернуло блох в список свободных из-за намного большего значения pctused

Это демонстрирует последствия увеличения значения параметра PCTUSED. Первое же изменение вернуло блок в список FREELIST. Этот блок может использоваться для вставки новой строки намного быстрее.

Значит ли это, что необходимо увеличивать значение параметра PCTUSED? Нет, не обязательно. Это зависит от того, что впоследствии происходит с данными. Пусть приложение работает по следующему циклу:

1. Добавление данных (множество вставок).

2. Изменение данных, которое приводит к увеличению и уменьшению строк.

3. Снова добавление данных.

Тогда вообще не нужно, чтобы блоки возвращались в список свободных в результате изменения. Желательно установить параметру PCTUSED небольшое значение, чтобы блок попадал в список FREELIST только после удаления из него всех строк данных. В противном случае некоторые из блоков с временно уменьшенными строками при большом значении PCTUSED будут использованы для вставки новых строк. Затем, когда придется изменять старые и новые строки в этих блоках, для них не хватит места и придется часть строк переносить.

Итак, параметры PCTUSED и PCTFREE имеют ключевое значение. С одной стороны, их нужно задавать, чтобы избежать переноса слишком большого количества строк, а с другой, - чтобы избежать избыточных потерь пространства в блоках. Необходимо изучить объекты и их предполагаемое использование, а затем выработать обоснованный план установки значений этих параметров. Простые правила могут и не подойти; оптимальные значения действительно зависят от способов использования объектов. Имеет смысл рассмотреть следующие варианты (помните, большое и небольшое - понятия относительные).

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

Небольшое значение PCTFREE, большое значение PCTUSED. Если предполагается только вставка и удаление строк или если при изменении строки ее длина только уменьшается.

Параметры INITIAL, NEXT и PCTINCREASE

Эти параметры хранения определяют размер начального (INITIAL) и последующих экстентов, выделяемых таблице, а также процент увеличения для следующих экстентов. Например, если используется начальный экстент размером 1 Мбайт, следующий - размером 2 Мбайта, а параметр PCTINCREASE имеет значение 50, в таблице будут следующие экстенты:

3. 3 Мбайт (150 процентов от 2).

4. 4,5 Мбайт (150 процентов от 3).

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

Если локально управляемые табличные пространства не используются, я рекомендую всегда устанавливать INITIAL = NEXT и PCTINCREASE = 0. Это позволяет эмулировать процесс выделения пространства, происходящий в локально управляемых табличных пространствах. Для всех объектов в табличном пространстве должна использоваться одинаковая стратегия выделения экстентов во избежание фрагментации.

Параметры LOGGING и NOLOGGING

Обычно объекты создаются с журнализацией (LOGGING), тем самым все действия с объектом, которые могут генерировать информацию повторного выполнения, ее генерируют. Параметр NOLOGGING позволяет выполнять с объектом ряд действий, не генерируя данных повторного выполнения. Параметр NOLOGGING затрагивает лишь несколько специфических действий: первоначальное создание объекта, непосредственная загрузка данных с помощью утилиты SQLLDR или пересоздание (подробнее о том, какие из этих действий применимы к тому или иному объекту базы данных, см. в справочном руководстве по языку SQL - SQL Language Reference Manual ).

Параметры INITRANS and MAXTRANS

Каждый блок данных объекта включает заголовок. Часть этого заголовка - таблица транзакций. В таблицу транзакций вносятся записи о том, какие строки/элементы блока заблокированы какими транзакциями. Первоначальный размер таблицы транзакций определяется параметром INITRANS объекта. Для таблиц стандартное значение - 1 (для индексов - 2). При необходимости таблица транзакций может динамически расти вплоть до MAXTRANS записей (естественно, при наличии достаточного свободного пространства в блоке). Каждая запись транзакции занимает 23 байта в заголовке блока.

Таблицы, организованные в виде кучи

Таблицы, организованные в виде кучи, используются приложениями в 99 (если не более) процентах случаев, хотя со временем это может измениться за счет более интенсивного использования таблиц, организованных по индексу, - ведь по таким таблицам

Параметры MINEXTENTS и MAXEXTENTS

Эти параметры управляют количеством экстентов, которые могут быть выделены объекту. Значение MINEXTENTS указывает серверу Oracle, сколько экстентов выделять таблице первоначально. Например, в локально управляемом табличном пространстве с одинаковыми экстентами размером 1 Мбайт при установке параметру MINEXTENTS значения 10 таблице будет выделено 10 Мбайт дискового пространства.

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

Читайте также: