注册
误删表数据
专栏/技术分享/ 文章详情 /

误删表数据

打工人小赵 2025/09/12 142 1 0
摘要

误删表

运维人员误删数据库对象,可以通过备份集和归档在其他机器上进行恢复还原,恢复后再将表重新导入原库。本方案需要进行异机还原、目标表导出和导入等步骤,需要消耗一定的恢复操作时间(实际耗时需要结合数据量、磁盘IO、网络速度等综合评估)。

1.1 创建测试表

create table t1 (id int,name varchar2(100));
insert into t1 values(1,'aa');
insert into t1 values(2,'bb');
commit;
insert into t1 values(3,'cc');
commit;
SELECT sysdate;
行号     SYSDATE            
---------- -------------------
1         2025-08-02 23:30:42

1.2 删除测试表

drop table t1;
SELECT sysdate;
行号     SYSDATE           
 ---------- -------------------
1          2025-08-02 23:30:52

删除时间:2025-08-02 23:30:52

判断还原点

表被删除后,首先需要确定误操作发生的时间点,需要精确的定位到操作时间才能够保证还原数据的完整性,以下通过两种方式判断误操作的发生时间。
1.归档日志挖掘
使用日志挖掘,数据库必须开了逻辑附加日志(RLOG_APPEND_LOGIC 不等于0 ),否无法挖掘到内容。

SQL>  SP_CREATE_SYSTEM_PACKAGES (1,'DBMS_LOGMNR');
SQL>  DBMS_LOGMNR.ADD_LOGFILE('/dm8/data/DM01/arch/ARCHIVE_LOCAL1_0x77F2DAFD_EP0_2025-08-02_11-03-32.log');
DMSQL 过程已成功完成
已用时间: 0.503(毫秒). 执行号:734.
SQL>  DBMS_LOGMNR.START_LOGMNR(OPTIONS=>2048);
DMSQL 过程已成功完成
已用时间: 24.503(毫秒). 执行号:735.
SQL> SELECT SCN,START_SCN,COMMIT_SCN,TIMESTAMP,START_TIMESTAMP,COMMIT_TIMESTAMP,SQL_REDO FROM V$LOGMNR_CONTENTS   where sql_redo like 'drop%';

行号     SCN                       TIMESTAMP               SQL_REDO
---------- --------------------   --------------------      --------------------                 
1          1000053            2025-08-02 23:30:52.045000      drop table  t1;

2.sql日志分析
如果没有开启逻辑附加日志,也可以通过sql执行日志进行定位误操作发生时间

[dmdba@localhost log]$ cat dmsql_DMSVR02_20221229_120139.log |grep drop
2025-08-02 23:30:52.037 (EP[0] sess:0x7fbe44016050 thrd:2552 user:SYSDBA trxid:2133553 stmt:0x7fbe4403a048 appname:disql ip:::1) [ORA]: drop table t1;
2025-08-02 23:30:52.037 (EP[0] sess:0x7fbe44016050 thrd:2552 user:SYSDBA trxid:2133553 stmt:0x7fbe4403a048 appname:disql ip:::1) [DDL] drop table t1;
2025-08-02 23:30:52.052 (EP[0] sess:0x7fbe44016050 thrd:2552 user:SYSDBA trxid:0 stmt:0x7fbe4403a048 appname:disql ip:::1) [DDL] drop table t1; EXECTIME: 9(ms).
[dmdba@localhost log]$

通过以上两种方式,我们就可以定位到误操作发生时间为:2025-08-02 23:30:52.037,对应的LSN号为:1000053

1.3 异机通过备份恢复

1.3.1 拷贝备份及归档日志

scp /dbbak/dmbak/BACKUP_FILE/* dmdba@192.168.182.132:/dbbak/dmbak/scp /dbarch/dmarch/* dmdba@192.168.182.132:/dbarch/dmtest/

1.3.2 异库还原数据

还原到删除时间点之前(2025-08-02 23:30:50)

## 恢复数据库文件
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="RESTORE DATABASE '/dbdata/dmdata/DMTEST/dm.ini' FROM BACKUPSET '/dbbak/dmbak/BACKUP_FILE'"
## 介质恢复,使其达到一致状态。
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="RECOVER DATABASE '/dbdata/dmdata/DMTEST/dm.ini' WITH ARCHIVEDIR '/dbarch/dmarch/' UNTIL TIME '2025-08-02 23:30:50'"
## 恢复后更新 DB_MAGIC
/home/dmdba/dmdbms/bin/dmrman CTLSTMT="RECOVER DATABASE '/dbdata/dmdata/DMTEST/dm.ini' UPDATE DB_MAGIC"

1.3.3 启动服务查询验证测试表

select * from t1;

1.3.4 导出导入测试表

创建目录
SQL> CREATE OR REPLACE DIRECTORY DM_BACKUP AS '/dbbak/dm_backup'; 
SQL> GRANT READ, WRITE ON DIRECTORY DM_BACKUP TO PUBLIC;
导出
dexpdp userid=sysdba/SYSDBA:5236 file=t2.dmp log=t2.log tables=t2 DIRECTORY=DM_BACKUP
检查日志未有报错

1.3.6 拷贝导出文件至原库,导入表对象

scp /dbbak/dm_backup/t2.dmp dmdba@192.168.182.133:/dbbak/dm_backupd
impdp sysdba/SYSDBA:5237 directory=DM_BACKUP file=t2.dmp log=imp_t2.log

1.3.7 原库查询测试表
数据无误,恢复完成。

误删表数据

数据闪回

闪回技术主要是通过回滚段存储的 UNDO 记录来完成历史记录的还原。开启闪回功能后, DM 会在内存中记录下每个事务的起始时间和提交时间。通过用户指定的时刻,查询到该时刻的事务号,结合当前记录和回滚段中的 UNDO 记录,就可以还原出特定事务号的记录。即指定时刻的记录状态,从而完成闪回查询。闪回查询功能完全依赖于回滚段管理。
注:对于DROP表的恢复,由于达梦数据库不存在回收站机制,所以对于DROP表操作无法flashback。DMDSC架构对于闪回查询功能不支持。

1.1 闪回设置

SP_SET_PARA_VALUE(1,'ENABLE_FLASHBACK',1);
sp_set_para_double_value(1,'UNDO_RETENTION',900);--单位秒
select * from v$dm_ini where para_name in ('ENABLE_FLASHBACK','UNDO_RETENTION');

1.2 创建测试表,插入数据

create table t1 (id int,name varchar2(100));insert into t1 values(1,'aa');
insert into t1 values(2,'bb');
commit;
insert into t1 values(3,'cc');
commit;
SQL> select count(*) from t1;
行号     COUNT(*)            
---------- --------------------
1          3

##1.3 删除数据

Delete from t1 where id=2;Commit;
SQL> select count(*) from t1;
行号     COUNT(*)           
 ---------- --------------------
1          2

1.4 闪回查询

删除时间2025-08-03 00:27:00

SQL> select * from t1 when timestamp '2025-08-03 00:26:00';
行号     ID          NAME
---------- ----------- ----
1          1           aa
2          2           bb
3          3           cc

1.5 创建还原表

通过闪回查询到的结果,创建名为t1_bak的表。

Create table t1_bak as select * from t1 when timestamp '2025-08-03 00:26:00';

1.6 将缺失记录写回原表

insert into t1 select * from t1_bak b where not exists (select 1 from t1 t where b.id=t.id);

1.7 查询还原表

select * from t1
还原表数据完毕

2 备份恢复

可参考误删表对象的恢复方法,将全表导入覆盖,或重新插入相关数据。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服