ITPub博客

首页 > 数据库 > Oracle > oracle数据文件被误删恢复

oracle数据文件被误删恢复

原创 Oracle 作者:彩伦 时间:2016-09-08 08:49:59 0 删除 编辑

----数据文件被误恢复方法有两种。如果发现数据文件被删除咯,此时数据库是open状态,可以直接通过句柄恢复,如果发现数据库已经宕机了,就只能用其他方式咯。具体方法,如下:

 

1.利用句柄恢复数据文件

1.1 环境准备

SQL> create table t tablespace users as select * from dba_objects;

Table created.

SQL> select count(*) from t;

  COUNT(*)

----------

     86961

SQL> alter system switch logfile;

System altered.

SQL>  create table t_curr tablespace users as select * from dba_objects;

Table created.

SQL> select name from v$datafile;

NAME

--------------------------------------------------------------------------------

/u01/app/oracle/oradata/orcl/system01.dbf

/u01/app/oracle/oradata/orcl/sysaux01.dbf

/u01/app/oracle/oradata/orcl/undotbs01.dbf

/u01/app/oracle/oradata/orcl/users01.dbf

/u01/app/oracle/oradata/orcl/example01.dbf

 

[oracle@xuan1 ~]$ ls /u01/app/oracle/oradata/orcl/

control01.ctl  redo01.log     redo03.log     system01.dbf   undotbs01.dbf 

example01.dbf  redo02.log     sysaux01.dbf   temp01.dbf     users01.dbf   

[oracle@xuan1 ~]$ rm -rf /u01/app/oracle/oradata/orcl/*

 

-----不要重启实例!!!

--------执行操作由root执行,如果用oracle身份去执行,cp完成一些数据文件后,数据库报错会自动shutdown。使用root拷贝完成后,在shutdown数据库,然后修改属组权限,最后启动数据库

    在误删除发生的时候,千万不要停止数据库实例。只要进程还握有文件句柄,还是有可能恢复的。

    直接查找lgwr的进程比查找dbwn要好。因为lgwr除了握有数据文件的句柄还握有日志文件的句柄。

 

1.2 查找dbwr进程,找文件句柄

------测试的时候,因为是删除的所有数据文件,所以,当数据库ckpt时,发现数据库文件不在就会强制shutdown数据库,所以,实验时快点。

 

----注意,最后用root身份去cp,最后再改回属组

----首先需要找到dbwr的进程号

[root@xuan1 ~]# ps -ef|grep ora_dbw|grep -v grep

oracle     2572      1  0 00:13 ?        00:00:00 ora_dbw0_orcl

 

----然后进入该进程号目录

[root@xuan1 ~]# ll /proc/2572/fd/

lrwx------ 1 oracle oinstall 64 Jul 18 00:18 258 -> /u01/app/oracle/oradata/orcl/system01.dbf (deleted)

lrwx------ 1 oracle oinstall 64 Jul 18 00:18 259 -> /u01/app/oracle/oradata/orcl/sysaux01.dbf (deleted)

lrwx------ 1 oracle oinstall 64 Jul 18 00:18 260 -> /u01/app/oracle/oradata/orcl/undotbs01.dbf (deleted)

lrwx------ 1 oracle oinstall 64 Jul 18 00:18 261 -> /u01/app/oracle/oradata/orcl/users01.dbf (deleted)

lrwx------ 1 oracle oinstall 64 Jul 18 00:18 262 -> /u01/app/oracle/oradata/orcl/example01.dbf (deleted)

lrwx------ 1 oracle oinstall 64 Jul 18 00:18 263 -> /u01/app/oracle/oradata/orcl/temp01.dbf (deleted)

 

----把删除的文件拷贝会原位置即可

[root@xuan1 ~]#  ll /proc/2572/fd |grep deleted|awk '{print "cp "$9" "$11}'

[root@xuan1 ~]# cd /proc/2572/fd

cp 256 /u01/app/oracle/oradata/orcl/control01.ctl

cp 258 /u01/app/oracle/oradata/orcl/system01.dbf

cp 259 /u01/app/oracle/oradata/orcl/sysaux01.dbf

cp 260 /u01/app/oracle/oradata/orcl/undotbs01.dbf

cp 261 /u01/app/oracle/oradata/orcl/users01.dbf

cp 262 /u01/app/oracle/oradata/orcl/example01.dbf

cp 263 /u01/app/oracle/oradata/orcl/temp01.dbf

----运行上面生成的脚本即可

 

1.3 查找lgwr进程,找文件句柄

----其实,拷贝数据文件,直接找redo进程就可以咯。

[root@xuan1 ~]# ps -ef|grep ora_lgwr|grep -v grep

oracle     2574      1  0 00:13 ?        00:00:00 ora_lgwr_orcl

[root@xuan1 ~]# ll /proc/2574/fd/

 

---和恢复数据文件一样

[root@xuan1 ~]#  ll /proc/2574/fd |grep deleted|awk '{print "cp "$9" "$11}'  

[root@xuan1 ~]# cd /proc/2574/fd

cp 256 /u01/app/oracle/oradata/orcl/control01.ctl

cp 258 /u01/app/oracle/oradata/orcl/redo01.log

cp 259 /u01/app/oracle/oradata/orcl/redo02.log

cp 260 /u01/app/oracle/oradata/orcl/redo03.log

cp 261 /u01/app/oracle/oradata/orcl/system01.dbf

cp 262 /u01/app/oracle/oradata/orcl/sysaux01.dbf

cp 263 /u01/app/oracle/oradata/orcl/undotbs01.dbf

cp 264 /u01/app/oracle/oradata/orcl/users01.dbf

cp 265 /u01/app/oracle/oradata/orcl/example01.dbf

cp 266 /u01/app/oracle/oradata/orcl/temp01.dbf

 

[root@xuan1 fd]# chown  -R oracle. /u01/app/oracle/oradata/orcl/*

SQL> startup

ORACLE instance started.

Total System Global Area  943669248 bytes

Fixed Size                  2258880 bytes

Variable Size             603981888 bytes

Database Buffers          331350016 bytes

Redo Buffers                6078464 bytes

ORA-00214: control file '/u01/app/oracle/fast_recovery_area/orcl/control02.ctl'

version 775 inconsistent with file '/u01/app/oracle/oradata/orcl/control01.ctl'

version 773

 

----如果报这个错,是因为控制文件scn不一致,最好先把所有的控制文件都备份,然后拷贝那个我们刚刚恢复的控制文件去覆盖其他的,这样一来,oepn就不会报其他错咯。如下

[oracle@xuan1 ~]$ cp /u01/app/oracle/oradata/orcl/control01.ctl /u01/app/oracle/fast_recovery_area/orcl/control02.ctl

SQL> alter database mount;

Database altered.

SQL> alter database open;

Database altered.

 

----数据都没有丢失

SQL>  select count(*) from t;

  COUNT(*)

----------

     86961

SQL>  select count(*) from t_curr;

  COUNT(*)

----------

     86962

 

2.使用extundelete恢复linux中删除的文件

----该软件下载地址:http://extundelete.sourceforge.net/

----该文档reference:http://www.xifenfei.com/2012/08/

 

2.1 编译安装extundelete

----安装之前需要安装e2fsprogs e2fsprogs-libs e2fsprogs-devel这些包

[root@xuan1 ~]# yum -y install e2fsprogs e2fsprogs-libs e2fsprogs-devel

[root@xuan1 ~]# bunzip2 extundelete-0.2.4.tar.bz2

[root@xuan1 ~]# tar xvf extundelete-0.2.4.tar

[root@xuan1 ~]# cd extundelete-0.2.4

[root@xuan1 extundelete-0.2.4]# ./configure

[root@xuan1 extundelete-0.2.4]# make && make install

 

----查看帮助

[root@xuan1 ~]# /usr/local/bin/extundelete --help

 

2.2 使用extundelete注意事项

    extundelete恢复数据的过程:在数据被误删除后,第一时间要做的就是卸载被删除数据所在的分区,如果是根分区的数据遭到误删,就需要将系统进入单用户模式,并且将根分区以只读模式挂载。这样做的原因很简单,因为将文件删除后,仅仅是将文件的inode节点中的扇区指针清零,实际文件还储存在磁盘上,如果磁盘继续以读写模式挂载,这些已删除的文件的数据块就可能被操作系统重新分配出去,在这些数据库被新的数据覆盖后,这些数据就真的丢失了,恢复工具也无力回天。所以!以只读模式挂载磁盘可以尽量降低数据库中数据被覆盖的风险,以提高恢复数据成功的比例。

 

--umount或者read only 分区(如果umount不成功,可以通过fuser -km /www类似方法找出来占用进程)  fuser -m -u /home

 umount /dev/partition

 mount -o remount,ro /dev/partition

 

--恢复文件

extundelete /dev/partition --restore-all

extundelete /dev/partition --restore-directory /backup/gnutool-delete

extundelete /dev/partition --restore-files /etc/passwd

 

 

2.3 数据删除恢复实验

----挂载一个磁盘

[root@xuan1 ~]# fdisk -l /dev/sdb

[root@xuan1 ~]# mkfs.ext4 /dev/sdb

[root@xuan1 ~]# mkdir /u02

[root@xuan1 ~]# mount /dev/sdb /u02

[root@xuan1 ~]# df -h|grep u02

/dev/sdb                       99G  188M   94G   1% /u02

 

----将u01下面的文件copy到u02下

[root@xuan1 ~]# cp -rf /u01/* /u02/

 

----删除文件,删除之前记录一下md5值

[root@xuan1 orcl]# pwd

/u02/app/oracle/oradata/orcl

[root@xuan1 orcl]# md5sum system01.dbf

11b1a003032bfcf9dd7932e497f29ae5  system01.dbf

[root@xuan1 orcl]# rm -rf system01.dbf

[root@xuan1 orcl]# ls system01.dbf

ls: cannot access system01.dbf: No such file or directory

 

----马上卸载分区,并通过extundelete命令查询该分区可恢复信息

[root@xuan1 ~]# umount /dev/sdb

[root@xuan1 ~]# extundelete /dev/sdb --inode 2

 

----恢复所有删除文件

[root@xuan1 tmp]# extundelete /dev/sdb --restore-all

----会在当前创建一个RECOVERED_FILES目录用于保存恢复的文件

[root@xuan1 tmp]# cd RECOVERED_FILES/

[root@xuan1 RECOVERED_FILES]# ll

total 4

drwxr-xr-x 3 root root 4096 Jul 19 00:11 app

 

----此时在挂载磁盘,将文件copy会原目录

[root@xuan1 RECOVERED_FILES]# mount /dev/sdb /u02

[root@xuan1 RECOVERED_FILES]# cp app/oracle/oradata/orcl/system01.dbf /u02/app/oracle/oradata/orcl/.

[root@xuan1 RECOVERED_FILES]# md5sum /u02/app/oracle/oradata/orcl/system01.dbf

11b1a003032bfcf9dd7932e497f29ae5  /u02/app/oracle/oradata/orcl/system01.dbf

 

 

3.oracle数据文件被删除,恢复

3.1 环境准备

SQL> create table test tablespace users as select * from dba_objects;

Table created.

SQL> select count(*) from test;

  COUNT(*)

----------

     86961

SQL> alter system switch logfile;

System altered.

SQL>  create table test_curr tablespace users as select * from dba_objects;

Table created.

SQL> select name from v$datafile;

NAME

--------------------------------------------------------------------------------

/u01/app/oracle/oradata/orcl/system01.dbf

/u01/app/oracle/oradata/orcl/sysaux01.dbf

/u01/app/oracle/oradata/orcl/undotbs01.dbf

/u01/app/oracle/oradata/orcl/users01.dbf

/u01/app/oracle/oradata/orcl/example01.dbf

 

[oracle@xuan1 ~]$ls /u01/app/oracle/oradata/orcl/

control01.ctl  redo01.log     redo03.log     system01.dbf   undotbs01.dbf 

example01.dbf  redo02.log     sysaux01.dbf   temp01.dbf     users01.dbf   

[oracle@xuan1 ~]$ rm -rf /u01/app/oracle/oradata/orcl/user01.dbf

 

SQL> select * from test;

select * from test

              *

ERROR at line 1:

ORA-01116: error in opening database file 4

ORA-01110: data file 4: '/u01/app/oracle/oradata/orcl/users01.dbf'

ORA-27041: unable to open file

Linux-x86_64 Error: 2: No such file or directory

Additional information: 3

SQL> alter system switch logfile;   ----切换几次日志后,数据库宕机

ERROR:

ORA-03114: not connected to ORACLE

 

----再次启动数据库时,open的时候报错

SQL> startup

ORACLE instance started.

Total System Global Area  943669248 bytes

Fixed Size                  2258880 bytes

Variable Size             566233152 bytes

Database Buffers          369098752 bytes

Redo Buffers                6078464 bytes

Database mounted.

ORA-01157: cannot identify/lock data file 4 - see DBWR trace file

ORA-01110: data file 4: '/u01/app/oracle/oradata/orcl/users01.dbf'

 

----看告警看trc文件

----在linux中确定该数据是否存在

 

3.2 恢复文件

SQL> select instance_name,status from v$instance;

INSTANCE_NAME    STATUS

---------------- ------------

orcl             MOUNTED

 

----因为数据宕机过,所以,想通过句柄方式恢复删除的数据文件是不可能的咯

ps -ef|grep ora_dbw|grep -v grep

ps -ef|grep ora_lgwr|grep -v grep

 

----这时候,如果删除的数据文件不重要,可以直接offline,然后启动数据库,最后再把该数据文件在数据库中删除

 

3.2.1 关闭数据库,卸载该分区

----既然数据库已经宕机过,无法重新启动,就把数据库shutdown后,试一下能恢复数据文件不

SQL> shut immediate

[oracle@xuan1 ~]$ lsnrctl stop

[oracle@xuan1 ~]$ emctl stop dbconsole

[oracle@xuan1 ~]$ df -hT |grep u01

/dev/sdb                     ext4    99G  6.7G   87G   8% /u01

 

[root@xuan1 ~]# umount /u01

umount: /u01: device is busy.

        (In some cases useful info about processes that use

         the device is found by lsof(8) or fuser(1))

[root@xuan1 ~]# fuser -km /u01/    ---直接kill掉占用u01目录的进程

/u01/:                7154

----或者先找到该进程,然后手动kill

[root@xuan1 ~]# fuser -m -u /u01/

/u01/:                7736(oracle)

[root@xuan1 ~]# kill -9 7736

 

[root@xuan1 ~]# umount /u01

 

3.2.2 使用extundelete恢复删除的数据文件

----这里直接恢复所有被删除的文件

[root@xuan1 tmp]# extundelete /dev/sdb --restore-all

[root@xuan1 tmp]# cd RECOVERED_FILES/

 [root@xuan1 RECOVERED_FILES]# ls

app  file.4063659  file.4063660  file.4063661  file.4063662  file.4196257

[root@xuan1 RECOVERED_FILES]# cd app/oracle/oradata/orcl/

[root@xuan1 orcl]# ls

users01.dbf

 

----找到删除的文件后,将该文件copy回原路径

[root@xuan1 orcl]# mount /dev/sdb /u01/

[root@xuan1 orcl]# ls /u01/app/oracle/oradata/orcl/

control01.ctl  redo01.log     redo03.log     system01.dbf   undotbs01.dbf 

example01.dbf  redo02.log     sysaux01.dbf   temp01.dbf    

[root@xuan1 orcl]# cp users01.dbf /u01/app/oracle/oradata/orcl/.

 

----最后注意改回属组权限

[root@xuan1 orcl]# chown -R oracle. /u01/app/oracle/oradata/orcl/users01.dbf

 

3.2.3 启动oracle数据库

SQL> startup    ----比较顺利,直接就启动咯

SQL> select instance_name,status from v$instance;

INSTANCE_NAME    STATUS

---------------- ------------

orcl             OPEN

 

SQL> select count(*) from test_curr;   ---数据也都在

  COUNT(*)

----------

     86994

 

 

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30130773/viewspace-2124679/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2015-02-06

  • 博文量
    138
  • 访问量
    892105