此文已由作者赵旭东授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
如果数据库被rm命令给删了,只要数据库的主进程还没有退出,就可以从文件句柄中恢复文件最终挽回损失。以下以oracle数据库为例,介绍一下恢复文件的步骤:
1.模拟删库(包含数据文件,控制文件,联机日志文件)
sys@GLOBAL>col NAME for a100; sys@GLOBAL>select FILE#,NAME from v$datafile; FILE# NAME ---------- ---------------------------------------------------------------------------------------------------- 1 /home/oracle/app/oradata/global/system01.dbf 2 /home/oracle/app/oradata/global/sysaux01.dbf 3 /home/oracle/app/oradata/global/undotbs01.dbf 4 /home/oracle/app/oradata/global/users01.dbf 5 /home/oracle/app/oradata/global/GLOBAL_ORDER01.dbf 6 /home/oracle/app/oradata/global/TS_DCIS_WMS01.dbf 7 /home/oracle/app/oradata/global/TS_DCIS_WMS02.dbf 7 rows selected. sys@GLOBAL>!rm -f /home/oracle/app/oradata/global/* sys@GLOBAL>create table t tablespace users as select * from dual; create table t tablespace users as select * from dual * ERROR at line 1: ORA-01116: error in opening database file 4 ORA-01110: data file 4: '/home/oracle/app/oradata/global/users01.dbf' ORA-27041: unable to open file Linux-x86_64 Error: 2: No such file or directory Additional information: 3
数据库文件和控制文件以及联机日志文件都已经被删了,尝试创建一个表时oracle报打不开数据文件异常。
2.检查 lgwr 的进程 PID
[oracle@ol6-a ~]$ ps -ef | grep lgwr | grep -v grep oracle 3804 1 0 Dec02 ? 00:01:40 ora_lgwr_global
3.lgwr 会打开所有数据文件、联机日志文件、控制文件的句柄。在 proc 目录中可以查到,目录名是进程 PID,fd 表示文件描述符。
[oracle@ol6-a ~]$ cd /proc/3804/fd [oracle@ol6-a fd]$ ls -l total 0 lr-x------. 1 oracle oinstall 64 Dec 7 03:49 0 -> /dev/null l-wx------. 1 oracle oinstall 64 Dec 7 03:49 1 -> /dev/null lrwx------. 1 oracle oinstall 64 Dec 7 03:49 10 -> /home/oracle/app/product/11.2.0/db_1/dbs/lkGLOBAL lr-x------. 1 oracle oinstall 64 Dec 7 03:49 13 -> /home/oracle/app/product/11.2.0/db_1/rdbms/mesg/oraus.msb l-wx------. 1 oracle oinstall 64 Dec 7 03:49 2 -> /dev/null lrwx------. 1 oracle oinstall 64 Dec 7 03:49 256 -> /home/oracle/app/oradata/global/control01.ctl (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 257 -> /home/oracle/app/fast_recovery_area/global/control02.ctl lrwx------. 1 oracle oinstall 64 Dec 7 03:49 258 -> /home/oracle/app/oradata/global/redo01.log (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 259 -> /home/oracle/app/oradata/global/redo02.log (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 260 -> /home/oracle/app/oradata/global/redo03.log (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 261 -> /home/oracle/app/oradata/global/system01.dbf (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 262 -> /home/oracle/app/oradata/global/sysaux01.dbf (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 263 -> /home/oracle/app/oradata/global/undotbs01.dbf (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 264 -> /home/oracle/app/oradata/global/users01.dbf (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 265 -> /home/oracle/app/oradata/global/GLOBAL_ORDER01.dbf (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 266 -> /home/oracle/app/oradata/global/TS_DCIS_WMS01.dbf (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 267 -> /home/oracle/app/oradata/global/TS_DCIS_WMS02.dbf (deleted) lrwx------. 1 oracle oinstall 64 Dec 7 03:49 268 -> /home/oracle/app/oradata/global/temp01.dbf (deleted) lr-x------. 1 oracle oinstall 64 Dec 7 03:49 3 -> /dev/null lr-x------. 1 oracle oinstall 64 Dec 7 03:49 4 -> /dev/null lr-x------. 1 oracle oinstall 64 Dec 7 03:49 5 -> /dev/null lr-x------. 1 oracle oinstall 64 Dec 7 03:49 6 -> /home/oracle/app/product/11.2.0/db_1/rdbms/mesg/oraus.msb lr-x------. 1 oracle oinstall 64 Dec 7 03:49 7 -> /proc/3804/fd lr-x------. 1 oracle oinstall 64 Dec 7 03:49 8 -> /dev/zero lrwx------. 1 oracle oinstall 64 Dec 7 03:49 9 -> /home/oracle/app/product/11.2.0/db_1/dbs/hc_global.dat
4.直接 cp 这些句柄文件名回原位置。
[oracle@ol6-a fd]$ cp 256 /home/oracle/app/oradata/global/control01.ctl [oracle@ol6-a fd]$ cp 258 /home/oracle/app/oradata/global/redo01.log [oracle@ol6-a fd]$ cp 259 /home/oracle/app/oradata/global/redo02.log [oracle@ol6-a fd]$ cp 260 /home/oracle/app/oradata/global/redo03.log [oracle@ol6-a fd]$ cp 261 /home/oracle/app/oradata/global/system01.dbf [oracle@ol6-a fd]$ cp 262 /home/oracle/app/oradata/global/sysaux01.dbf [oracle@ol6-a fd]$ cp 263 /home/oracle/app/oradata/global/undotbs01.dbf [oracle@ol6-a fd]$ cp 264 /home/oracle/app/oradata/global/users01.dbf [oracle@ol6-a fd]$ cp 265 /home/oracle/app/oradata/global/GLOBAL_ORDER01.dbf [oracle@ol6-a fd]$ cp 266 /home/oracle/app/oradata/global/TS_DCIS_WMS01.dbf [oracle@ol6-a fd]$ cp 267 /home/oracle/app/oradata/global/TS_DCIS_WMS02.dbf [oracle@ol6-a fd]$ cp 268 /home/oracle/app/oradata/global/temp01.dbf
5.检查数据库是否可用:
[oracle@ol6-a fd]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Wed Dec 7 03:47:39 2016 Copyright (c) 1982, 2013, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, Oracle Label Security, OLAP, Data Mining and Real Application Testing options sys@GLOBAL>create table t tablespace users as select * from dual; Table created.
完成数据文件恢复。
6.如果数据库不可用,可能还会涉及到数据文件等的恢复过程,使用以下命令恢复数据文件:
alter database datafile 1 offline; recover datafile 1; alter database datafile 1 online;
恢复的原理:在 Linux 操作系统中,如果文件从操作系统级别被rm掉,之前打开该文件的进程仍然持有相应的文件句柄,所指向的文件仍然可以读写,并且该文件的文件描述符可以从 /proc 目录中获得。但是要注意的是,此时如果关闭数据库,则此句柄会消失,那么除了扫描磁盘进行文件恢复之外就没有其它方法了,因此在数据库出现问题的时候,如果不确认情况的复杂程度,千万不要随便关闭数据库。重启数据库往往是没有意义的,甚至是致命的。
如果不慎关闭数据库,句柄丢失,还可以通过恢复工具来恢复数据库文件(只要数据在磁盘上还没有被覆盖,且有足够的磁盘空间存放待恢复的文件),可以使用的工具有testdisk和extundelete。
以testdisk恢复文件为例,使用testdisk的Filesystem Utils工具将被误删的文件恢复到指定目录:
1.选择误删文件所在介质
2.使用Filesystem Utils工具
3.选择需要恢复的文件并恢复到指定目录:
免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 Spring Boot 学习系列(02)—使用热部署,提升开发效
【推荐】 Spark——为数据分析处理提供更为灵活的赋能