exclusão / atualização forense de dados

15

Eu tenho uma necessidade forense de remover dados do oracle. Se eu apenas excluí-lo, entendo que os dados ainda estarão no arquivo de dados até que esse espaço seja reutilizado. Não estou preocupado com o espaço de refazer / arquivar / desfazer, eles envelhecerão razoavelmente rapidamente.

Existe algum método para garantir que os dados sejam realmente removidos de um arquivo de dados?

Matthew Watson
fonte

Respostas:

15

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_destdiretó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 Dsinalizador definido). Se observarmos os dados binários reais (imediatamente antes da block header dumpseçã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.

Vincent Malgrat
fonte
+1 "Uma maneira de forçar a substituição dos dados seria atualizá-los para um valor sem sentido antes de excluir a linha".
Ótima resposta! Gostaria de acrescentar que você pode implementar a "atualização antes de excluir" com um gatilho em vez de gatilho .
precisa
Se você deseja garantir que os dados do índice também sejam substituídos, você pode reduzir a tabela, reconstruir todos os índices (dessa tabela), criar uma nova tabela com PCT_FREE = 99, que você estende até consumir todo o espaço livre e preencher essa tabela com linhas fictícias. Finalmente, você pode soltar a tabela para liberar espaço. Definitivamente, essa não é uma tarefa que você deve executar automaticamente após cada exclusão. Lembre-se também de desativar a extensão automática antes de executar esta operação.
Ora-600
0

Eu não acho que os dados persistem após uma exclusão, mas você está certo de que o espaço será mantido em uso por essa tabela até que seja recarregado. O uso do espaço superior em uma tabela é conhecido como a marca d'água alta. Tom Kyte tem um post realmente bom (sem surpresa) sobre isso.

Você reduz a marca d'água alta reconstruindo a tabela:

alter table my_table_name move

ou truncando-o; embora em uma tabela ativa isso obviamente não seja uma opção.

Ben
fonte
ISTBC, mas eu esperaria que os dados ainda existissem (no formato "bruto") após uma exclusão. Ela estará lá, apenas que a linha foi "desvinculada" da tabela e o espaço foi marcado como livre. Tom Kyte diz isso "Então, quando você exclui as informações, o bloco ainda é" um bloco ", é apenas um bloco que já teve linhas ativas - mas não possui mais". Eu não tenho 100% de certeza disso, então não há voto negativo. :)
@cagcowboy, ele também diz "podemos ter muitos blocos que não contêm mais dados ". Eu sempre entendi que isso significa que o espaço é mantido para uso futuro, mas os dados se foram. Estou disposto a provar que estou incorreto :-).
Ben
3
Eu entendo o seu ponto. No entanto, eu diria que ele poderia ter escrito "podemos ter muitos blocos que não contêm mais dados ativos ". Basicamente, eu não esperaria que a Oracle substituísse os dados excluídos - acho que isso não faz referência a eles.