请大家访问 tyoracle.com 关注最新的博文发布
个人介绍
本人TY,从事ORACLE DBA十五年,从ORACLE 8I开始,一直奋战在一线,本着对技术的狂热,一直走到今天,积累了大量的经验与案例,期待静下心来,
将这些案例与经验化成文字,与大家分享,共同进步。
前言
作为从事DBA多年的TY来说,与奋战在一线的同行们一样,每天都会遇到各种各样的奇怪问题,这些问题有些莫名奇妙的自动出现,然后莫名奇妙的自动消失,
但这世上不会有无缘无故的爱,也不会有无缘无故的恨:-),TY是一个喜欢创根问根的人,非常喜欢接受数据库奇怪问题的挑战。也可以简称“自虐”。
最近两天,有个客户打电话给TY,说他的数据库刚从AIX迁移到PC 服务器上,使用的是OLE 6的操作系统,最近备份时,出现报错,系统中居然报归档文件存在
坏块。
这个就非常奇怪了,数据库出现坏块就常见,归档文件出现坏块这个极为罕见,这挑起了TY的好奇心,决定到客户现场一探究竟。
这里讲述的是一个,对于未知问题,无从下手的情况下,如何分析解决问题的过程。
背景
客户的数据库是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_TAG20160106T062152_84jyb44j_.bkp
分析
对于corrupt data,一般都是发生在数据库文件中,有两种情况,一种是物理损坏,是指数据库不能读取到该块内部的数据结构,一般是因为硬件出现问题,内存
问题、OS问题、IO子系统问题等引起。而逻辑损坏,则大多是指数据库能读取到该块的数据结构,但是因为数据结构的值不一致,从而被数据库标识为坏块,大
部分的逻辑损坏,很多都是因为ORACLE 的BUG 造成的。
但对于客户现在这种情况,是归档文件损坏。而用户的环境是新的机器,存储也是新的。硬件出现问题的概率较低,对于内存,OS,IO等问题,如果存在,肯定
数据库本身的数据文件也会报坏块,而现在只是归档文件有问题,所以基本上可以排除物理坏块的的可能。
对于归档文件出现坏块这种情况,在TY十多年的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:: 非阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方式来
判断具体操作是否成功。
存在ONONBLOCK的关键字,即其是非阻塞的IO操作,这从ASM的原理上可以推测到,因为ASM是直接操作底层磁盘的,其没有文件缓存,那问题会不会出在
OSYNC|O_DIRECT这两个参数上,难道是写归档日志的方式不对,导致了归档出现坏块?
马上到metelink上输入OSYNC ODIRECT进行搜索,发现排在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相匹配,那么这个filesystemiooptions是什么参数呢?ORACLE数据库里面有两个参数控制IO的行为,也就是说,我们可以通过
filesystemiooptions与diskasynchio这两个参数来优化ORACLE数据库的IO性能。
filesystemio_options 这个参数是允许数据库对IO进行间接或直接,同步或异步读写,这个参数默认是none,这意味着,数据库对文件系统IO操作模式是同步读写
,对文件系统的cache是间接读写。Oracle推荐这个参数是使用setall,这个参数值是执行IO操作时绕过了文件系统的cache,直接读写到磁盘上。
而diskasynchio这个参数是默认为true的,即启用异步IO。
基于上述的原理,所以当filesystemiooptions设置为setall时,我们看到OSYNC|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.ora).
要不就不要使用EXT4来存放数据库的相关文件,改为其他文件系统格式或直接存放到ASM上。
终于解决问题,可以回家了:-)
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12482/viewspace-2124842/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/12482/viewspace-2124842/