четверг, 29 апреля 2010 г.

Хранение данных в блоке

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

Первое что я сделал, это создал таблицу  t1 и вставил в неё одну строку:
Подключение к:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options
 
SQL> CREATE TABLE zh.t1 (c1 NUMBER PRIMARY KEY, c2 VARCHAR2(50));
 
Таблица создана
SQL> INSERT INTO zh.t1 (c1, c2) VALUES(1, 'row1');
 
Вставлено: 1 строка

SQL> COMMIT;
 
Commit complete

Посмотрел номер файла и блока  для таблицы  t1:
SQL> SELECT header_file, header_block, blocks FROM dba_segments WHERE owner = 'ZH' AND segment_name = 'T1';
 
HEADER_FILE HEADER_BLOCK BLOCKS
----------- ------------ ------
4           563          8     
 
Выбрано: 1 строка

Сделал дамп этого блока данных:
SQL> ALTER SYSTEM DUMP DATAFILE 4 BLOCK MIN 563 BLOCK MAX 570;
 
Система изменена

И вот она строка из файла дампа:
col  0: [ 2]  c1 02
col  1: [ 4]  72 6f 77 31

Далее, очищаю таблицу с помощью TRUNCATE.
SQL> TRUNCATE TABLE zh.t1;
 
Таблица очищена

Повторяю дамп этого блока.  Строка присутствует:
col  0: [ 2]  c1 02
col  1: [ 4]  72 6f 77 31

Пробую схлопнуть таблицу:
SQL> ALTER TABLE zh.t1 ENABLE ROW MOVEMENT;
 
Таблица изменена

SQL> ALTER TABLE zh.t1 SHRINK SPACE;
 
Таблица изменена

Результата нет.  Тогда решаю  удалить таблицу:
SQL> DROP TABLE zh.t1;
 
Таблица удалена

Делаю дамп блока. Строка присутствует. Удаляю таблицу из корзины:
SQL> PURGE TABLE zh.t1;
 
Выполнено

Всё! Таблицы нет.  Блок тоже не занят никаким объектом:
SQL> SELECT COUNT(*) FROM dba_objects WHERE owner = 'ZH' AND object_name = 'T1'
 
COUNT(*)
--------
0       
 
Выбрано: 1 строка

SQL> SELECT COUNT(*) FROM dba_segments WHERE header_file = 4 AND header_block = 563
 
COUNT(*)
--------
0       
 
Выбрано: 1 строка

Делаю дамп блока. Строка присутствует:
col  0: [ 2]  c1 02
col  1: [ 4]  72 6f 77 31

Перезагружаю экземпляр:
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup;
ORACLE instance started.

Database mounted.
Database opened.

Делаю дамп блока. Строка всё равно есть. Пробую схлопнуть табличное пространство. Знаю, что не поможет, но всё-таки:
SQL> ALTER TABLESPACE users COALESCE;
 
Табличное пространство изменено

Результата нет. Создаю снова таблицу и смотрю, какие блоки она займёт:
SQL> CREATE TABLE zh.t1 (c1 NUMBER PRIMARY KEY, c2 VARCHAR2(50));
 
Таблица создана

SQL> SELECT header_file, header_block, blocks FROM dba_segments WHERE owner = 'ZH' AND segment_name = 'T1';
 
HEADER_FILE HEADER_BLOCK BLOCKS
----------- ------------ ------
4           563          8     
 
Выбрано: 1 строка

Таблица заняла те же блоки. Ну, теперь уж надеюсь, строки в блоке нет:
col  0: [ 2]  c1 02
col  1: [ 4]  72 6f 77 31

Не тут- то было. Наконец- то решаю вставить в таблицу строку:
SQL> INSERT INTO zh.t1 (c1, c2) VALUES(2, 'row2');
 
Вставлено: 1 строка
Затрачено времени: 0.31 секунд(ы)
 
SQL> COMMIT;
 
Commit complete

В дампе строка с новым значением:
col  0: [ 2]  c1 03
col  1: [ 4]  72 6f 77 32

Выводы:
Данные в блоке таблицы остаются до тех пор, пока они не будут перезаписаны новой порцией информации.

Комментариев нет: