Essa é uma pergunta interessante: quando o Oracle realmente exclui dados fisicamente?
A unidade de dados no Oracle é um bloco. Vamos ver o que acontece quando excluímos uma linha.
Aqui está um exemplo com uma tabela simples em 11gR2 (consulte " Como despejar o Oracle Data Block? "):
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;
Você deve obter algo assim no final do arquivo criado em seu user_dump_dest
diretório:
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
Se eu excluir a segunda linha, confirmar e despejar o mesmo bloco, obterá algo como isto:
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
O registro ainda está lá (com um D
sinalizador definido). Se observarmos os dados binários reais (imediatamente antes da block header dump
seção, veremos que os dados ainda não foram substituídos:
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]
Uma maneira de forçar a substituição dos dados seria atualizá-los para um valor sem sentido antes de excluir a linha. Isso não funcionaria com índices, pois as atualizações são traduzidas para excluir + inserir no índice ab * tree.