Oracle恢复DELETE数据的PACKAGE(介绍篇)(仅做研究使用)

恢复DELETE数据的PACKAGE(介绍篇)

目的

在"不小心"对表执行了delete操作,并"不小心"提交之后,如果没有闪回、备份等常规恢复手段,那就傻眼了。

我在学习bbed的时候,有学到通过修改行标记来恢复delete的数据的手段,但这种方法存在风险,且较为复杂,于是思考是否有更简单更安全的方法。

至此,这个PACKAGE诞生了,虽然还很稚嫩。

目前该版本仅支持恢复NUMBER, VARCHAR2, CHAR, DATE, TIMESTAMP, RAW这六种数据类型。

其他数据类型将被恢复为null(如CLOB、BLOB、XMLTYPE、INTERVAL 等)。

需注意部分不支持的数据类型会导致数据读取错误(目前已知会导致错误的有LONG、LONG RAW)。

适用环境

  • 目前已知适用于Oracle11g和Oracle19c,期间版本和更高版理论是支持的,但未经过测试。

  • 仅支持恢复普通表,暂不支持如分区表、索引组织表等类型的表。

  • 支持CDB/PDB环境

  • 暂不支持RAC(不支持共享存储)

  • 前提条件:

    源表没有被drop

    数据块未被重用或覆盖

原理简介

Oracle的数据存储于数据文件当中,而delete一个表后,被delete的数据不会立刻消失,在被复用之前仍会存储在数据文件上。

此时只需要找到目标表数据存储的位置,并将底层数据读取出来并进行对应转换,就能得到真实的数据,再将这些数据插入到一张结构一致的新表上,数据就成功恢复了。

使用演示

创建PACKAGE
sql 复制代码
SQL> alter session set container=pdb1;

Session altered.

SQL> @del_recover_basic.sql
Installing DEL_RECOVER_BASIC package...

Package created.


Package body created.

Package DEL_RECOVER_BASIC installed end.
To display usage, execute: EXEC DEL_RECOVER_BASIC.usage
Disconnected from Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.28.0.0.0
准备测试表
sql 复制代码
DROP TABLE test.basic_types_test PURGE;
CREATE TABLE test.basic_types_test (
    id            NUMBER(10) PRIMARY KEY,
    num_col       NUMBER(12,2),
    vc_col        VARCHAR2(200),
    char_col      CHAR(10),
    date_col      DATE,
    ts_col        TIMESTAMP(6),
    raw_col       RAW(200)
);

INSERT INTO test.basic_types_test VALUES (
    1,
    12345.67,
    'Hello, World!',
    'FIXED',
    TO_DATE('2024-01-15 10:30:00', 'YYYY-MM-DD HH24:MI:SS'),
    TIMESTAMP '2024-01-15 10:30:00.123456',
    HEXTORAW('1A2B3C4D')
);

INSERT INTO test.basic_types_test VALUES (
    2,
    -9876.54,
    RPAD('Long string test ', 190, 'X'),
    'ABC       ',  
    TO_DATE('1999-12-31 23:59:59', 'YYYY-MM-DD HH24:MI:SS'),
    TIMESTAMP '1999-12-31 23:59:59.999999',
    HEXTORAW('FFEEDDCCBBAA')
);

INSERT INTO test.basic_types_test VALUES (
    3,
    0,
    '',      
    '',          
    NULL,
    NULL,
    NULL
);

INSERT INTO test.basic_types_test VALUES (
    4,
    NULL,
    NULL,
    NULL,
    SYSDATE,
    SYSTIMESTAMP,
    HEXTORAW(RPAD('FF', 200, 'FF')) 
);

INSERT INTO test.basic_types_test VALUES (
    5,
    0.01,
    'A',
    '1234567890',  
    TO_DATE('2020-02-29 12:00:00', 'YYYY-MM-DD HH24:MI:SS'),
    TIMESTAMP '2020-02-29 12:00:00.000001',
    HEXTORAW('01')
);

COMMIT;

set linesize 999
set pagesize 999
COLUMN vc_col FORMAT a30
COLUMN char_col FORMAT a10
COLUMN date_col FORMAT a19
COLUMN ts_col FORMAT a19
COLUMN raw_hex FORMAT a30

SQL> SELECT id,
       num_col,
       vc_col,
       char_col,
       TO_CHAR(date_col, 'YYYY-MM-DD HH24:MI:SS') AS date_col,
       TO_CHAR(ts_col, 'YYYY-MM-DD HH24:MI:SS') AS ts_col,
       RAWTOHEX(raw_col) AS raw_hex
  FROM test.basic_types_test
 ORDER BY id;

    ID	 NUM_COL VC_COL 			CHAR_COL   DATE_STR	       TS_STR			  RAW_HEX
------ --------- ------------------------------ ---------- ------------------- -------------------------- ------------------------------
     1	12345.67 Hello, World!			FIXED	   2024-01-15 10:30:00 2024-01-15 10:30:00.123456 1A2B3C4D
     2	-9876.54 Long string test XXXXXXXXXXXXX ABC	   1999-12-31 23:59:59 1999-12-31 23:59:59.999999 FFEEDDCCBBAA
		 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		 XXXXXXXXXX

     3	     .00
     4							   2026-06-03 17:44:06 2026-06-03 17:44:06.359346 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													  FFFFFFFFFFFFFFFFFFFF

     5	     .01 A				1234567890 2020-02-29 12:00:00 2020-02-29 12:00:00.000001 01
模拟误删除
sql 复制代码
SQL> delete from test.basic_types_test;

5 rows deleted.

SQL> commit;

Commit complete.

SQL> alter system checkpoint;

System altered.

SQL> select * from test.basic_types_test;

no rows selected
执行恢复

在执行package之前,需要有一个指向"要恢复的表所在的数据文件所在的路径"的目录,如没有,执行时会报错并提供推荐的创建语句,创建后重新执行即可。

更多详细的用法,请见下一文章操作手册篇。

sql 复制代码
SQL> SET SERVEROUTPUT ON
SQL> EXEC DEL_RECOVER_BASIC.recover_deleted_table('TEST', 'BASIC_TYPES_TEST', 'TEST');
17:57:06: Source table: TEST.BASIC_TYPES_TEST, DATA_OBJ#=75104, TS=TESTDATAFILE
17:57:06: Creating recovery table: TEST.R_BASIC_TYPES_TEST
17:57:06: Recovery table created successfully: TEST.R_BASIC_TYPES_TEST
17:57:06: Processing datafile:
/u01/app/oracle/oradata/ORCL/4A74127AED179CCAE0632400A8C0B3DF/datafile/o1_mf_tes
tdata_nvhbjhnd_.dbf using directory BBED_DATA_DIR
17:57:06: Recovery completed. Total rows recovered: 5
17:57:06: Data stored in table: TEST.R_BASIC_TYPES_TEST

PL/SQL procedure successfully completed.
验证恢复结果
sql 复制代码
SQL> SELECT id,
       num_col,
       vc_col,
       char_col,
       TO_CHAR(date_col, 'YYYY-MM-DD HH24:MI:SS') AS date_col,
       TO_CHAR(ts_col, 'YYYY-MM-DD HH24:MI:SS') AS ts_col,
       RAWTOHEX(raw_col) AS raw_hex
  FROM test.r_basic_types_test
 ORDER BY id;
	ID    NUM_COL VC_COL			     CHAR_COL	DATE_COL	    TS_COL		RAW_HEX
---------- ---------- ------------------------------ ---------- ------------------- ------------------- ------------------------------
	 1   12345.67 Hello, World!		     FIXED	2024-01-15 10:30:00 2024-01-15 10:30:00 1A2B3C4D
	 2   -9876.54 Long string test XXXXXXXXXXXXX ABC	1999-12-31 23:59:59 1999-12-31 23:59:59 FFEEDDCCBBAA
		      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
		      XXXXXXXXXX

	 3	    0
	 4							2026-06-03 17:44:06 2026-06-03 17:44:06 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
													FFFFFFFFFFFFFFFFFFFF

	 5	  .01 A 			     1234567890 2020-02-29 12:00:00 2020-02-29 12:00:00 01

package下载链接

https://download.csdn.net/download/sp60cn/92942843

相关推荐
l1t1 小时前
DeepSeek总结的从 DeepSeek 到 Quack:分布式 DuckDB 的梦想何时开始变得真实
数据库·分布式
小猿姐1 小时前
MongoDB Kubernetes Operator 实测对比:Community、Percona 与 KubeBlocks,谁更适合团队落地?
数据库·mongodb·kubernetes
zyl837211 小时前
Matplotlib/Seaborn:数据可视化
数据库·oracle
赵渝强老师1 小时前
【赵渝强老师】MongoDB的视图
数据库·mongodb
这个DBA有点耶2 小时前
死锁排查进阶:从日志到根因的完整分析链
java·开发语言·数据库·sql·运维开发·学习方法·dba
A-刘晨阳2 小时前
数据库挂了服务就瘫?我用PostgreSQL主从流复制搭了高可用架构,cpolar打通远程访问
数据库·postgresql·架构
一个儒雅随和的男子2 小时前
Modbus通信协议原理
数据库
码农阿豪2 小时前
Node.js 连接金仓数据库踩坑记(上篇):环境搭建与基础操作
数据库·node.js