Oracle数据库数据恢复、性能优化

找回密码
注册
搜索
热搜: 活动 交友 discuz
发新帖

22

积分

0

好友

12

主题
1#
发表于 2012-4-25 15:42:08 | 查看: 6885| 回复: 5
我有一个库,有次意外 一个表空间上 几个数据文件和控制文件都丢失了。

执行:alter database datafile # offline drop ; 后 这几个文件的状态都变成了 recover。

select file_name,file_id,online_status from dba_data_files where online_status='RECOVER'

/oradata/cc/data_space/err/data_tab41.dbf 41 RECOVER
/oradata/cc/data_space/err/data_tab42.dbf 42 RECOVER
/oradata/cc/data_space/err/data_tab43.dbf 43 RECOVER
/oradata/cc/data_space/err/data_tab44.dbf 44 RECOVER
/oradata/cc/data_space/err/data_tab46.dbf 46 RECOVER
/oradata/cc/data_space/err/data_tab47.dbf 47 RECOVER
/oradata/cc/data_space/err/data_tab48.dbf 48 RECOVER
/oradata/cc/data_space/err/data_tab49.dbf 49 RECOVER
/oradata/cc/data_space/err/data_tab56.dbf 56 RECOVER
/oradata/cc/data_space/err/data_tab57.dbf 57 RECOVER
/oradata/cc/data_space/err/data_tab58.dbf 58 RECOVER
/oradata/cc/data_space/err/data_tab59.dbf 59 RECOVER

我再用 alter database create datafile # as 打算重建这几个文件的时候,数据库报:
ORA-01178: file 41 created before last CREATE CONTROLFILE, cannot recreate (控制文件重建过)

现在的问题是 只要我向 这个表空间 插数据  ,数据库就会向上面几个有问题的数据文件写数据,然后就报错 说这个几个文件不能用,

有没有办法 彻底的将这几个文件的 信息从数据库中 抹去,让数据库不再尝试访问这几个文件呢?
2#
发表于 2012-4-25 16:23:31
该问题 延迟到 晚饭时间 之后 或者 明天回答

回复 只看该作者 道具 举报

3#
发表于 2012-4-25 21:16:29
提供 一个思路 ,这不是唯一的解决方案:

通过rowid access的方式将 丢失数据文件的 表空间 重建到 别的表空间上,  并将原损坏表空间 DROP掉。

Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options


SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
PL/SQL Release 10.2.0.5.0 - Production
CORE    10.2.0.5.0      Production
TNS for Linux: Version 10.2.0.5.0 - Production
NLSRTL Version 10.2.0.5.0 - Production


SQL> create tablespace lost datafile '/s01/lost1.dbf' size 10M;

Tablespace created.


SQL> create table losttest tablespace lost as select * from dba_objects;

Table created.


SQL> alter tablespace lost add  datafile '/s01/lost2.dbf' size 10M;

Tablespace altered.


SQL> insert /*+ append */ into losttest select * from losttest;

50722 rows created.

SQL> commit;

Commit complete.

SQL> insert /*+ append */ into losttest select * from losttest;
insert /*+ append */ into losttest select * from losttest
                          *
ERROR at line 1:
ORA-01653: unable to extend table SYS.LOSTTEST by 128 in tablespace LOST



SQL>  alter system checkpoint;

System altered.


SQL> alter system flush buffer_cache;

System altered.


SQL> select count(*) from losttest;

  COUNT(*)
----------
    101444


SQL> select object_id,data_object_id from dba_objects where object_name='LOSTTEST';

OBJECT_ID DATA_OBJECT_ID
---------- --------------
     53710          53710



SQL> select RELATIVE_FNO,BLOCK_ID,BLOCKS from dba_extents where segment_name='LOSTTEST' order by 1,2;

RELATIVE_FNO   BLOCK_ID     BLOCKS
------------ ---------- ----------
           6          9          8
           6         17          8
           6         25          8
           6         33          8
           6         41          8
           6         49          8
           6         57          8
           6         65          8
           6         73          8
           6         81          8
           6         89          8

RELATIVE_FNO   BLOCK_ID     BLOCKS
------------ ---------- ----------
           6         97          8
           6        105          8
           6        113          8
           6        121          8
           6        129          8
           6        137        128
           6        265        128
           6        393        128
           6        521        128
           6        649        128
           6        777        128

RELATIVE_FNO   BLOCK_ID     BLOCKS
------------ ---------- ----------
           6        905        128
           6       1033        128
           7          9        128
           7        137        128
           7        265        128
           7        393        128
           7        521        128
           7        649        128
           7        777        128
           7        905        128
           7       1033        128

33 rows selected.


SQL> col file_name for a40
SQL> select RELATIVE_FNO,FILE_ID,FILE_NAME from dba_data_files where TABLESPACE_NAME='LOST';

RELATIVE_FNO    FILE_ID FILE_NAME
------------ ---------- ----------------------------------------
           6          6 /s01/lost1.dbf
           7          7 /s01/lost2.dbf

           
RELATIVE_FNO      6         /s01/lost1.dbf   rowid from  block 9 to (1033+128)
RELATIVE_FNO    7      /s01/lost2.dbf   rowid from  block 9 to (1033+128)



示例表 losttest 在 RFN 6 上的存储范围是 从 9号块到 1033+128号块(不包括该块)
示例表 losttest 在 RFN 7 上的存储范围是 从 9号块到 1033+128号块(不包括该块)

我们利用以上信息构建 rowid

rowid between  dbms_rowid.rowid_create(1,53710,6,9,0)  and dbms_rowid.rowid_create(1,53710,6,1033+128,0)


SQL>  alter database datafile '/s01/lost2.dbf' offline drop;

Database altered.


SQL> select count(*) from losttest;
select count(*) from losttest
                     *
ERROR at line 1:
ORA-00376: file 7 cannot be read at this time
ORA-01110: data file 7: '/s01/lost2.dbf'



SQL> set linesize 140 pagesize 1400
SQL> select * from v$recover_file;

     FILE# ONLINE  ONLINE_ ERROR                                                                CHANGE# TIME
---------- ------- ------- ----------------------------------------------------------------- ---------- ---------
         7 OFFLINE OFFLINE                                                                      1533717 25-APR-12




SQL>  select dbms_rowid.rowid_create(1,53710,6,9,0) from dual;

DBMS_ROWID.ROWID_C
------------------
AAANHOAAGAAAAAJAAA                        ==> 这是RFN 6上的 低位ROWID


SQL> select dbms_rowid.rowid_create(1,53710,6,1033+128,0) from dual;

DBMS_ROWID.ROWID_C
------------------
AAANHOAAGAAAASJAAA                              ==> 这是RFN 6上的 高位ROWID



注意 不能让SQL FULL Table Scan Losttest ,全表扫描必然触发 ORA-00376错误。 需要让SQL走 rowid access的路径,所以要用到 /*+ ROWID(A) */的 HINT

因为RFN 6上的ROWID 总是小于 RFN 7上的rowid,所以我们仅指定  小于 上面获得的高位ROWID即可


SQL> select  /*+ ROWID(A) */ count(*) from losttest A  where rowid<'AAANHOAAGAAAASJAAA';

  COUNT(*)
----------
     82158


SQL> create table backup_losttest  tablespace users as  select  /*+ ROWID(A) */ *  from losttest A  where rowid<'AAANHOAAGAAAASJAAA';

Table created.


SQL> select count(*) from backup_losttest;

  COUNT(*)
----------
     82158



SQL> drop table losttest purge;

Table dropped.




SQL> drop tablespace lost;

Tablespace dropped.

回复 只看该作者 道具 举报

4#
发表于 2012-4-27 22:31:16

回复 3# 的帖子

刘老大 多谢回复,我按照你的方法 试试看。

回复 只看该作者 道具 举报

5#
发表于 2012-4-27 22:37:13

回复 3# 的帖子

问一下  在这种情况下 能否通过EXP 将该表空间的数据导出,然后新建一个表空间,再将数据导入,最后将原来表空间DROP 掉?

回复 只看该作者 道具 举报

6#
发表于 2012-4-27 22:39:56
"能否通过EXP 将该表空间的数据导出,然后新建一个表空间,再将数据导入,最后将原来表空间DROP 掉?"

前提是 EXP 可用, 如果读取到 跨越多个已丢失的data file 的 TABLE 会出现 ORA-00376错误

回复 只看该作者 道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|Archiver|Oracle数据库数据恢复、性能优化

GMT+8, 2024-12-25 00:19 , Processed in 0.047860 second(s), 21 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部
TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569