在 UNIX® 环境中,文件无处不在,这便产生了一句格言:“任何事物都是文件”。通过文件不仅仅可以访问常规数据,通常还可以访问网络连接和硬件。在有些情况下,当您使用 ls 请求目录清单时,将出现相应的条目。在其他情况下,如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字,不存在相应的目录清单。但是在后台为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。
当进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录条目。该文件占用的存储空间并不会没其他应用程序覆盖,通过df命令查看,剩余空间没有发生改变。
下面利用这个特性来看看,在误删除了数据库文件时如何进行恢复。
1、所有数据库文件全部被误删除。
1.1 场景描述
1.1.1查询数据库数据情况
1.1.2 误删除数据
[oracle@rac1 ~]$ cd /oracle/oradata/orcl/ [oracle@rac1 orcl]$ pwd /oracle/oradata/orcl [oracle@rac1 orcl]$ ll 总计 1491828 -rw-r—– 1 oracle oinstall 9781248 07-02 10:22 control01.ctl -rw-r—– 1 oracle oinstall 52429312 07-02 10:03 redo01.log -rw-r—– 1 oracle oinstall 52429312 07-02 10:03 redo02.log -rw-r—– 1 oracle oinstall 52429312 07-02 10:22 redo03.log -rw-r—– 1 oracle oinstall 566239232 07-02 10:22 sysaux01.dbf -rw-r—– 1 oracle oinstall 734011392 07-02 10:21 system01.dbf -rw-r—– 1 oracle oinstall 20979712 07-02 10:04 temp01.dbf -rw-r—– 1 oracle oinstall 52436992 07-02 10:21 undotbs01.dbf -rw-r—– 1 oracle oinstall 5251072 07-02 10:08 users01.dbf
[oracle@rac1 orcl]$ rm -rf *
1.1.3 DML操作,这时并没有发现alert.log有任何告警信息
SQL> select * from google.test; ID NAME ———- ———- 1 1 SQL> insert into google.test values(2,2); 1 row created. SQL> commit; Commit complete. SQL> select file#,status from v$datafile; FILE# STATUS ———- ——- 1 SYSTEM 2 ONLINE 3 ONLINE 4 ONLINE
发现DML操作正常。下面进行switch logfile操作
SQL> alter system archive log current; alter system archive log current * ERROR at line 1: ORA-16038: log 3 sequence# 21 cannot be archived ORA-00312: online log 3 thread 1: ‘/oracle/oradata/orcl/redo03.log’ alert.log中有明显的错误信息提示 Errors in file /oracle/diag/rdbms/orcl_p/orcl/trace/orcl_m000_3739.trc: ORA-00210: cannot open the specified control file ORA-00202: control file: ‘/oracle/oradata/orcl/control01.ctl’ ORA-27041: unable to open file Linux Error: 2: No such file or directory Additional information: 3
1.2 解决方法
从上面的实验可以看出,误删除了数据库文件,数据库并没有立即发出告警。在发现问题时,不要盲目行动,在不关闭数据库的情况下。
可以通过文件描述符恢复被删除的文件。
1.2.1 根据lgwr进程找被误删除的文件
[oracle@rac1 orcl]$ ps -ef|grep ora_lgwr|grep -v grep oracle 3242 1 0 10:03 ? 00:00:01 ora_lgwr_orcl [oracle@rac1 orcl]$ ps -ef|grep ora_lgwr|grep -v grep oracle 3242 1 0 10:03 ? 00:00:01 ora_lgwr_orcl [oracle@rac1 orcl]$ lsof -a -p 3242 |grep deleted oracle 3242 oracle 256u REG 8,3 9781248 2887591 /oracle/oradata/orcl/control01.ctl (deleted) oracle 3242 oracle 258u REG 8,3 52429312 2887592 /oracle/oradata/orcl/redo01.log (deleted) oracle 3242 oracle 259u REG 8,3 52429312 2887593 /oracle/oradata/orcl/redo02.log (deleted) oracle 3242 oracle 260u REG 8,3 52429312 2887594 /oracle/oradata/orcl/redo03.log (deleted) oracle 3242 oracle 261u REG 8,3 734011392 2887587 /oracle/oradata/orcl/system01.dbf (deleted) oracle 3242 oracle 262u REG 8,3 566239232 2887588 /oracle/oradata/orcl/sysaux01.dbf (deleted) oracle 3242 oracle 263u REG 8,3 52436992 2887589 /oracle/oradata/orcl/undotbs01.dbf (deleted) oracle 3242 oracle 264u REG 8,3 5251072 2887590 /oracle/oradata/orcl/users01.dbf (deleted) oracle 3242 oracle 265u REG 8,3 20979712 2887595 /oracle/oradata/orcl/temp01.dbf (deleted)
1.2.2 通过文件描述符复制丢失的文件到其他录。
无需担心在同一分区会覆盖被删除的文件,因为进程没有释放的文件(deleted),系统并不会释放文件占据的区域。通过
df -h可以验证。删除前后剩余空间没有增加。
[oracle@rac1 orcl]$ cd /proc/3242/fd [oracle@rac1 fd]$ ll |grep deleted lrwx—— 1 oracle oinstall 64 07-02 10:35 256 -> /oracle/oradata/orcl/control01.ctl (deleted) lrwx—— 1 oracle oinstall 64 07-02 10:35 258 -> /oracle/oradata/orcl/redo01.log (deleted) lrwx—— 1 oracle oinstall 64 07-02 10:35 259 -> /oracle/oradata/orcl/redo02.log (deleted) lrwx—— 1 oracle oinstall 64 07-02 10:35 260 -> /oracle/oradata/orcl/redo03.log (deleted) lrwx—— 1 oracle oinstall 64 07-02 10:35 261 -> /oracle/oradata/orcl/system01.dbf (deleted) lrwx—— 1 oracle oinstall 64 07-02 10:35 262 -> /oracle/oradata/orcl/sysaux01.dbf (deleted) lrwx—— 1 oracle oinstall 64 07-02 10:35 263 -> /oracle/oradata/orcl/undotbs01.dbf (deleted) lrwx—— 1 oracle oinstall 64 07-02 10:35 264 -> /oracle/oradata/orcl/users01.dbf (deleted) lrwx—— 1 oracle oinstall 64 07-02 10:35 265 -> /oracle/oradata/orcl/temp01.dbf (deleted) [oracle@rac1 fd]$ cp 256 /home/oracle/control01.ctl cp 258 /home/oracle/redo01.log cp 259 /home/oracle/redo02.log cp 260 /home/oracle/redo03.log cp 261 /home/oracle/system01.dbf cp 262 /home/oracle/sysaux01.dbf cp 263 /home/oracle/undotbs01.dbf cp 264 /home/oracle/users01.dbf cp 265 /home/oracle/temp01.dbf
很显然如果当前目录空间足够大,也可以直接复制到本地,这样关闭数据库后无需再复制回数据文件。
确认所有的丢失的文件都已经被复制后,关闭数据库
SQL> shutdown abort
重新复制文件到原来的位置
$mv * /oracle/oradata/orcl/
重新启动数据库
SQL> startup
1.2.3 检查数据文件丢失
SQL> select * from google.test; ID NAME ———- ———- 1 1 2 2
2、第二种情况,部分数据文件被误删除。
2.1 场景描述
[oracle@rac1 orcl]$ rm -rf users01.dbf DML操作,这时并没有发现alert.log有任何告警信息 SQL> select * from google.test; ID NAME ———- ———- 1 1 SQL> insert into google.test values(3,3); 1 row created. SQL> commit; Commit complete. SQL> select file#,status from v$datafile; FILE# STATUS ———- ——- 1 SYSTEM 2 ONLINE 3 ONLINE 4 ONLINE
2.2 解决方法
[oracle@rac1 orcl]$ ps -ef|grep ora_lgwr|grep -v grep oracle 8192 1 0 11:18 ? 00:00:00 ora_lgwr_orcl [oracle@rac1 orcl]$ lsof -a -p 8192|grep deleted oracle 8192 oracle 264u REG 8,3 5251072 3932223 /oracle/oradata/orcl/users01.dbf (deleted)
通过文件描述符复制丢失的文件。对user01.dbf操作看貌似没有错误。但是查询/proc/8192/fd下的文件,仍然能够查询到该文件丢失。
通过offline、online操作。系统就不会再认为该文件丢失。
$cd /proc/8192/fd $cp 264 /oracle/oradata/orcl/users01.dbf SQL> alter database datafile 4 offline; Database altered. SQL> recover datafile 4; Media recovery complete. SQL> alter database datafile 4 online;