Управление пространством (доступным «местом») осуществляется на нескольких уровнях. Вначале место выделяется для табличного пространства (путём изменения размеров файлов данных). Затем пространство внутри табличного пространства выделяется для сегментов (путём выделения экстентов). И наконец пространство внутри сегментов выделяется для строк. Это происходит путём управления битовыми масками (bitmaps) которые отслеживают сколько свободного места в каждом блоке.
Управление экстентами
Метод управления экстентами устанавливается для табличного пространства и применяется для вссех сегментов этого табличного пространства. Существует два метода управления: управление с помощью словаря (dictionary management) или локальное управление (local management). Разница предельно проста: всегда надо использовать local management; dictionary management никогда не надо использовать. Dictionary management пока ещё поддерживается, и только. Это ограничение для поддержки предыдущих версий Oracle.
Dictionary management использует две таблицы в словаре данных. SYS.UET$ содержит строки описывающие использованные экстенты и SYS.FET$ хранит информацию о свободных экстентах. Каждый раз когда БД необходимо добавить экстент к таблице, необходимо прочитать FET$ таблицу чтобы найти свободный экстент и затем выполнить DML команды к таблицам FET$ и UET$ так как экстент становится не свободным. Этот механизм существенно снижает производительность, так как все операции по управлению пространством в БД (они могут инициироваться параллельно) должны выполняться согласно механизму управления транзакциями.
Локальный механизм был введён начиная с версии 8i и стал значением по умолчанию начиная с версии 9i. Он использует битовую маску которая хранится в каждом файле данных. Каждый бит управляет определённым набором блоков и когда место выделяется, значение соответсвующего бита устанавливается в единицу. Такой механизм гораздо более эффективен чем dictionary management. Время на выделение экстентов распределено между битовыми масками каждого файла, и битовые маски разных файлов могут обновляться параллельно, в отличие от использования двух общих таблиц. Битовая маска хранится в шапке файла данных (размер header по умолчанию = 64 Кб до 11g и 1 Мб после 11g. Надо добавлять размер шапки когда вы считаете размер файла).
Когда вы создаёте табличное пространство с механизмом локального управленяи, важным параметром является uniform size (равномерный размер). Если указывается эта опция, каждый экстент выделяемый в этом табличном пространтсве будет фиксированного размера.Это позволяет управлять пространством ещё более эффективно, так как количество блоков управляемых каждым битом в маске будет больше: один бит для экстента. Рассмотрим пример
create tablespace large_tabs datafile ‘large_tabs_01.dbf’ size 10g extent management local uniform size 160m;
Каждый экстент выделяемый в этом табличном пространстве будет размером 160 МБ, т.е. во всего будет около 64 экстентов. Битовой маске нужно всего 64 бита и 160 МБ можно выделить обновив всего один бит. Это может быть очень эффективно – если сегменты в этом табличном пространстве будут большими. Если будет создан сегмент которому надо место всего для нескольких строк – все равно будет выделен экстент в 160 МБ. Маленьким объектам лучше создавать отдельно таблично пространство
create tablespace small_tabs datafile ‘small_tabs_01.dbf’ size 1g extent management local uniform size 160k;
Альтернативой этой команде (и командой по умолчанию) будет команда
create tablespace any_tabs datafile ‘any_tabs_01.dbf’ size 10g extent management local autoallocate;
Когда сегмент будет создаваться в этом табличном пространстве, Oracle выделит экстент размером в 64Кб. Когда сегмент будет расти и требовать больше места, Oracle будет выделять экстенты по 64Кб до тех пор, пока их число не станет 16, а затем размер выделяемых экстентов будет постепенно увеличиваться.
Если база данных была обновлена, возможно что будут табличные пространства с dictionary-management управлением. Вы можете проверить это выполнив запрос
select tablespace_name, extent_management from dba_tablespaces
Любые dictionary-management табличные пространства могут быть сконвертированы в локально управляемые с помощью PL/SQL программы, которую можно вызвать
execute dbms_space_admin.tablespace_migrate_to_local(‘tablespacename’);
Управление пространством сегмента
Метод управления пространством для сегмента устанавливается для табличного пространства и применяется ко всем сегментам в таблично пространстве. Существует два метода: manual и automatic. Автоматическое управление надо всегда использовать, а ручное – всего лишь ограничение для поддержки старых версий.
Автоматический метод был введён в версии 9i и стал значением по умолчанию начиная с версии 11g. Каждый сегмент создаваемый в автоматически управляемом табличном пространстве имеет набор битовых масок описывающих насколько заполнены блоки в нём. Всего хранится 5 битовых масок для каждого сегмента, и каждый блок существует только в одной битовой маске. В битмапах хранится информация о использованном пространстве по группам: битмап для полностью заполненных блоков, блоков где заполнено от 75% до 100%, от 50 до 75%, от 25 до 50 и от 0 до 25%. Когда нужен блок для записи сроки, серверный процесс сессии смотрит на размер строки, чтобы определить в какой битовой маске искать блок. Например если размер блока 4КБ и строка для вставки 1500 байт, то соответствующий блок необходимо искать в группе блоков где заполнено от 25 до 50%. Каждый блок в этой группе гарантированно имеет 2КБ свободного места. Когда строки доабвляются, удаляются или изменяются – битовые маски тоже обновляются.
Старый ручной способ управления использовал обычный список, известный как free list, в котором хранился список блоков доступных для записи, но без какой-либо информации о том сколько места свободно. Такой метод не оптимален так как необходимо проверять каждый блок хватает ли места и место распределяется непропорционально (может появиться много неиспользованного места). Для проверки метода управления можно выполнить запрос
select tablespace_name,segment_space_management from dba_tablespaces;
Невозможно изменить метод для управления пространством сегментов, но можно создать новое таблично пространство с автоматическим методом, перенсти туда все сегменты и удалить старое табличное пространство.
Добавить комментарий