(1)模拟删除数据文件

/u01/app/oracle/oradata/racdb/system01.dbf
/u01/app/oracle/oradata/racdb/sysaux01.dbf

! rm -rf /u01/app/oracle/oradata/racdb/system01.dbf
! rm -rf /u01/app/oracle/oradata/racdb/sysaux01.dbf
! ls -l /u01/app/oracle/oradata/racdb/system01.dbf

(2)查看数据库基本信息

select status from v$instance;
select open_mode from v$database;
select count(*) from dba_objects;
create table aa as select * from dba_objects;

由于数据文件都被删除,其中包括 system01.dbf,是存放数据字典的容器,想要再访问数据字典中得视
图,当然是不可能的了,所以这里会报错,找不到文件,故障出现

(3)开始恢复

3.1 判断句柄位置

其实这个时候,所有 oracle 的进程都还在,都是以 ora_开头的都是 oracle 的后台进程:
SQL> ! ps -ef|grep ora_
--查看 lgwr 进程,判断需要恢复文件句柄所在目录
SQL> !ps -ef|grep ora_lgwr
oracle     2997      1  0 17:08 ?        00:00:00 ora_lgwr_racdb
oracle     3781   3747  0 17:54 pts/1    00:00:00 /bin/bash -c ps -ef|grep ora_lgwr
oracle     3783   3781  0 17:54 pts/1    00:00:00 grep ora_lgwr

3.2 恢复数据文件、控制文件、tmp 文件和 online log 文件

cd /proc/31863/fd
ll(后置标注为deleted就是刚刚被删除的文件)
[root@oracle fd]# ll
total 0
lr-x------ 1 oracle oinstall 64 Feb  3 17:56 0 -> /dev/null
l-wx------ 1 oracle oinstall 64 Feb  3 17:56 1 -> /dev/null
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 10 -> /u01/app/oracle/product/11.2.0.4/db_1/dbs/lkRACDB
lr-x------ 1 oracle oinstall 64 Feb  3 17:56 11 -> /u01/app/oracle/product/11.2.0.4/db_1/rdbms/mesg/oraus.msb
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 14 -> socket:[29608]
l-wx------ 1 oracle oinstall 64 Feb  3 17:56 2 -> /dev/null
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 256 -> /u01/app/oracle/oradata/racdb/control01.ctl
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 257 -> /u01/app/oracle/oradata/racdb/control02.ctl
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 258 -> /u01/app/oracle/oradata/racdb/control03.ctl
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 259 -> /u01/app/oracle/oradata/racdb/redo01_1.log
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 260 -> /u01/app/oracle/oradata/racdb/redo01_2.log
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 261 -> /u01/app/oracle/oradata/racdb/redo02_1.log
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 262 -> /u01/app/oracle/oradata/racdb/redo02_2.log
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 263 -> /u01/app/oracle/oradata/racdb/system01.dbf (deleted)
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 264 -> /u01/app/oracle/oradata/racdb/sysaux01.dbf (deleted)
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 265 -> /u01/app/oracle/oradata/racdb/undotbs1.dbf
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 266 -> /u01/app/oracle/oradata/racdb/users01.dbf
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 267 -> /u01/app/oracle/oradata/racdb/test01.dbf
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 268 -> /u01/app/oracle/oradata/racdb/eas_d_anjoy_standard01.dbf
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 269 -> /u01/app/oracle/oradata/racdb/temp01.dbf
lr-x------ 1 oracle oinstall 64 Feb  3 17:56 3 -> /dev/null
lr-x------ 1 oracle oinstall 64 Feb  3 17:56 4 -> /dev/null
lr-x------ 1 oracle oinstall 64 Feb  3 17:56 5 -> /dev/null
lr-x------ 1 oracle oinstall 64 Feb  3 17:56 6 -> /u01/app/oracle/product/11.2.0.4/db_1/rdbms/mesg/oraus.msb
lr-x------ 1 oracle oinstall 64 Feb  3 17:56 7 -> /proc/2997/fd
lr-x------ 1 oracle oinstall 64 Feb  3 17:56 8 -> /dev/zero
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 9 -> /u01/app/oracle/product/11.2.0.4/db_1/dbs/hc_racdb.dat

[root@orcltest fd]# ll | grep deleted
[root@oracle fd]# ll | grep deleted
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 263 -> /u01/app/oracle/oradata/racdb/system01.dbf (deleted)
lrwx------ 1 oracle oinstall 64 Feb  3 17:56 264 -> /u01/app/oracle/oradata/racdb/sysaux01.dbf (deleted)

分析:可以看句柄 256-266 的文件末尾被标记(deleted),这是由刚才的 rm -rf 操作所导致的,误删
除后只要 Oracle 数据库未重启,进程就不会停止,那么就可以通过/proc/#oracle DBWn 进程号/fd 目录
中的文件句柄号,来对这些被 delete 的文件进行恢复,方法就是 cp 文件句柄到原路径,注意一点这里如果
不是在 fd 目录,那就要用绝对路径来指定文件句柄,如果删除文件后就,又对数据库进行了关闭操作,那就
无解了,只能想想 rman 了如果采用 secureCRT 软件来作为终端查看的话,可以看到这几个 deleted 的文件是一直闪动的。

执行恢复,执行如下脚本:

cp 263 /u01/app/oracle/oradata/racdb/system01.dbf
cp 264 /u01/app/oracle/oradata/racdb/sysaux01.dbf

注意,这里一定要注意权限问题,要用 oracle 用户去 cp,如果用 root 去 cp 出来的文件,oracle 进
程是没有权限操作的,当然,你也可以在用 root 恢复完后,再 chown 一下:
chown -R oracle:oinstall /u01/app/oracle/oradata/racdb/system01.dbf
chown -R oracle:oinstall /u01/app/oracle/oradata/racdb/sysaux01.dbf

对文件进行恢复以后,直接查询 fd 目录下的文件状态,依然可以看到是(deleted)的,但是没关系,实际上文件已经恢复成功了

四、重启数据库,检验是否正常

startup force

五、总结

当我们进行 Linux 操作系统命令 rm 的时候,切忌不可随意加-rf 参数,就算一定要用,也要确定再三后
才能执行,否则对于数据库而言,可以说是灾难性的。这里只是测试了一下删除
/u01/app/oracle/oradata/下的全部文件,试想一下,如果你当初执行的是 rm -rf /u01 呢?可能情况
就要更加复杂一点了,恢复需要的步骤也就更多了。
由于是在数据库 open 状态下直接进行了破坏性操作,对于 redo buffer 还来不及写入 online redo
logfile 的那部分操作,肯定是会丢失的,因为我们通过文件句柄号恢复出来的日志文件中,并不一定包含数
据库的最新变更,即便如此,对于 rm -rf 误操作的恢复,还是有一定意义的,至少可以在你没有任何备份的
情况下,多提供了一根救命稻草来拯救你的数据库,再次强调一下,rm -rf 后,千万不要着急地关闭数据库

Related Posts