Мигрирующие и сцепленные строки

dbstalker, 08 мая

Миграция строк,Цепочки строк (фрагментация строк),Причина появления фрагментации строк,Влияние фрагментации строк на производительность,Мониторинг.Об этом далее.

Миграция строк

Миграция строк происходит, если при обновлении (UPDATE) строка не помещается в блоке. Та как Oracle не изменяет ROWID строки за все время ее существования в базе данных, то, если недостаточно места в блоке для обновленной строки, то строка вынуждена перемещаться в другой блок, где места достаточно. В старом блоке остается указатель, по которому можно найти мигрировавшую строку. Этот механизм придуман, чтобы не менялся rowid мигрировавшей строки. Таким образом, обращаться к такой строке придется в два этапа: сначала к первоначальному блоку, а затем к блоку, где реально находится запись. Указатель на мигрировавшую строку особо не сказывается на свободном пространстве блока, так как длина его составляет около 10 байтов.

Цепочки строк (фрагментация строк)

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

Причина появления фрагментации строк

  • Длина строки больше, чем размер блока
  • PCTFREE – слишком маленький (не хватает места для обновления)

  • Табличка имеет больше 255 полей

Влияние фрагментации строк на производительность

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

Мониторинг

Первоначальную информацию о наличии проблемы можно получить, выполняя следующий запрос:

select value from v$sysstat  where name = 'table fetch continued row';

Что это за статистика, посмотрите здесь.

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

select sum(value) from v$sysstat  where name in ('table scan rows gotten','table fetch by rowid');

Можно взять отношение :

select (select value from v$sysstat  where name = 'table fetch continued row')/
(select sum(value) from v$sysstat  where name in ('table scan rows gotten','table fetch by rowid')) from dual

И если получите небольшое число (насколько небольшое - судить Вам), то можно успокоиться. В противном случае идем дальше.

Если Вы регулярно собираете статистику ANALYZE TABLE ESTIMATE/COMPUTE STATISTICS, то можно почерпнуть интересную информацию из представления all_tables. Кстати, есть еще конструкция LIST CHAINED ROWS для команды analyze.

Выполним запрос:

select num_rows, chain_cnt from all_tables where owner='Ваша_схема' and table_name='название таблицы';

В поле CHAIN_CNT проставлено количество строк таблицы, состоящих из нескольких частей. Поле NUM_ROWS - общее количество строк в таблице. Если у таблицы CHAIN_CNT>0, и если длина строки не больше размера блока, то стоит подумать об увеличении параметра PCTFREE.

А так можно найти все подозрительные таблицы.

select owner,table_name,num_rows, chain_cnt from dba_tables where chain_cnt is not null and chain_cnt<>0

А так можно найти сессии, работающие с таблицами, провоцирующими рост статистики 'table fetch continued row':

select e.username, s.sid, s.value  from v$statname n, v$sesstat s, v$session e where s.statistic#=n.statistic# and s.sid=e.sid and
name='table fetch continued row' and s.value>0;

Еще раз обратимся к представлениям DBA_TABLES и DBA_TAB_PARTITIONS. Для таблиц, по которым была выполнена команда ANALYZE TABLE ESTIMATE/COMPUTE STATISTICS, проанализируем следующие столбцы:

NUM_ROWS – число записей

AVG_SPACE - среднее доступное свободное место в блоке

CHAIN_CNT – число сцепленных записей

AVG_ROW_LEN – средняя длина записи

AVG_SPACE_FREELIST_BLOCKS - среднее свободное пространство в блоках входящих в список свободных блоков,

  • Для оценки правильности установленных PCTUSED и PCTFREE, выполним сравнение: (100 - (PCTFREE + PCTUSED)) *blocksize > avg_row_len.
  • Значение chain_cnt/num_rows даст процент строк, которые перенесены. Если это число велико (больше, чем 5 %) и максимальная длина строки меньше размера блока, тогда PCTFREE должно быть определенно увеличено. Если процент сцепленных записей мал (менее 1 %) и максимальная длина строки меньше размера блока, то PCTFREE должно быть увеличено только в том случае, если максимальная длина строки не сильно отличается от avg_row_len, иначе место будет потрачено впустую.
  • Значение (Blocksize - avg_space) /blocksize дает использование пространства. Если строки не велики, то уменьшение PCTFREE и увеличение PCTUSED улучшит использование пространства. Будьте осторожны при увеличении PCTUSED и всегда лучше допустить ошибку в сторону более низкого PCTUSED, то есть используйте максимальный размер строки.
  • Если максимальная длина строки > blocksize, тогда повторно проверьте, что PCTUSED установлен в очень малое значение. Если avg_row_len намного меньше, чем размер блока, но максимум больший, то использование пространства может быть слабым, если строки удаляются беспорядочно. Этого нельзя избежать, но можно перестроить. Установка большого значения PCTUSED может немного помочь, но может и привести ухудшению использования пространства.
  • select sum( (num_rows*AVG_ROW_LEN)) must_be_used, sum((blocks*размер_блока - AVG_SPACE_FREELIST_BLOCKS)) used from all_tables;
    Общий смысл его таков - сравнивается место, которое должны были занимать данные и которое занимают:
    • Должны были занимать без учета накладных расходов на заголовки блоков - количество записей* среднюю длину
    • Занимают - количество блоков*размер блока – свободное место в блока списка свободных блоков.
    Разница этих величин - это место в блоках, которые не попали во freelist и накладные расходы. Если расхождение велико, то это говорит о неэффективном использовании места. Это может быть как неудачно выбранные методы хранения так и параметры pctfree, pctused

После того как определились с кругом проблем , нужно решить, что делать.Есть несколько направлений:

  • Увеличить PCTFREE, уменьшить PCTUSED
  • Для больших объектов можно осуществить перенос в табличное пространство с достаточным размером блока
  • Можно использовать метод CTAS (create table as select), alter table move
  • Можно «плохие» строки перенести в промежуточную таблицу, а затем вставить в прежнюю.
  • Экспорт, импорт – также чудный способ борьбы с цепочками и мигрирующими строками.

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

Успехов!

Собрать статистику можно еще и таким образом:

exec dbms_stats.GATHER_SCHEMA_STATS ('SMAP');
или 
begin
dbms_stats.gather_schema_stats (ownname =>'SCOTT', estimate_percent
=> 90, block_sample => TRUE, method_opt => 'for all indexed columns');
end;

Материалы почерпнуты:

http://masters.donntu.edu.ua/publ2002/foreign/ibrahim.pdf

http://www.oracle.com/global/ru/oramag/feb2007/dba_adm_frag.html

http://dsvolk.msk.ru/oracle/faq/dba.php?PHPSESSID=bc9d12150631cb0266ca8803589ada0d

 

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

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



 

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

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

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

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


 
 

Бизнес форум

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

Телепрограмма
23 июня, 1 ответа
Турция
23 июня, 4 ответа
Выбор люстры
22 июня, 1 ответа