在数据库日常运维过程中,数据文件可能因误操作等原因被删除,导致对应表空间无法访问,甚至影响数据库正常启动。针对数据文件误删,需要根据数据库运行状态以及备份、归档情况选择合适的恢复方式。
本文通过实验介绍 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
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
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;
可以看到查询表空间状态,STATUS已经从1变成0。查询实验表也发生了报错。
4、执行表空间恢复准备
CALL SP_TABLESPACE_PREPARE_RECOVER('TS_RECOVER');
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
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;
至此,通过文件句柄方式恢复误删的数据文件已经完成。
1、开启归档,并进行一次全量备份,此时t_recover表中的10000条数据则备份到全量备份中。
进行一次全备,并校验备份。
BACKUP DATABASE FULL BACKUPSET '/dm/backup/DATAFILE_FULL';
SELECT SF_BAKSET_CHECK(
'DISK',
'/dm/backup/DATAFILE_FULL'
);
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
4、停止数据库,释放文件句柄
./DmServiceEXAMDB stop ls -l /proc/$(pgrep -x dmserver)/fd | grep ts_recover01
5、尝试启动数据库
./DmServiceEXAMDB start
启动成功,但是登录可以发现数据库状态为mount,不能正常进行查询。
查看数据库日志,是由于表空间文件找不到,导致强制设置为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
内容为空,代表通过文件句柄方式找回不可行。
6、关闭数据库,通过dmrman进行恢复。
./DmServiceEXAMDB stop ./dmrman
进入dmrman使用全备进行restore
RESTORE DATABASE '/dm/data/EXAMDB/dm.ini' FROM BACKUPSET '/dm/backup/DATAFILE_FULL';
此步骤执行完,其实已经可以看到ts_recover01.dbf文件出现
继续使用归档进行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;
可以看到数据库成功启动,并且是open状态,查询t_recover表也是正常最新的20000条数据。
本文针对 DM8 表空间数据文件误删场景,分别验证了两种恢复方式:数据库进程未退出时,可利用 Linux 文件句柄找回被删除的数据文件;数据库重启导致文件句柄释放后,则可利用备份结合归档日志完成数据库恢复。此类数据文件丢失问题通常会在数据库重启时被发现,因此生产环境中应做好日常备份和归档管理,确保发生故障后具备可靠的数据恢复条件。
文章
阅读量
获赞
