судебное удаление / обновление данных

15

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

Есть ли какие-либо методы, обеспечивающие удаление данных из файла данных?

Мэтью Уотсон
источник

Ответы:

15

Это интересный вопрос: когда Oracle действительно удаляет данные физически?

Блок данных в Oracle - это блок. Посмотрим, что произойдет, когда мы удалим строку.

Вот пример с простой таблицей на 11gR2 (см. « Как выгрузить блок данных Oracle? »):

CREATE TABLE test_delete_data(id NUMBER,data VARCHAR2(100));
INSERT INTO test_delete_data VALUES (1, rpad('1', 100, '1'));
INSERT INTO test_delete_data VALUES (2, rpad('2', 100, '2'));
INSERT INTO test_delete_data VALUES (3, rpad('3', 100, '3'));
COMMIT;

SELECT dbms_rowid.rowid_to_absolute_fno(rowid, user, 'TEST_DELETE_DATA') fileno,
       dbms_rowid.rowid_block_number(rowid) blockno
  FROM test_delete_data;

-- replace with values from query
alter system dump datafile 4 block 16573;

Вы должны получить что-то вроде этого в конце файла, созданного в вашем user_dump_destкаталоге:

data_block_dump,data header at 0x8b02264
===============
[...]
block_row_dump:
tab 0, row 0, @0x1f2d
tl: 107 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 02
col  1: [100]
 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31
 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31
 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31
 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31
tab 0, row 1, @0x1ec2
tl: 107 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 03
col  1: [100]
 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32
 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32
 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32
 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32 32
tab 0, row 2, @0x1e57
tl: 107 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 2]  c1 04
col  1: [100]
 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
end_of_block_dump

Если я удалю вторую строку, зафиксирую и дам дамп того же блока, я получу что-то вроде этого:

block_row_dump:
tab 0, row 0, @0x1f2d
tl: 107 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 2]  c1 02
col  1: [100]
 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31
 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31
 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31
 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31
tab 0, row 1, @0x1ec2
tl: 2 fb: --HDFL-- lb: 0x2 
tab 0, row 2, @0x1e57
tl: 107 fb: --H-FL-- lb: 0x0  cc: 2
col  0: [ 2]  c1 04
col  1: [100]
 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
end_of_block_dump

Запись все еще там (с установленным Dфлагом). Если мы посмотрим на реальные двоичные данные (непосредственно перед block header dumpразделом, мы увидим, что данные еще не были перезаписаны:

8B040C0 33336404 33333333 33333333 33333333  [.d33333333333333]
8B040D0 33333333 33333333 33333333 33333333  [3333333333333333]
        Repeat 4 times
8B04120 33333333 023C3333 03C10202 32323264  [333333<.....d222]
8B04130 32323232 32323232 32323232 32323232  [2222222222222222]
        Repeat 5 times
8B04190 02002C32 6402C102 31313131 31313131  [2,.....d11111111]
8B041A0 31313131 31313131 31313131 31313131  [1111111111111111]
        Repeat 4 times
8B041F0 31313131 31313131 31313131 30A30602  [111111111111...0]

Один из способов принудительно перезаписать данные - это обновить их до бессмысленного значения перед удалением строки. Это не будет работать с индексами, так как обновления переводятся для удаления + вставки в индекс дерева ab *.

Винсент Малграт
источник
+1 «Один из способов принудительно перезаписать данные - это обновить их до бессмысленного значения перед удалением строки».
Отличный ответ! Я хотел бы добавить, что вы можете реализовать «обновление перед удалением» вместо триггера .
ora-600
Если вы хотите убедиться, что данные индекса также перезаписаны, вы можете уменьшить таблицу, перестроить все индексы (этой таблицы), создать новую таблицу с PCT_FREE = 99, которую вы расширяете до тех пор, пока она не займет все свободное пространство, а затем заполните эту таблицу фиктивные ряды. Наконец вы можете бросить стол, чтобы освободить место. Это определенно не та задача, которую вы должны выполнять автоматически после каждого удаления. Также имейте в виду отключение автоматического расширения перед выполнением этой операции.
ora-600
0

Я не думаю, что данные сохраняются после удаления, но вы правы, что пространство будет использоваться этой таблицей, пока она не будет заполнена. Максимальное использование пространства в таблице известно как отметка максимальной воды. У Тома Кайта есть действительно хороший (неудивительно) пост об этом.

Вы уменьшаете верхнюю отметку, восстанавливая таблицу:

alter table my_table_name move

или усекать его; хотя в активной таблице это явно не вариант.

Бен
источник
ISTBC, но я ожидаю, что данные еще будут существовать (в «сыром» виде) после удаления. Это будет там, просто строка была «не связана» со столом, а пространство помечено как свободное. Том Кайт говорит: «Итак, когда вы удаляете информацию, блок по-прежнему является« блоком », это просто блок, в котором когда-то были активные строки, но больше нет». Хотя я не уверен на 100% в этом, так что никакого отрицательного голоса. :)
@cagcowboy, он также говорит: «У нас может быть много блоков, которые больше не содержат данных ». Я всегда считал, что это место оставлено для будущего использования, но данные исчезли. Я готов быть доказан неверным, хотя :-).
Бен
3
Я понимаю вашу точку зрения. Однако я бы предположил, что он мог написать «у нас может быть много блоков, которые больше не содержат активных данных». По сути, я бы не ожидал, что Oracle перезапишет удаленные данные - я думаю, что это просто отсылает их.