Welcome 微信登录

首页 / 数据库 / MySQL / Oracle使用句柄实现特定场景的无备份恢复

在dba的工作中,备份是一切工作的基础。如果没有备份,本来很简单的恢复工作也会难上加难,如果业务数据要求很高,造成数据的丢失或者损坏,就是重大事故了。使用rman备份或者做一个完整的系统级备份也是很重要的,如果在特定的场景下,没有备份,如果还能恢复,那就太幸运了。当数据库中的某个数据文件误删的时候,如果数据库还没有重启的时候,还是能够做一些工作的。因为文件对应的句柄还没有释放。我们可以从里面找到一个镜像的备份实现我们的数据恢复。一定注意这种恢复不一定是完全的数据恢复,如果在数据文件删除的瞬间,有开启的事务,那么这些事务也是提交过的。--------------------------------------推荐阅读 --------------------------------------RMAN 配置归档日志删除策略 http://www.linuxidc.com/Linux/2013-11/92670.htmOracle基础教程之通过RMAN复制数据库 http://www.linuxidc.com/Linux/2013-07/87072.htmRMAN备份策略制定参考内容 http://www.linuxidc.com/Linux/2013-03/81695.htmRMAN备份学习笔记 http://www.linuxidc.com/Linux/2013-03/81892.htmOracle数据库备份加密 RMAN加密 http://www.linuxidc.com/Linux/2013-03/80729.htm--------------------------------------分割线 --------------------------------------在删除之前,我们先来看看测试环境的数据文件情况。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(*)
 ----------
     5660SQL> 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 21 05:36 14 -> /proc/938/fd
 lr-x------ 1 ora11g dba 64 Nov 21 05:36 15 -> /dev/zero
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 16 -> /u03/ora11g/product/11.2.0/dbhome_1/dbs/hc_TEST01.dat
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 17 -> /u03/ora11g/product/11.2.0/dbhome_1/dbs/lkTEST01
 lr-x------ 1 ora11g dba 64 Nov 21 05:36 18 -> /u03/ora11g/product/11.2.0/dbhome_1/rdbms/mesg/oraus.msb
 lrwx------ 1 ora11g dba 64 Nov 21 06:05 19 -> socket:[1434598]
 l-wx------ 1 ora11g dba 64 Nov 21 05:36 2 -> /dev/null
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 256 -> /u03/ora11g/oradata/TEST01/control01.ctl
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 257 -> /u03/ora11g/oradata/TEST01/control02.ctl
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 258 -> /u03/ora11g/oradata/TEST01/system01.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 259 -> /u03/ora11g/oradata/TEST01/sysaux01.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 260 -> /u03/ora11g/oradata/TEST01/undotbs01.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 261 -> /u02/ora11g/testdata1.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 262 -> /u03/ora11g/oradata/TEST01/pool_data03.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 263 -> /u03/ora11g/oradata/TEST01/pool_data01.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 264 -> /u03/ora11g/oradata/TEST01/pool_data02.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 265 -> /u03/ora11g/oradata/TEST01/pool_data04.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 266 -> /u03/ora11g/oradata/TEST01/pool_data05.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 267 -> /u01/ora11g/pool_data06.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 268 -> /u01/ora11g/pool_data07.dbf
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 269 -> /u03/ora11g/oradata/TEST01/temp01.dbf
lrwx------ 1 ora11g dba 64 Nov 21 05:55 270 -> /u01/ora11g/test_delete.dbf (deleted)
 lr-x------ 1 ora11g dba 64 Nov 21 05:36 3 -> /dev/null
 lr-x------ 1 ora11g dba 64 Nov 21 05:36 4 -> /dev/null
 lr-x------ 1 ora11g dba 64 Nov 21 05:36 5 -> /dev/null
 lr-x------ 1 ora11g dba 64 Nov 21 05:36 6 -> /dev/null
 lrwx------ 1 ora11g dba 64 Nov 21 05:36 7 -> /u03/ora11g/product/11.2.0/dbhome_1/dbs/hc_TEST01.dat
 lr-x------ 1 ora11g dba 64 Nov 21 05:36 8 -> /dev/null
 lr-x------ 1 ora11g dba 64 Nov 21 05:36 9 -> /dev/null可以看到句柄的信息,删除的数据文件状态已经在/proc/xx/fd里面有所体现了。
 这个时候我们手动拷贝数据文件到目标目录。[ora11g@rac1 fd]$ cp 270 /u01/ora11g/test_delete.dbf
 [ora11g@rac1 fd]$
拷贝完成之后,使用测试用户来做一些简单的验证。发现创建一个新表的操作顺利完成了。SQL> conn test_delete/test_delete
 Connected.
 SQL> create table test4 as select *from cat;
 Table created.
来看看在数据文件恢复之前的情况。
SQL> select count(*)from test;  --数据没有问题,条数和预期一致。
  COUNT(*)
 ----------
     5660SQL> select count(*)from test1 where object_name="a";  --这个部分,事务已经做了提交。可以说明变更的数据已经写入了数据文件。期望应该是0条。
  COUNT(*)
 ----------
       99
然后我们来尝试做数据文件的恢复。SQL> conn / as sysdba
 Connected.
 SQL> alter database datafile "/u01/ora11g/test_delete.dbf" offline;
 Database altered.
 SQL> recover datafile "/u01/ora11g/test_delete.dbf";
 Media recovery complete.
 SQL> alter database datafile "/u01/ora11g/test_delete.dbf" online;
 Database altered.
来看看数据文件恢复之后的情况SQL> select count(*)from test;  --数据没有问题,条数和预期一致。
  COUNT(*)
 ----------
     5660SQL> select count(*)from test1 where object_name="a";  --这个部分,事务已经做了提交。可以说明变更的数据已经写入了数据文件。期望应该是0条。
  COUNT(*)
 ----------
       99重新启动数据库来看看能否正常启停。数据的变化情况。
SQL> shutdown immediate
 Database closed.
 Database dismounted.
 ORACLE instance shut down.
 SQL> startup
 ORACLE instance started.Total System Global Area  313159680 bytes
 Fixed Size                  2227944 bytes
 Variable Size           255852824 bytes
 Database Buffers         50331648 bytes
 Redo Buffers                4747264 bytes
 Database mounted.
 Database opened.SQL> conn test_delete
 Enter password:
 Connected.
 SQL> select count(*)from test;  --数据没有问题,条数和预期一致。
  COUNT(*)
 ----------
     5660SQL> select count(*)from test1 where object_name="a";  --这个部分,事务已经做了提交。可以说明变更的数据已经写入了数据文件。期望应该是0条。
  COUNT(*)
 ----------
       99所以通过上面的例子也能够说明备份重于一切,而且这种恢复还是需要运气的,不过某正程度来说,有总比没有好。而且这种恢复也是需要运气,如果数据库一开始停掉的话,也无能为力了。 关于sysdba,sysoper,dba的区别关于dual表的破坏性测试相关资讯      Oracle备份恢复 
  • Oracle数据库物理文件备份/恢复  (07/20/2015 20:53:07)
  • Oracle控制文件的备份、恢复以及多  (04/10/2014 15:15:06)
  • Oracle用控制文件旧备份恢复后数据  (08/19/2013 09:38:27)
  • Oracle 数据备份与恢复  (04/26/2014 09:35:49)
  • Oracle 10g控制文件备份到文件与手  (02/23/2014 09:03:34)
  • 非归档下Oracle的备份和恢复  (08/19/2013 09:30:17)
本文评论 查看全部评论 (0)
表情: 姓名: 字数