首页 > 数据库 > Oracle > oracle数据文件被误删恢复
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除了握有数据文件的句柄还握有日志文件的句柄。
------测试的时候,因为是删除的所有数据文件,所以,当数据库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
----运行上面生成的脚本即可
----其实,拷贝数据文件,直接找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
----该软件下载地址:http://extundelete.sourceforge.net/
----该文档reference:http://www.xifenfei.com/2012/08/
----安装之前需要安装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
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
----挂载一个磁盘
[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
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中确定该数据是否存在
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,然后启动数据库,最后再把该数据文件在数据库中删除
----既然数据库已经宕机过,无法重新启动,就把数据库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
----这里直接恢复所有被删除的文件
[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
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/ ,如需转载,请注明出处,否则将追究法律责任。