回答:
これは興味深い質問です。Oracleが実際にデータを物理的に削除するのはいつですか?
Oracleのデータの単位はブロックです。行を削除するとどうなるか見てみましょう。
11gR2の単純な表の例を次に示します(「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;
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
2番目の行を削除し、同じブロックをコミットしてダンプすると、次のようになります。
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]
データを実際に上書きする1つの方法は、行を削除する前に無意味な値に更新することです。更新はab * treeインデックスのdelete + insertに変換されるため、これはインデックスでは機能しません。
削除後もデータが保持されるとは思わないが、スペースが補充されるまでそのテーブルが使用し続けることは正しい。表の最上部のスペース使用量は、最高水準点として知られています。Tom Kyteには、それについての非常に優れた(当然のことながら)投稿があります。
テーブルを再構築して、最高水準点を下げます。
alter table my_table_name move
またはそれを切り捨てることにより; ただし、アクティブなテーブルでは、これは明らかにオプションではありません。