4、一次“成功”的实验
我们借助RMAN备份,恢复到实验前的状态。
[root@bspdev datafile]# ls
mvtbltest01.dbf o1_mf_temp_7xt46489_.tmp
o1_mf_example_7xt46m9x_.dbf o1_mf_undotbs1_7xt3yzl5_.dbf.bak
o1_mf_jpatest_87y6v8qc_.dbf o1_mf_undotbs1_92l5b0v4_.dbf
o1_mf_nbscommo_820frtg1_.dbf o1_mf_users_805nxydh_.dbf
o1_mf_nbscommo_820ft5y5_.dbf rmdtest01.dbf
o1_mf_sysaux_7xt3yzkb_.dbf tts_simple01.dbf
o1_mf_system_7xt3yzhj_.dbf
删除数据文件。
[root@bspdev datafile]# rm rmdtest01.dbf
rm: remove regular file `rmdtest01.dbf'? y
[root@bspdev datafile]# ls
mvtbltest01.dbf o1_mf_system_7xt3yzhj_.dbf
o1_mf_example_7xt46m9x_.dbf o1_mf_temp_7xt46489_.tmp
o1_mf_jpatest_87y6v8qc_.dbf o1_mf_undotbs1_7xt3yzl5_.dbf.bak
o1_mf_nbscommo_820frtg1_.dbf o1_mf_undotbs1_92l5b0v4_.dbf
o1_mf_nbscommo_820ft5y5_.dbf o1_mf_users_805nxydh_.dbf
o1_mf_sysaux_7xt3yzkb_.dbf tts_simple01.dbf
删除之后,借助文件描述符,我们还是可以查询的。
SQL> select count(*) from rmtest.rm_tab;
COUNT(*)
----------
145462
查找dbwr进程,确定进程编号。
[root@bspdev datafile]# ps -ef | grep dbw
Oracle 9405 1 0 02:45 ? 00:00:00 ora_dbw0_wilson
root 9716 4466 0 02:56 pts/0 00:00:00 grep dbw
使用lsof –p确定文件描述符信息。
[root@bspdev datafile]# lsof -p 9405
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
oracle 9405 oracle cwd DIR 253,0 4096 10574090 /u01/oracle/dbs
(篇幅原因,有省略……)
oracle 9405 oracle 29uW REG 253,0 209723392 525165 /u01/oradata/WILSON/datafile/o1_mf_nbscommo_820frtg1_.dbf
oracle 9405 oracle 30uW REG 253,0 104865792 525166 /u01/oradata/WILSON/datafile/o1_mf_nbscommo_820ft5y5_.dbf
oracle 9405 oracle 31uW REG 253,0 104865792 525484 /u01/oradata/WILSON/datafile/o1_mf_jpatest_87y6v8qc_.dbf
oracle 9405 oracle 32uW REG 253,0 10493952 525541 /u01/oradata/WILSON/datafile/tts_simple01.dbf
oracle 9405 oracle 33uW REG 253,0 10493952 2978999 /u01/oradata/WILSON/datafile/mvtbltest01.dbf
oracle 9405 oracle 34uW REG 253,0 30416896 524875 /u01/oradata/WILSON/datafile/o1_mf_temp_7xt46489_.tmp
oracle 9405 oracle 35r REG 253,0 1074176 10595009 /u01/oracle/rdbms/mesg/oraus.msb
oracle 9405 oracle 36uW REG 253,0 1048584192 2979001 /u01/oradata/WILSON/datafile/rmdtest01.dbf (deleted)
注意:lsof是描述文件描述符最好的工具,其中包括FD列。我们从dbwr的连接中,找到了rmdtest01.dbf的信息行。其中FD=36uw。这个36就表示了连接文件的名称。
联合dbwr的进程编号9405,我们在目录/proc/9405/fd中找到所有的文件符。
[root@bspdev datafile]# cd /proc/9405/fd
[root@bspdev fd]# ls
0 10 12 14 16 18 2 21 23 25 27 29 30 32 34 36 5 7 9
1 11 13 15 17 19 20 22 24 26 28 3 31 33 35 4 6 8
Ls命令也可以列出信息。
[root@bspdev fd]# ls -l
total 0
lr-x------ 1 oracle oinstall 64 Feb 2 02:56 0 -> /dev/null
l-wx------ 1 oracle oinstall 64 Feb 2 02:56 1 -> /dev/null
lrwx------ 1 oracle oinstall 64 Feb 2 02:56 10 -> /u01/oracle/dbs/lkinstwilson (deleted)
lrwx------ 1 oracle oinstall 64 Feb 2 02:56 34 -> /u01/oradata/WILSON/datafile/o1_mf_temp_7xt46489_.tmp
lr-x------ 1 oracle oinstall 64 Feb 2 02:56 35 -> /u01/oracle/rdbms/mesg/oraus.msb
lrwx------ 1 oracle oinstall 64 Feb 2 02:56 36 -> /u01/oradata/WILSON/datafile/rmdtest01.dbf (deleted)
l-wx------ 1 oracle oinstall 64 Feb 2 02:56 9 -> /home/oracle/oradiag_oracle/diag/clients/user_oracle/host_1437849207_76/trace/ora_9293_3085993664.trm
这个36对应的文件还存在,就是已经被删除的那个rmdtest01.dbf文件。进行拷贝出来。
[root@bspdev fd]# cp 36 /u01/oradata/WILSON/datafile/rmdtest01res.dbf
[root@bspdev fd]#
拷贝出来之后,最好进行一定转换。先将其offline,之后进行控制文件中的rename动作,最后recover和online操作。具体流程常见笔者专门的文章()。
SQL> alter database datafile 11 offline;
Database altered
Rename操作。
--报错
SQL> alter database rename file '/u01/oradata/WILSON/datafile/rmdtest01.dbf' to '/u01/oradata/WILSON/datafile/rmdtest01res.dbf';
alter database rename file '/u01/oradata/WILSON/datafile/rmdtest01.dbf' to '/u01/oradata/WILSON/datafile/rmdtest01res.dbf'
ORA-01511: 重命名日志/数据文件时出错
ORA-01141: 重命名数据文件 11 时出错 - 未找到新文件 '/u01/oradata/WILSON/datafile/rmdtest01res.dbf'
ORA-01110: 数据文件 11: '/u01/oradata/WILSON/datafile/rmdtest01.dbf'
ORA-27041: 无法打开文件
Linux Error: 13: Permission denied
Additional information: 9
究其原因,是拷贝权限为root,需要手工修改所有权信息。
[root@bspdev datafile]# ls -l | grep rmd
-rw-r----- 1 root root 1048584192 Feb 2 03:01 rmdtest01res.dbf
[root@bspdev datafile]# chown oracle:oinstall rmdtest01res.dbf
[root@bspdev datafile]# ls -l | grep rmd
-rw-r----- 1 oracle oinstall 1048584192 Feb 2 03:01 rmdtest01res.dbf
Rename文件。
SQL> alter database rename file '/u01/oradata/WILSON/datafile/rmdtest01.dbf' to '/u01/oradata/WILSON/datafile/rmdtest01res.dbf';
Database altered
SQL> recover datafile 11;
Media recovery complete.
SQL> alter database datafile 11 online;
Database altered.
使用rman中的recovery advisor工具,来判断错误是否存在。
[oracle@bspdev ~]$ rman nocatalog
Recovery Manager: Release 11.2.0.1.0 - Production on Sun Feb 2 03:06:43 2014
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
RMAN> connect target /
connected to target database: WILSON (DBID=3906514064)
using target database control file instead of recovery catalog
RMAN> list failure;
no failures found that match specification
恢复完成,实验成功。
5、结论
本篇文章的书写,有一半目的是揭示文件内部的运行机制,另一半是记录下Linux下使用文件描述符FD来恢复数据的方法。我们说,从运维角度看,直接绕过数据库对OS进行文件操作是非常不成熟的做法,无论是出于什么目的。很多致命的错误都是一系列的rm造成的。愿文章描述的场景永不会在所有运维生产系统中出现!