11 июля 2008 г.

Дамп структуры индекса

Иногда очень полезно посмотреть на внутреннюю структуру индекса. Для этого можно выгрузить индекс в дамп следующей командой:

alter session set events 'immediate trace name treedump level nnnn;

где nnnn равен object_id индекса, который можно посмотреть в dba_objects:

SQL> column object_name format A15
SQL> select object_id, object_name
from dba_objects a
where owner = 'SCHEMA' and
object_type = 'INDEX' and
object_name = 'CUSTOMERS_PK';

OBJECT_ID OBJECT_NAME
---------- ---------------
33243 CUSTOMERS_PK

SQL> alter session set events 'immediate trace name treedump level 33243';

Session altered.
Последняя команда выгрузит структуру указанного индекса в файл в папку user_dump_dest, который обычно указывает на $ORACLE_BASE/admin/SID/udump.
Содержимое файла выглядит приблизительно так (заголовок не включен):
----- begin tree dump
branch: 0x2402004 37756932 (0: nrow: 104, level: 1)
leaf: 0x2402005 37756933 (-1: nrow: 517 rrow: 517)
leaf: 0x2402006 37756934 (0: nrow: 514 rrow: 514)
leaf: 0x2402007 37756935 (1: nrow: 481 rrow: 481)
leaf: 0x2402008 37756936 (2: nrow: 481 rrow: 481)
leaf: 0x2403309 37761801 (3: nrow: 481 rrow: 481)
...
leaf: 0x240336d 37761901 (97: nrow: 481 rrow: 481)
leaf: 0x240336e 37761902 (98: nrow: 482 rrow: 482)
leaf: 0x240336f 37761903 (99: nrow: 481 rrow: 481)
leaf: 0x2403370 37761904 (100: nrow: 481 rrow: 481)
leaf: 0x2403372 37761906 (101: nrow: 481 rrow: 481)
leaf: 0x2403373 37761907 (102: nrow: 377 rrow: 377)
----- end tree dump
По дампу видно, что индекс состоит из одного корневого блока и 104 листовых блоков (с -1 до 102 включительно). Строки начинающиеся на branch - это либо корневой блок, либо блоки ветвления. Листовые блоки начинаются на leaf. Вторая цифра после него 37756932 - это адрес блока. Используя этот адрес блока, можно получить id файла и блока функциями пакета dbms_utility и выгрузить содержимое конкретных блоков индекса. Об этом чуть позже. Дальше, nrow - это суммарное количество ключей или строк включая строки, которые отмечены как удаленные, а rrow - количество ключей или строк.

В этом дампе мы увидели общую структуру индекса и сколько ключей хранятся в каждом узле индекса, но в ней нет самих значений ключей. Я пока не видела одношагового решения для выгрузки всех узлов вместе со значениями ключей, но можно выгрузить содержимое отдельного узла, то есть блока индекса следующим образом:
SQL> select dbms_utility.data_block_address_file(37756932) file_id,
dbms_utility.data_block_address_block(37756932) block_id
from dual;

FILE_ID BLOCK_ID
---------- ----------
9 8196

SQL> alter system dump datafile 9 block 8196;

System altered.