数据库坏块(corruption) 的类型可以按照坏块所属对象的不同,分为用户数据坏块,数据字典坏块,undo坏块,控制文件坏块,redo坏块
概述
-------------
数据库坏块(corruption) 的类型可以按照坏块所属对象的不同,分为用户数据坏块,数据字典坏块,undo坏块,控制文件坏块,redo坏块,lob坏块,index坏块等等;也可以按照坏块产生的原因,分为物理坏块(physical corruption)和逻辑坏块(logical corruption )。
本文主要讨论用户数据发生物理坏块(physical corruption)分析和解决方法。
物理坏块
-------------
常见的物理坏块(physical block corruptions)有块头和块尾信息不一致(fractured/incomplete),checksum值无效,数据块信息全部为0等情况,并且可能伴随错误ora-1578和ora-1110
为了及时发现物理坏块和准确定位坏块产生的原因,oracle建议设置初始化参数db_block_checksum=typical(默认值)。一般情况下,物理坏块是由于底层os/disk系统错误/损坏,,导致数据块被修改,数据块标志为坏块(corruption)。
case分享
-------------
数据块的checksum值无效是一种常见的物理坏块,当数据库初始化参数db_block_checksum=typical(默认值)时,dbwr进程将数据块写入disk时会计算数据块的checksum,并且将checksum值记录在数据块的位置offset 16和17;当从disk读取该数据块时,oracle重新计算数据块的checksum,并且与记录在数据块中的checksum做异或运算(xor),如果异或结果为非0,说明数据块被修改过,数据块为坏块(corruption)。
1. 当前数据库初始化参数配置db_block_checksum=typical,因此从disk读取数据块时校验checksum:
sql> show parameter db_block_checksum
name type value
------------------------------------ ----------- ------------------------------
db_block_checksum string typical
2. 查询表dept时发现有坏块,报错信息ora-1578和ora-1110,坏块为file # 4, block # 133
sql> select * from dept;
select * from dept
*
error at line 1:
ora-01578: oracle data block corrupted (file # 4, block # 133)
ora-01110: data file 4: '/u01/app/oracle/oradata/orcl/users01.dbf'
3. 出现以上错误的同时在alert log中也有详细错误信息,这些错误信息说明数据块(file # 4, block # 133)损坏的原因是checksum无效。数据块中记录的checksum值为0x8167(这个值是上一次dbwr写入磁盘时计算的),读取数据块时重新计算得到的checksum是0x8122,checksum值异或运算(xor)的结果是0x45 (computed block checksum)。由于两次checksum值不同(即异或结果为非0),说明数据块被修改过,数据块为坏块(corruption)。
alert log错误信息:
hex dump of (file 4, block 133) in trace file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_20892.trc
corrupt block relative dba: 0x01000085 (file 4, block 133)
bad check value found during multiblock buffer read
data in bad block:
type: 6 format: 2 rdba: 0x01000085
last change scn: 0x0000.0023d69a seq: 0x5 flg: 0x06
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0xd69a0605
check value in block header: 0x8167
computed block checksum: 0x45
reading datafile '/u01/app/oracle/oradata/orcl/users01.dbf' for corruption at rdba: 0x01000085 (file 4, block 133)
reread (file 4, block 133) found same corrupt data (no logical check)
sun mar 23 22:53:40 2014
corrupt block found
tsn = 4, tsname = users
rfn = 4, blk = 133, rdba = 16777349
objn = 14343, objd = 14343, object = dept, subobject =
segment owner = james, segment type = table segment
errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_20892.trc (incident=182595):
ora-01578: oracle data block corrupted (file # 4, block # 133)
ora-01110: data file 4: '/u01/app/oracle/oradata/orcl/users01.dbf'
4.1 对应的orcl_ora_20892.trc中也有数据块的信息,其中数据块上记录的checksum值是0x8167(chkval)
block dump from disk:
buffer tsn: 4 rdba: 0x01000085 (4/133)
scn: 0x0000.0023d69a seq: 0x05 flg: 0x06 tail: 0xd69a0605
frmt: 0x02 chkval: 0x8167 type: 0x06=trans data
hex dump of block: st=0, typ_found=1
4.2 通过dd也查看数据块中记录的checksum值, offset 16,17 对应的是checksum值0x8167
$ dd if=/u01/app/oracle/oradata/orcl/users01.dbf bs=8192 count=1 skip=133 of=/tmp/dd133.out
$ od -x /tmp/dd133.out
0000000 a206 0000 0085 0100 d69a 0023 0000 0605
0000020 8167 0000 0001 0000 3807 0000 2fef 000c
^^^^
5. 修复数据坏块的方法可以通过备份恢复或者dbms_repair.skip_corrupt_blocks跳过坏块。
5.1 方法#1 rman数据块恢复:
rman> run {blockrecover datafile 4 block 133;}
sql> select * from dept;
deptno dname loc
---------- -------------- -------------
10 accounting dalian
20 research dallas
30 sales chicago
40 operations boston
5.2 方法#2 dbms_repair.skip_corrupt_blocks跳过坏块,然后将dept表中的其他数据导出重建表
sql> alter session set db_file_multiblock_read_count=1;
sql> execute dbms_repair.skip_corrupt_blocks('james','dept');
sql> create table dept_new as select * from dept;
本文永久更新链接地址: