注册
表空间文件误删的两种恢复方式
培训园地/ 文章详情 /

表空间文件误删的两种恢复方式

OK小魏 2026/08/21 191 0 0

背景介绍

在数据库日常运维过程中,数据文件可能因误操作等原因被删除,导致对应表空间无法访问,甚至影响数据库正常启动。针对数据文件误删,需要根据数据库运行状态以及备份、归档情况选择合适的恢复方式。

本文简介

本文通过实验介绍 DM8 表空间数据文件误删后的两种恢复方式:当数据库进程未退出、文件句柄尚未释放时,通过 Linux 文件句柄找回数据文件;当数据库已经重启、文件句柄释放后,则通过备份结合归档日志恢复数据库,并验证数据完整性。

文件句柄找回方式

1、创建实验用表空间,并确认表空间状态和物理文件

CREATE TABLESPACE TS_RECOVER DATAFILE '/dm/data/EXAMDB/ts_recover01.dbf' SIZE 128; SELECT GROUP_ID, PATH, STATUS$, RW_STATUS, LAST_CKPT_TIME, MODIFY_TIME FROM V$DATAFILE WHERE PATH LIKE '%ts_recover01.dbf%'; ls -lh /dm/data/EXAMDB/ts_recover01.dbf

image.png

2、创建测试表,插入1000条数据

CREATE TABLE T_RECOVER ( ID INT, NAME VARCHAR(50) ) STORAGE(ON TS_RECOVER); INSERT INTO T_RECOVER SELECT LEVEL, 'TEST' FROM DUAL CONNECT BY LEVEL <= 10000; commit; SELECT COUNT(*) FROM T_RECOVER;

3、删除实验表空间文件,并让数据库检测到异常,模拟真实查询报错情况。

rm /dm/data/EXAMDB/ts_recover01.dbf ls -lh /dm/data/EXAMDB/ts_recover01.dbf

image.png

SP_FILE_SYS_CHECK(); SELECT GROUP_ID, PATH, STATUS$, RW_STATUS, LAST_CKPT_TIME, MODIFY_TIME FROM V$DATAFILE WHERE PATH LIKE '%ts_recover01.dbf%'; SELECT COUNT(*) FROM T_RECOVER;

image.png
可以看到查询表空间状态,STATUS已经从1变成0。查询实验表也发生了报错。

4、执行表空间恢复准备

CALL SP_TABLESPACE_PREPARE_RECOVER('TS_RECOVER');

image.png
5、通过文件句柄恢复数据文件

确认 PID:

ps -ef|grep dmserver

然后找到deleted标记文件

ls -l /proc/<pid>/fd | grep deleted

通过cp方式将文件恢复

cp /proc/<PID>/fd/<FD> /dm/data/EXAMDB/ts_recover01.dbf

image.png

6、执行 DM 表空间恢复,并检查表空间状态

CALL SP_TABLESPACE_RECOVER('TS_RECOVER'); SELECT GROUP_ID, PATH, STATUS$, RW_STATUS, LAST_CKPT_TIME, MODIFY_TIME FROM V$DATAFILE WHERE PATH LIKE '%ts_recover01.dbf%'; SELECT COUNT(*) FROM T_RECOVER;

image.png

至此,通过文件句柄方式恢复误删的数据文件已经完成。

通过备份归档进行恢复

1、开启归档,并进行一次全量备份,此时t_recover表中的10000条数据则备份到全量备份中。

进行一次全备,并校验备份。

BACKUP DATABASE FULL BACKUPSET '/dm/backup/DATAFILE_FULL'; SELECT SF_BAKSET_CHECK( 'DISK', '/dm/backup/DATAFILE_FULL' );

image.png

2、再插入10000条数据,这部分数据没有在全量备份中,通过归档进行恢复。

INSERT INTO T_RECOVER SELECT LEVEL + 10000, 'AFTER_BACKUP' FROM DUAL CONNECT BY LEVEL <= 10000; COMMIT;

切换一次归档,让后插入的10000条数据落盘到归档文件。

ALTER SYSTEM ARCHIVE LOG CURRENT;

3、删除实验的表空间文件,此时数据库没有重启,则还能看到未释放的文件句柄

rm /dm/data/EXAMDB/ts_recover01.dbf ls -lh /dm/data/EXAMDB/ts_recover01.dbf ls -l /proc/$(pgrep -x dmserver)/fd | grep ts_recover01

image.png
4、停止数据库,释放文件句柄

./DmServiceEXAMDB stop ls -l /proc/$(pgrep -x dmserver)/fd | grep ts_recover01

image.png
5、尝试启动数据库

./DmServiceEXAMDB start

启动成功,但是登录可以发现数据库状态为mount,不能正常进行查询。
image.png
查看数据库日志,是由于表空间文件找不到,导致强制设置为mount状态。

/dm/data/EXAMDB/ts_recover01.dbf not exist,force ts[7, TS_RECOVER] to be off-line User data files missed, Force to startup MOUNT

查找数据库进程的deleted标记文件句柄

ls -l /proc/$(pgrep -x dmserver)/fd | grep ts_recover01

image.png
内容为空,代表通过文件句柄方式找回不可行。

6、关闭数据库,通过dmrman进行恢复。

./DmServiceEXAMDB stop ./dmrman

进入dmrman使用全备进行restore

RESTORE DATABASE '/dm/data/EXAMDB/dm.ini' FROM BACKUPSET '/dm/backup/DATAFILE_FULL';

此步骤执行完,其实已经可以看到ts_recover01.dbf文件出现
image.png
继续使用归档进行recovery,恢复数据库到最新的可用状态。

RECOVER DATABASE '/dm/data/EXAMDB/dm.ini' WITH ARCHIVEDIR '/dm/data/EXAMDB/arch'; RECOVER DATABASE '/dm/data/EXAMDB/dm.ini' UPDATE DB_MAGIC;

7、启动数据库,查看恢复情况

./DmServiceEXAMDB start select count(1) from t_recover;

image.png
可以看到数据库成功启动,并且是open状态,查询t_recover表也是正常最新的20000条数据。

总结

本文针对 DM8 表空间数据文件误删场景,分别验证了两种恢复方式:数据库进程未退出时,可利用 Linux 文件句柄找回被删除的数据文件;数据库重启导致文件句柄释放后,则可利用备份结合归档日志完成数据库恢复。此类数据文件丢失问题通常会在数据库重启时被发现,因此生产环境中应做好日常备份和归档管理,确保发生故障后具备可靠的数据恢复条件。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服