今天接到个电话,说某省的一个非归档数据库中,为某个表空间添加数据文件时误操作,加成了文件系统(数据库是使用裸设备做数据文件的),当时处理的方式是直接在os级rm掉了这个数据文件。结果在oem里面点击表空间的时候就报数据文件找不到了。然后,另一个同事将该数据文件执行offline drop后,在oem里面点击表空间不报错了。
但是这是否就正常了呢?
我们说,表空间就像一个容器,像一个空的水杯,一旦我们把水倒进水杯里面,我们就分辨不出那些水是第一次倒入的,哪些是第二次倒入的。我们也无法把已经倒进去的水区别开来,把最后一次倒入的水在倒出来。
我们检查了那个数据文件说涉及到的表空间,将这个表空间下的所有的表都count(*)一遍,如果没有报错,那么我们比较幸运,那个被rm掉的文件里面没有数据,如果有数据,那就比较惨了……count(*)的结果表明:我们就是属于那种不幸的情况。
我们首先考虑恢复数据,由于是非规定模式,redolog就显得比较重要了。如果redolog没有使用一圈的话,我们还能用redolog来进行恢复:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
SQL> archive log list Database log mode No Archive Mode Automatic archival Disabled Archive destination /oradata/arch/oralocal Oldest online log sequence 101 Current log sequence 103 SQL> SQL> select * from v$log; GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARCHIV STATUS FIRST_CHANGE# FIRST_TIME ---------- ---------- ---------- ---------- ---------- ------ -------------------------------- ------------- ------------ 1 1 103 10485760 1 NO CURRENT 832673 08-DEC-07 2 1 101 10485760 1 NO INACTIVE 832669 08-DEC-07 3 1 102 10485760 1 NO INACTIVE 832671 08-DEC-07 SQL> create tablespace test datafile '/oradata/test.dbf' size 1m; Tablespace created. SQL> create table hr.xx tablespace test as select * from dba_users where 1=2; Table created. SQL> insert into hr.xx select * from dba_users; 37 rows created. SQL> / 37 rows created. SQL> / 37 rows created. SQL> / 37 rows created. SQL> commit; Commit complete. SQL> select count(*) from hr.xx; COUNT(*) ---------- 148 SQL> select * from v$log; GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARCHIV STATUS FIRST_CHANGE# FIRST_TIME ---------- ---------- ---------- ---------- ---------- ------ -------------------------------- ------------- ------------ 1 1 103 10485760 1 NO CURRENT 832673 08-DEC-07 2 1 101 10485760 1 NO INACTIVE 832669 08-DEC-07 3 1 102 10485760 1 NO INACTIVE 832671 08-DEC-07 SQL> ! [oracle@localdb ~]$ cd /oradata [oracle@localdb oradata]$ ll total 1088 drwxr-xr-x 3 oracle dba 4096 Dec 6 15:42 arch drwxr-xr-x 3 oracle dba 4096 Dec 6 15:37 cfile drwxr-xr-x 3 oracle dba 4096 Dec 6 16:19 dfile drwxr-xr-x 3 oracle dba 4096 Dec 6 15:37 lfile drwx------ 2 oracle dba 16384 Dec 6 15:33 lost+found -rw-r----- 1 oracle dba 1056768 Dec 8 11:23 test.dbf [oracle@localdb oradata]$ rm test.dbf [oracle@localdb oradata]$ ll total 48 drwxr-xr-x 3 oracle dba 4096 Dec 6 15:42 arch drwxr-xr-x 3 oracle dba 4096 Dec 6 15:37 cfile drwxr-xr-x 3 oracle dba 4096 Dec 6 16:19 dfile drwxr-xr-x 3 oracle dba 4096 Dec 6 15:37 lfile drwx------ 2 oracle dba 16384 Dec 6 15:33 lost+found [oracle@localdb oradata]$ exit exit SQL> select * from v$log; GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARCHIV STATUS FIRST_CHANGE# FIRST_TIME ---------- ---------- ---------- ---------- ---------- ------ -------------------------------- ------------- ------------ 1 1 103 10485760 1 NO CURRENT 832673 08-DEC-07 2 1 101 10485760 1 NO INACTIVE 832669 08-DEC-07 3 1 102 10485760 1 NO INACTIVE 832671 08-DEC-07 SQL> shutdown abort; ORACLE instance shut down. SQL> SQL> startup ORACLE instance started. Total System Global Area 313860096 bytes Fixed Size 1299624 bytes Variable Size 276826968 bytes Database Buffers 29360128 bytes Redo Buffers 6373376 bytes Database mounted. ORA-01157: cannot identify/lock data file 6 - see DBWR trace file ORA-01110: data file 6: '/oradata/test.dbf' SQL> alter database datafile 6 offline; alter database datafile 6 offline * ERROR at line 1: ORA-01145: offline immediate disallowed unless media recovery enabled SQL> alter database datafile 6 offline drop; Database altered. SQL> alter database create datafile 6 as '/oradata/test.dbf'; Database altered. SQL> recover datafile 6; Media recovery complete. SQL> alter database open; Database altered. SQL> select count(*) from hr.xx; select count(*) from hr.xx * ERROR at line 1: ORA-00376: file 6 cannot be read at this time ORA-01110: data file 6: '/oradata/test.dbf' SQL> alter database datafile 6 online; Database altered. SQL> select count(*) from hr.xx; COUNT(*) ---------- 148 |
上述的这个情况是属于比较幸运的情况,我们的redolog还没有被重复利用,但是实际中遇到的情况往往是,等到发现数据文件误删报错,已经是好几天之外了,生产系统中redolog的切换,已经切换n次了。因此,在这里,我们只能尽量的挽回数据了:
首先查看被删除的数据文件涉及到哪几个表空间,将这些表空间里面的所有表都count一次,以确定有哪些表受到影响,如果是分区表,还比较好办些,分别count每一个分区的数据确认没有问题,将没有问题的数据进行exp备份,或者ctas到别的表。然后将表drop掉之后进行重建,注意重建的时候也要重新表的索引约束等等。如果对于非分区表,无法一个分区一个分区的进行测试,因此只能exp表,在exp的时候,会报错,但是无须理会,exp出来成一个文件后,可以imp到另一用户,重新本用户的表,在insert into table select * from user_b.table,注意索引和约束也要重建。
当然,重建表只是最低影响的处理,正确的处理方式应该是重建表空间,对表空间中的所有表都进行重建,但是这个工程量就比较大了……
DBA切记:数据文件一旦加入表空间,切勿随意删除!!(特别是9i的数据库,10g还能drop empty datafile。)
4条评论
10.2才可以drop empty datafile。。
10.1还没有这个功能。这个是需要注意 的
re 古董:谢谢提醒,之前确实不知道10.1是没这个功能的。
最重要的,还是要拿掉文件系统的写权限,这样就不至于加数据文件加到文件系统了。人为错误不可避免,还是靠技术来尽量保障比较可靠些
re NinGoo:是加到了oracle的软件的安装目录下,控制不了-_-!
我们的HPUX的机器上,对vg确实只给root权限,里面的lv给oracle权限,所以在vg下就不能加不存在的文件系统了。