ext4文件系统下的corrupt data block 问题处理

背景

 

客户的数据库是11.2.0.1,刚从AIX上迁移到PC服务器上,迁移时,归档文件是放到FRADG上的,备份一直没有问题,但最近将归档目录修改到文件系统后,备份时alter.log就出现如下的报错:

 

RMAN> backup archivelog all;

  

  Starting backup at 06-Jan-16

  current log archived

  allocated channel: ORA_DISK_1

  channel ORA_DISK_1: SID=148 device type=DISK

  channel ORA_DISK_1: starting archived log backup set

  channel ORA_DISK_1: specifying archived log(s) in backup set

  input archived log thread=1 sequence=4 RECID=1 STAMP=793260539

  input archived log thread=1 sequence=5 RECID=2 STAMP=793260573

  input archived log thread=1 sequence=6 RECID=3 STAMP=793260647

  input archived log thread=1 sequence=7 RECID=4 STAMP=793260764

  input archived log thread=1 sequence=8 RECID=5 STAMP=793260835

  input archived log thread=1 sequence=9 RECID=6 STAMP=793260868A6

  channel ORA_DISK_1: starting piece 1 at 06-Jan-16

  RMAN-571: ===========================================================

  RMAN-569: =============== ERROR MESSAGE STACK FOLLOWS ===============

  RMAN-571: ===========================================================

  RMAN-3009: failure of backup command on ORA_DISK_1 channel at 01/06/2016

  06:21:59

  ORA-19599: block number 2048 is corrupt in archived log

  /u01/app/oracle/flash_recovery_area/ORCL/archivelog/2016_01_06/o1_mf_1_10_84j

  xxb4d_.arc

 

 

 

 

  [oracle@localhost trace]$ tail -f alert_orcl.log

 

Bad header found during backing up archived log

  Data in bad block - seq:0. bno:0. time:0

  beg:0 cks:0

  calculated check value: 0

  Reread of seq=10, blocknum=2048,

  file=/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2016_01_06/o1_mf_1_1

  0_84jxxb4d_.arc, found same corrupt data

  Reread of seq=10, blocknum=2048,

  file=/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2016_01_06/o1_mf_1_1

  0_84jxxb4d_.arc, found same corrupt data

  Reread of seq=10, blocknum=2048,

  file=/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2016_01_06/o1_mf_1_1

  0_84jxxb4d_.arc, found same corrupt data

  Reread of seq=10, blocknum=2048,

  file=/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2016_01_06/o1_mf_1_1

  0_84jxxb4d_.arc, found same corrupt data

  Reread of seq=10, blocknum=2048,

  file=/u01/app/oracle/flash_recovery_area/ORCL/archivelog/2016_01_06/o1_mf_1_1

  0_84jxxb4d_.arc, found same corrupt data

  Deleted Oracle managed file

  /u01/app/oracle/flash_recovery_area/ORCL/backupset/2016_01_06/o1_mf_annnn_TAG

  20160106T062152_84jyb44j_.bkp

 

 

分析

 

对于corrupt data,一般都是发生在数据库文件中,有两种情况,一种是物理损坏,是指数据库不能读取到该块内部的数据结构,一般是因为硬件出现问题,内存问题、OS问题、IO子系统问题等引起。而逻辑损坏,则大多是指数据库能读取到该块的数据结构,但是因为数据结构的值不一致,从而被数据库标识为坏块,大部分的逻辑损坏,很多都是因为ORACLE 的BUG 造成的。

 

但对于客户现在这种情况,是归档文件损坏。而用户的环境是新的机器,存储也是新的。硬件出现问题的概率较低,对于内存,OS,IO等问题,如果存在,肯定数据库本身的数据文件也会报坏块,而现在只是归档文件有问题,所以基本上可以排除物理坏块的的可能。

 

 

对于归档文件出现坏块这种情况,在小Y十多年的DBA生涯中也极少遇到,正在苦思冥想,不知如何下手的时候,突然灵光一闪,客户曾提到过,当刚迁移完的时候,归档是存放在ASM中的,那个时候没有出现这种情况。只有迁移到文件系统后,才出现这种情况,这是一条多么重要的线索啊。

 

认真思考了一下归档文件涉及到的进程,无非就是arch写,然后备份时RMAN读的时候报错。那是不是写的时候出现了问题呢?

 

为了证实自己的想法,决定对归档进程进行trace,看看归档进程在进行归档时,ASM与文件系统之间有没有什么特别的地方。

 

会话一:

# ps -ef|grep arc

oracle    2768     1  0 22:11 ?        00:00:01 ora_arc0_orcl

root      3000  2395  0 23:09 pts/1    00:00:00 grep arc

 

strace –o /tmp/strace.log –p 2768

 

会话二:

sqlplus / as sysdba

alter syste switch logfile;

 

 

这个时候,会产生归档进程的整个归档trace,仔细检查这个trace,发现写文件时,只有以下的相关信息:

 

open("...../1_21_900928246.dbf", O_RDWR|O_SYNC|O_DIRECT) = 21

open("...../1_21_900928246.dbf", O_RDWR|O_SYNC|O_DIRECT) = 21

open("...../1_21_900928246.dbf", O_RDWR|O_SYNC|O_DIRECT) = 21

open("...../1_21_900928246.dbf", O_RDWR|O_SYNC|O_DIRECT) = 21

 

然后,将归档路径重新设置回ASM里面,重做上述的过程,对比一下strace的输出

 

open("/dev/raw/raw7", O_RDWR|O_NONBLOCK|O_SYNC|O_DIRECT) = 20

open("/dev/raw/raw6", O_RDWR|O_NONBLOCK|O_SYNC|O_DIRECT) = 20

open("/proc/6236/stat", O_RDONLY)       = 20

 

 

发现其多了一个O_NONBLOCK的关键字,对于一个IO操作的句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明:
基本概念:

  阻塞IO::

   socket 的阻塞模式意味着必须要做完IO 操作(包括错误)才会返回。非阻塞IO::

   非阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方式来判断具体操作是否成功。

 

 

存在O_NONBLOCK的关键字,即其是非阻塞的IO操作,这从ASM的原理上可以推测到,因为ASM是直接操作底层磁盘的,其没有文件缓存,那问题会不会出在O_SYNC|O_DIRECT这两个参数上,难道是写归档日志的方式不对,导致了归档出现坏块?

 

马上到metelink上输入O_SYNC O_DIRECT进行搜索,发现排在BUG的第一位就有一个相类似的BUG,其描述是在linux上使用EXT4的文件系统存放archived log ,redo log ,datafile 文件时,数据库的参数filesystemio_options=setall时,就会出现数据库坏块。

 
 

 

柳暗花明又一村,看到这个BUG,心中一阵狂喜,客户是不是命中这个BUG呢?是不是离解决问题不远了。马上登录到系统中一看归档目录,发现果然是以ext4来加载的。

 

再到数据库里查看

SQL> show parameter filesystem

 

NAME                    TYPE        VALUE

----------------------  ----------- --------

filesystemio_options    string      SETALL

 

 

果然与这个BUG相匹配,那么这个filesystemio_options是什么参数呢?ORACLE数据库里面有两个参数控制IO的行为,也就是说,我们可以通过filesystemio_options与disk_asynch_io这两个参数来优化ORACLE数据库的IO性能。

 

filesystemio_options 这个参数是允许数据库对IO进行间接或直接,同步或异步读写,这个参数默认是none,这意味着,数据库对文件系统IO操作模式是同步读写,对文件系统的cache是间接读写。Oracle推荐这个参数是使用setall,这个参数值是执行IO操作时绕过了文件系统的cache,直接读写到磁盘上。

 

而disk_asynch_io这个参数是默认为true的,即启用异步IO。

 

基于上述的原理,所以当filesystemio_options设置为setall时,我们看到O_SYNC|O_DIRECT的关键字,其绕过了EXT4上的文件系统缓存,直接对IO进行操作,导致触发了14594193这个BUG。

原因总结及建议

通过对上述的分析,可以知道是因为客户将归档文件存放到了EXT4上的文件系统,而数据库的参数filesystemio_options设置为setall时,数据库在做IO操作时,绕过了EXT4文件系统的缓存,从而触发了BUG而引起了坏块,所以这种坏块属于逻辑坏块。

 

这个问题在metalink的文档ORA-1578 ORA-353 ORA-19599 Corrupt blocks with zeros when filesystemio_options=SETALL on ext4 file system using Linux (文档 ID 1487957.1)里有详细的描述,在这里我就不帖出来了,各位自已去查阅吧。

 

这个文档提及,从10.1.0.2 to 12.1.0.1都存在这个BUG,也就是说,从10.2.0.2引入filesystemio_options这个参数,只要设为SETALL,结合EXT4,就会有可能遇到这个BUG。

 

建议:

 

万事知道原理后,解决就非常容易了,要不修改filesystemio_options这个参数为非SETALL值。

Workaround:

The workaround to avoid corruptions in the Oracle database files is to set filesystemio_options=NONE or filesystemio_options=DIRECTIO or filesystemio_options=ASYNCH in the database parameter file (spfile / init<SID>.ora).

 

要不就不要使用EXT4来存放数据库的相关文件,改为其他文件系统格式或直接存放到ASM上。

 

终于解决问题,可以回家了:-)

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

转载于:http://blog.itpub.net/12482/viewspace-1980486/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值