在dba的工作中,备份是一切工作的基础。如果没有备份,本来很简单的恢复工作也会难上加难,如果业务数据要求很高,造成数据的丢失或者损坏,就是重大事故了。使用rman备份或者做一个完整的系统级备份也是很重要的,如果在特定的场景下,没有备份,如果还能恢复,那就太幸运了。
当数据库中的某个数据文件误删的时候,如果数据库还没有重启的时候,还是能够做一些工作的。因为文件对应的句柄还没有释放。我们可以从里面找到一个镜像的备份实现我们的数据恢复。一定注意这种恢复不一定是完全的数据恢复,如果在数据文件删除的瞬间,有开启的事务,那么这些事务也是提交过的。
--------------------------------------推荐阅读 --------------------------------------
--------------------------------------分割线 --------------------------------------
在删除之前,我们先来看看测试环境的数据文件情况。
SQL> select tablespace_name,file_name from dba_data_files;
?TABLESPACE_NAME? ? ? ? ? ? ? ? FILE_NAME
?------------------------------ --------------------------------------------------
?SYSTEM? ? ? ? ? ? ? ? ? ? ? ? /u03/ora11g/oradata/TEST01/system01.dbf
?SYSAUX? ? ? ? ? ? ? ? ? ? ? ? /u03/ora11g/oradata/TEST01/sysaux01.dbf
?UNDOTBS? ? ? ? ? ? ? ? ? ? ? ? /u03/ora11g/oradata/TEST01/undotbs01.dbf
?TEST_DATA1? ? ? ? ? ? ? ? ? ? /u02/ora11g/testdata1.dbf
?POOL_DATA? ? ? ? ? ? ? ? ? ? ? /u03/ora11g/oradata/TEST01/pool_data03.dbf
?POOL_DATA? ? ? ? ? ? ? ? ? ? ? /u03/ora11g/oradata/TEST01/pool_data01.dbf
?POOL_DATA? ? ? ? ? ? ? ? ? ? ? /u03/ora11g/oradata/TEST01/pool_data02.dbf
?POOL_DATA? ? ? ? ? ? ? ? ? ? ? /u03/ora11g/oradata/TEST01/pool_data04.dbf
?POOL_DATA? ? ? ? ? ? ? ? ? ? ? /u03/ora11g/oradata/TEST01/pool_data05.dbf
?POOL_DATA? ? ? ? ? ? ? ? ? ? ? /u01/ora11g/pool_data06.dbf
?POOL_DATA? ? ? ? ? ? ? ? ? ? ? /u01/ora11g/pool_data07.dbf
?11 rows selected.
我们创建一个新的表空间和数据文件,
SQL> create tablespace test_delete datafile '/u01/ora11g/test_delete.dbf' size 10M;
?Tablespace created.
SQL> create user test_delete identified by test_delete default tablespace test_delete quota unlimited on test_delete;
?User created.
然后创建一个用户,在里面添加一些数据。
grant connect,resource to test_delete;
?conn test_delete/test_delete
?create table test as select *from all_objects;
?create index test_ind on test(object_id);
?create table test1 as select *from test where rownum<100;
?update test1 set object_name='a' ;
注意最后的一条update语句,我们还没有做commit操作,所以此时数据还可能没有写入数据文件,从事务的角度来说,这个update还没有完成。
?我们来看看是否能够恢复所有的数据,包括未提交的事务数据。
?在删除之前,简单来一个检查。
SQL> select count(*)from test;
? COUNT(*)
?----------
? ? ? 5660
SQL> select count(*)from test1 where object_name='a';
? COUNT(*)
?----------
? ? ? ? 99
开始手动删除数据文件
[ora11g@rac1 fd]$ rm /u01/ora11g/test_delete.dbf
删除之后尝试做一个create操作,竟然成功了。
SQL> create table test3 as select *from test1;
?Table created.
继续尝试一个Update,终于报错了,得到了期望之中的Ora错误。
update test set object_id=1
? ? ? ? *
?ERROR at line 1:
?ORA-01116: error in opening database file 12
?ORA-01110: data file 12: '/u01/ora11g/test_delete.dbf'
?ORA-27041: unable to open file
?Linux-x86_64 Error: 2: No such file or directory
?Additional information: 3
这个时候开始考虑使用句柄来查看对应的数据文件,
?首先使用ps得到dbw对应的进程号。
[ora11g@rac1 proc]$ ps -ef|grep ora_dbw
?ora11g? ? 938? ? 1? 0 Nov20 ?? ? ? ? 00:00:07 ora_dbw0_TEST01
?ora11g? ? 7819? 5794? 0 06:04 pts/0? ? 00:00:00 grep ora_dbw
然后在/proc/938/fd里面查看
[ora11g@rac1 proc]$ ll /proc/938/fd? ?
?total 0
?lr-x------ 1 ora11g dba 64 Nov 21 05:36 0 -> /dev/null
?l-wx------ 1 ora11g dba 64 Nov 21 05:36 1 -> /dev/null
?lr-x------ 1 ora11g dba 64 Nov 21 05:36 10 -> /dev/zero
?lr-x------ 1 ora11g dba 64 Nov 21 05:36 11 -> /dev/zero
?lrwx------ 1 ora11g dba 64 Nov 21 05:36 12 -> /u03/ora11g/product/11.2.0/dbhome_1/dbs/hc_TEST01.dat
?lr-x------ 1 ora11g dba 64 Nov 21 05:36 13 -> /u03/ora11g/product/11.2.0/dbhome_1/rdbms/mesg/oraus.msb
?lr-x------ 1 ora11g dba 64 Nov 2