模拟坏块故障并抢救数据(一.普通表)

OS:Oracle Linux 5u8
DB:Oracle 11.2.0.4.0

已创建示例表空间CCDATA,schema为cc,数据文件o1_mf_ccdata_bn8l5x7l_.dbf

找到该表空间中的一个表CUSTACCOUNTS,看看它的block_id范围


点击(此处)折叠或打开

  1. select owner, segment_name, segment_type,
  2. extent_id, file_id, block_id, blocks
  3. from dba_extents
  4. where owner='CC' and segment_name='CUSTACCOUNTS'

OWNER SEGMENT_NAME SEGMENT_TYPE EXTENT_ID FILE_ID BLOCK_ID BLOCKS
CC CUSTACCOUNTS TABLE 0 5 896 128
CC CUSTACCOUNTS TABLE 1 5 1152 128
CC CUSTACCOUNTS TABLE 2 5 1408 128
CC CUSTACCOUNTS TABLE 3 5 1664 128
CC CUSTACCOUNTS TABLE 4 5 1792 128
CC CUSTACCOUNTS TABLE 5 5 2048 128
CC CUSTACCOUNTS TABLE 6 5 2304 128
CC CUSTACCOUNTS TABLE 7 5 2560 128
CC CUSTACCOUNTS TABLE 8 5 2688 128
CC CUSTACCOUNTS TABLE 9 5 2944 128
CC CUSTACCOUNTS TABLE 10 5 3200 128
CC CUSTACCOUNTS TABLE 11 5 3456 128
CC CUSTACCOUNTS TABLE 12 5 3712 128
这里我们修改block_id为1000的块,刚好落在这个表里面。

使用UE打开数据文件。怎么确定block_id=1000在数据文件的哪个位置呢。块大小8192字节,8192×1000=8192,000,转换成16进制为007D 0000。随意改这一行第一个数字为FF,保存退出。


注:以上操作要在Oracle关闭状态下操作,别且要做好备份。

打开数据库,试试查找该表。

点击(此处)折叠或打开

  1. SQL> select * from CUSTACCOUNTS;


      CAID CAVALIDFROM         CAVALIDTO
---------- ------------------- -------------------
CANAME
----------------------------------------------------------------
CAPIN
----------------------------------------------------------------
CALASTLOGIN         CAFAILEDLOGINS CALASTFAILEDLOGIN
------------------- -------------- -------------------
     10763 1970-01-01 00:00:00 4312-12-31 23:59:59
0000000000010763
1234
1970-01-01 00:00:00              0 1970-01-01 00:00:00
--查询进行了一段时间后,报错
ERROR:
ORA-01578: ORACLE data block corrupted (file # 5, block # 1000)
ORA-01110: data file 5: '/oradata/APR/datafile/o1_mf_ccdata_bn8l5x7l_.dbf'

仔细看会发现,坏块block_id为1000,正好是我们改掉的块。

这时,如果有RMAN备份,恢复很简单

点击(此处)折叠或打开

  1. RMAN> blockrecover datafile 5 block 1000;
这里我们假设没有RMAN备份,尽可能多的抢救数据。
坏块检查

当前已出现的坏块记录在视图v$database_block_corruption

点击(此处)折叠或打开

  1. select * from v$database_block_corruption

     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTION_TYPE
---------- ---------- ---------- ------------------ ------------------
         5       1000          1                  0 CORRUPT

另外,可以使用DBV命令在线检查数据文件的坏块

点击(此处)折叠或打开

  1. [oracle@apr datafile]$ dbv file=o1_mf_ccdata_bn8l5x7l_.dbf

  2. DBVERIFY: Release 11.2.0.4.0 - Production on Sat May 2 16:54:32 2015

  3. Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.

  4. DBVERIFY - Verification starting : FILE = /oradata/APR/datafile/o1_mf_ccdata_bn8l5x7l_.dbf
  5. Page 10000 is marked corrupt
  6. Corrupt block relative dba: 0x01402710 (file 5, block 10000)
  7. Bad header found during dbv:
  8. Data in bad block:
  9.  type: 255 format: 2 rdba: 0x01402710
  10.  last change scn: 0x0000.0011261f seq: 0x1 flg: 0x06
  11.  spare1: 0x0 spare2: 0x0 spare3: 0x0
  12.  consistency value in tail: 0x261f0601
  13.  check value in block header: 0x7764
  14.  computed block checksum: 0xf9



  15. DBVERIFY - Verification complete

  16. Total Pages Examined : 222848
  17. Total Pages Processed (Data) : 103647
  18. Total Pages Failing (Data) : 0
  19. Total Pages Processed (Index): 54090
  20. Total Pages Failing (Index): 0
  21. Total Pages Processed (Other): 2756
  22. Total Pages Processed (Seg) : 0
  23. Total Pages Failing (Seg) : 0
  24. Total Pages Empty : 62354
  25. Total Pages Marked Corrupt : 1
  26. Total Pages Influx : 0
  27. Total Pages Encrypted : 0
  28. Highest block SCN : 1135578 (0.1135578)


根据罗敏的《感悟Oracle核心技术》,推荐用ROWID扫描方法抢救数据。

//2016.04.08更新
首先需要定位到坏块属于哪个数据库对象。

点击(此处)折叠或打开

  1. select owner,segment_name,segment_type,block_id,blocks from dba_extents
    where file_id = 5
    and block_id  10000;
最小ROW_ID
SELECT dbms_rowid.rowid_create(1, , , , 0) LOW_RID from DUAL;
最大ROW_ID
SELECT dbms_rowid.rowid_create(1, , , +1, 0) HI_RID from DUAL;

点击(此处)折叠或打开

  1. SQL> SELECT OBJECT_ID FROM DBA_OBJECTS WHERE OWNER='CC' AND OBJECT_NAME='CUSTACCOUNTS';


 OBJECT_ID
----------
     87524


点击(此处)折叠或打开

  1. SQL> SELECT dbms_rowid.rowid_create(1, 87524, 5, 1000, 0) LOW_RID from DUAL;
  2. LOW_RID
    ------------------------------------
    AAAVXkAAFAAAAPoAAA
  3. SQL> SELECT dbms_rowid.rowid_create(1, 87524, 5, 1001, 0) HI_RID from DUAL;
  4. HI_RID
    ------------------------------------
    AAAVXkAAFAAAAPpAAA

点击(此处)折叠或打开

  1. --将坏块所在的表转存到另一“安全”的表空间
  2. CREATE TABLE ccbak.CUSTACCOUNTS_BAK
  3. TABLESPACE ccbak
  4. AS SELECT /*+ ROWID(A) */ * FROM CC.CUSTACCOUNTS A
  5. WHERE ROWID < 'AAAVXkAAFAAAAPoAAA';
  6. --继续
  7. INSERT INTO ccbak.CUSTACCOUNTS_BAK 
  8. SELECT /*+ ROWID(A) */ * FROM CC.CUSTACCOUNTS A
  9. WHERE ROWID >= 'AAAVXkAAFAAAAPpAAA';
  10. commit;
将问题表删除,并清空回收站,但坏块并不会消失,最好将整个数据文件所关联的表空间导出,再重新导入。

点击(此处)折叠或打开

  1. drop table CC.CUSTACCOUNTS;
  2. purge recyclebin;
导出表空间,这里的schemas CC就是表空间的全部。

点击(此处)折叠或打开

  1. SQL> create directory ccdir as '/home/oracle/ccdir';
  2. [oracle@apr ~]$ expdp system/oracle@apr schemas=cc dumpfile=cc.dmp DIRECTORY=ccdir
再删除整个表空间

点击(此处)折叠或打开

  1. SQL> drop tablespace ccdata including contents AND datafiles;
重建表空间,并指定其为用户的默认表空间

点击(此处)折叠或打开

  1. SQL> create tablespace ccdata datafile size 1G autoextend on;

  2. SQL> alter user cc default tablespace ccdata;
导入schemas

点击(此处)折叠或打开

  1. impdp system/oracle@apr DIRECTORY=ccdir DUMPFILE=cc.dmp SCHEMAS=cc
重新用DBV检查,确认已经没有坏块了。

注:ROWID扫描方法适用于用户表和分区表段内的坏块,对段头和系统表坏块不适用。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22621861/viewspace-1619107/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/22621861/viewspace-1619107/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值