暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

ORACLE 恢复 rm 的数据文件

原创 lps 2022-12-23
1125

接上文:https://www.modb.pro/db/589259
环境描述:
OS:CentOS Linux release 7.6.1810 (Core)
DB:ORACLE 19.17
两个数据库实例分别为 orclyxxt
rm 的数据文件的实例没有被关闭(也就是dbf的访问具柄没有释放)。

[root@dsmart:/root]# ps -ef |grep ora_pmon|grep -v grep oracle 10710 1 0 Dec20 ? 00:00:07 ora_pmon_orcl oracle 11331 1 0 Dec20 ? 00:00:07 ora_pmon_yxxt

其中 orcl 实例的 /oradata/ORCL/tbs01.dbf被 rm掉,然后此数据文件又被创建到了 yxxt 实例。orcl 实例没有重启过。相应数据文件对应表空间的表仍然可以查询数据。
查看 yxxt 实例的tbs 创建语句:

sys@YXXT 10:52:05> select dbms_metadata.get_ddl('TABLESPACE','TBS') ddl FROM dual; DDL -------------------------------------------------------- CREATE TABLESPACE "TBS" DATAFILE '/oradata/ORCL/tbs01.dbf' SIZE 104857600 AUTOEXTEND ON NEXT 1048576000 MAXSIZE 32767M LOGGING ONLINE PERMANENT BLOCKSIZE 8192 EXTENT MANAGEMENT LOCAL AUTOA

查看 orcl 实例的 tbs 创建语句:

sys@ORCL 10:37:10> select dbms_metadata.get_ddl('TABLESPACE','TBS') ddl FROM dual; DDL ------------------------------------------------------------ CREATE TABLESPACE "TBS" DATAFILE '/oradata/ORCL/tbs01.dbf' SIZE 104857600 AUTOEXTEND ON NEXT 1048576000 MAXSIZE 32767M LOGGING ONLINE PERMANENT BLOCKSIZE 8192 EXTENT MANAGEMENT LOCAL AUTOA

可以看到 orcl 实例和yxxt 都有tbs的表空间和 /oradata/ORCL/tbs01.dbf 的数据文件。

sys@ORCL 11:00:51> select segment_name,segment_type,owner from dba_segments where tablespace_name='TBS'; SEGMENT_NAME SEGMENT_TYPE OWNER -------------------- ------------------ --------------------------------- A TABLE SYS sys@ORCL 10:53:58> select count(1) from a; COUNT(1) ---------- 5242880 sys@YXXT 11:01:30> select segment_name,segment_type,owner from dba_segments where tablespace_name='TBS'; SEGMENT_NAME SEGMENT_TYPE OWNER -------------------- ------------------ -------------------- Y TABLE SYS sys@YXXT 11:07:05> select count(1) from y; COUNT(1) ---------- 1048576

其中orcl 实例对应的 a 表有5242880行数据,yxxt 实例对应的 y 表有1048576 行数据。
通过lsof |grep delete命令查看删除文件的信息,这里通过 grep 过滤 dbf 文件。可以看到tbs01.dbf 的状态是 deleted,但是仍然有进城在访问,句柄没有释放,这样此dbf文件可以有效的恢复。

[root@dsmart:/root]# lsof |grep delete|grep dbf ora_dbw0_ 10767 oracle 263uW REG 253,1 104865792 917524 /oradata/ORCL/tbs01.dbf (deleted) ora_ckpt_ 10775 oracle 261u REG 253,1 104865792 917524 /oradata/ORCL/tbs01.dbf (deleted) [root@dsmart:/root]# ps -ef |grep 10767|grep -v grep oracle 10767 1 0 Dec20 ? 00:00:09 ora_dbw0_orcl [root@dsmart:/root]# ps -ef |grep 10775|grep -v grep oracle 10775 1 0 Dec20 ? 00:00:29 ora_ckpt_orcl

/oradata/ORCL/tbs01.dbf 的句柄被 orcl 实例的 ckpt和dbw进程占用。
由于目前 /oradata/ORCL/tbs01.dbf 文件目前被 yxxt 实例占有,这里将 yxxt 实例占有的dbf 重命名,如下操作:

sys@YXXT 11:26:50> alter tablespace tbs offline; Tablespace altered. sys@YXXT 11:26:56> !mv /oradata/ORCL/tbs01.dbf /oradata/ORCL/tbs01_yxxt.dbf sys@YXXT 11:27:23> alter tablespace tbs rename datafile '/oradata/ORCL/tbs01.dbf' to '/oradata/ORCL/tbs01_yxxt.dbf'; Tablespace altered. sys@YXXT 11:28:14> alter tablespace tbs online; Tablespace altered. sys@YXXT 11:28:23> select dbms_metadata.get_ddl('TABLESPACE','TBS') ddl FROM dual; DDL ----------------------------------------------- CREATE TABLESPACE "TBS" DATAFILE '/oradata/ORCL/tbs01_yxxt.dbf' SIZE 10485 7600 AUTOEXTEND ON NEXT 1048576000 MAXSIZE 32767M LOGGING ONLINE PERMANENT BLOCKSIZE 8192 EXTENT MANAGEMENT LOCAL sys@YXXT 11:29:08> select count(1) from y; COUNT(1) ---------- 1048576

将 yxxt 实例的表空间的 /oradata/ORCL/tbs01_yxxt.dbf rename 到/oradata/ORCL/tbs01_yxxt.dbf
这样 yxxt 实例跟 /oradata/ORCL/tbs01.dbf 没有任何关系了。目前yxxt实例是正常的,能够正常查询 tbs 表空间上的 y表,数据仍然是 1048576.
下面恢复 orcl 库的 /oradata/ORCL/tbs01.dbf 文件

[oracle@dsmart:/home/oracle]$ lsof |grep delete|grep dbf ora_dbw0_ 10767 oracle 263uW REG 253,1 104865792 917524 /oradata/ORCL/tbs01.dbf (deleted) ora_ckpt_ 10775 oracle 261u REG 253,1 104865792 917524 /oradata/ORCL/tbs01.dbf (deleted) [oracle@dsmart:/home/oracle]$ ps -ef |grep -E "10767|10775"|grep -v grep oracle 10767 1 0 Dec20 ? 00:00:09 ora_dbw0_orcl oracle 10775 1 0 Dec20 ? 00:00:30 ora_ckpt_orcl [oracle@dsmart:/home/oracle]$
[oracle@dsmart:/proc/10767/fd]$ cd /proc/10767/fd [oracle@dsmart:/proc/10767/fd]$ ls -l total 0 lr-x------ 1 oracle oinstall 64 Dec 23 11:34 0 -> /dev/null l-wx------ 1 oracle oinstall 64 Dec 23 11:34 1 -> /dev/null l-wx------ 1 oracle oinstall 64 Dec 23 11:34 2 -> /dev/null lrwx------ 1 oracle oinstall 64 Dec 23 11:34 256 -> /oradata/ORCL/control01.ctl lrwx------ 1 oracle oinstall 64 Dec 23 11:34 257 -> /oradata/ORCL/control02.ctl lrwx------ 1 oracle oinstall 64 Dec 23 11:34 258 -> /oradata/ORCL/system01.dbf lrwx------ 1 oracle oinstall 64 Dec 23 11:34 259 -> /oradata/ORCL/sysaux01.dbf lrwx------ 1 oracle oinstall 64 Dec 23 11:34 260 -> /oradata/ORCL/undotbs01.dbf lrwx------ 1 oracle oinstall 64 Dec 23 11:34 261 -> /oradata/ORCL/users01.dbf lrwx------ 1 oracle oinstall 64 Dec 23 11:34 262 -> /oradata/ORCL/temp01.dbf lrwx------ 1 oracle oinstall 64 Dec 23 11:34 263 -> /oradata/ORCL/tbs01.dbf (deleted) lr-x------ 1 oracle oinstall 64 Dec 23 11:34 3 -> /dev/null lr-x------ 1 oracle oinstall 64 Dec 23 11:34 4 -> /u01/app/oracle/product/19.3.0/db/rdbms/mesg/oraus.msb lr-x------ 1 oracle oinstall 64 Dec 23 11:34 5 -> /proc/10767/fd lrwx------ 1 oracle oinstall 64 Dec 23 11:34 6 -> /u01/app/oracle/product/19.3.0/db/dbs/hc_orcl.dat lrwx------ 1 oracle oinstall 64 Dec 23 11:34 7 -> /u01/app/oracle/product/19.3.0/db/dbs/lkORCL lr-x------ 1 oracle oinstall 64 Dec 23 11:34 8 -> /u01/app/oracle/product/19.3.0/db/rdbms/mesg/oraus.msb [oracle@dsmart:/proc/10767/fd]$ cp 263 /tmp/263_tbs01.dbf [oracle@dsmart:/proc/10767/fd]$ cd /proc/10775/fd [oracle@dsmart:/proc/10775/fd]$ ls -l total 0 lr-x------ 1 oracle oinstall 64 Dec 23 11:34 0 -> /dev/null l-wx------ 1 oracle oinstall 64 Dec 23 11:34 1 -> /dev/null l-wx------ 1 oracle oinstall 64 Dec 23 11:34 2 -> /dev/null lrwx------ 1 oracle oinstall 64 Dec 23 11:34 256 -> /oradata/ORCL/control01.ctl lrwx------ 1 oracle oinstall 64 Dec 23 11:34 257 -> /oradata/ORCL/control02.ctl lrwx------ 1 oracle oinstall 64 Dec 23 11:34 258 -> /oradata/ORCL/system01.dbf lrwx------ 1 oracle oinstall 64 Dec 23 11:34 259 -> /oradata/ORCL/sysaux01.dbf lrwx------ 1 oracle oinstall 64 Dec 23 11:34 260 -> /oradata/ORCL/undotbs01.dbf lrwx------ 1 oracle oinstall 64 Dec 23 11:34 261 -> /oradata/ORCL/tbs01.dbf (deleted) lrwx------ 1 oracle oinstall 64 Dec 23 11:34 262 -> /oradata/ORCL/users01.dbf lr-x------ 1 oracle oinstall 64 Dec 23 11:34 3 -> /dev/null lr-x------ 1 oracle oinstall 64 Dec 23 11:34 4 -> /u01/app/oracle/product/19.3.0/db/rdbms/mesg/oraus.msb lr-x------ 1 oracle oinstall 64 Dec 23 11:34 5 -> /proc/10775/fd lrwx------ 1 oracle oinstall 64 Dec 23 11:34 6 -> /u01/app/oracle/product/19.3.0/db/dbs/hc_orcl.dat lrwx------ 1 oracle oinstall 64 Dec 23 11:34 7 -> /u01/app/oracle/product/19.3.0/db/dbs/lkORCL lr-x------ 1 oracle oinstall 64 Dec 23 11:34 8 -> /u01/app/oracle/product/19.3.0/db/rdbms/mesg/oraus.msb [oracle@dsmart:/proc/10775/fd]$ cp 261 /tmp/261-tbs01.dbf [oracle@dsmart:/proc/10767/fd]$ cd /tmp/ [oracle@dsmart:/tmp]$ ls -l *tbs* -rw-r----- 1 oracle oinstall 104865792 Dec 23 11:37 261-tbs01.dbf -rw-r----- 1 oracle oinstall 104865792 Dec 23 11:37 263_tbs01.dbf [oracle@dsmart:/tmp]$ md5sum 261-tbs01.dbf 99bf4495aef775392d53f741fbb88ad7 261-tbs01.dbf [oracle@dsmart:/tmp]$ md5sum 263_tbs01.dbf 99bf4495aef775392d53f741fbb88ad7 263_tbs01.dbf [oracle@dsmart:/tmp]$

可以看到俩进程复制出来的文件是同一个,md5都是一样的。
保险起见把 a 表的数据exp出来

[oracle@dsmart:/home/oracle]$ exp Export: Release 19.0.0.0.0 - Production on Fri Dec 23 15:11:18 2022 Version 19.17.0.0.0 Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved. Username: / as sysdba Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.17.0.0.0 Enter array fetch buffer size: 4096 > Export file: expdat.dmp > a.dmp (1)E(ntire database), (2)U(sers), or (3)T(ables): (2)U > t Export table data (yes/no): yes > yes Compress extents (yes/no): yes > yes Export done in AL32UTF8 character set and AL16UTF16 NCHAR character set About to export specified tables via Conventional Path ... Table(T) or Partition(T:P) to be exported: (RETURN to quit) > a . . exporting table A 5242880 rows exported Table(T) or Partition(T:P) to be exported: (RETURN to quit) > Export terminated successfully with warnings.

由于是sys下的对象,这里通过exp交互的方式将sys.a 表dump出来。

[oracle@dsmart:/tmp]$ cp 263_tbs01.dbf /oradata/ORCL/tbs01.dbf [oracle@dsmart:/tmp]$ ll /oradata/ORCL/tbs01.dbf -rw-r----- 1 oracle oinstall 104865792 Dec 23 15:15 /oradata/ORCL/tbs01.dbf [oracle@dsmart:/tmp]$ s SQL*Plus: Release 19.0.0.0.0 - Production on Fri Dec 23 15:15:21 2022 Version 19.17.0.0.0 Copyright (c) 1982, 2022, Oracle. All rights reserved. Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.17.0.0.0 sys@ORCL 15:15:22> shutdown immediate Database closed. Database dismounted. ORACLE instance shut down. sys@ORCL 15:15:49> startup ORACLE instance started. Total System Global Area 973077208 bytes Fixed Size 8895192 bytes Variable Size 385875968 bytes Database Buffers 570425344 bytes Redo Buffers 7880704 bytes Database mounted. Database opened. sys@ORCL 23-DEC-22>

将从 /proc/10767/fd.263 句柄里的文件复制到原来的位置,重启数据库,能够正常启动。
这样 orcl 和yxxt 实例都恢复正常了。
总结:
这次 rm 数据文件的恢复,关键是orcl 实例没有关闭数据库,删除的数据文件一直被进程访问,这样的话就可以通过以上方式进行恢复了。

最后修改时间:2022-12-26 09:48:40
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论