暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle在Solaris的VXFS上的异步I/O问题

原创 eygle 2011-11-22
567





一、     VXFS文件系统的简介


  VXFS文件系统是Veritas公司推出的一种高性能,高可用性的文件系统,一般用于数据中心。它是一种基于扩展的文件系统,能够让应用程序读取和写入大的连续块,适用于OLTP系统和DSS系统。


Oracle数据库在Solaris操作系统上的vxfs文件系统上是可以实现异步I/O的,那Oracle数据库在vxfs文件系统中究竟该不该使用异步I/O?如何去判断是否Oracle数据库是真正实现了异步I/O?下面就这几个问题来具体的看看Oracle数据库在vxfs文件系统上的异步I/O


 


二、     VXFS文件系统上如何启用异步I/O


    
首先我们必须要知道Solaris操作系统上那些磁盘上的文件系统是vxfs格式的,如何来查看一下哪些磁盘是属于vxfs格式的呢,可以使用如下的命令来查看:


Df -F vxfs


/opt/oracle/db02   (/dev/vx/dsk/ipasdg/db02_vol):55665072
blocks   869766 files


/opt/oracle/db03   (/dev/vx/dsk/ipasdg/db03_vol):41688928
blocks   651380 files


/opt/oracle/db04   (/dev/vx/dsk/ipasdg/db04_vol):41688928
blocks   651380 files


/opt/oracle/arch   (/dev/vx/dsk/ipasdg/arch_vol):164632064
blocks  2572348 files


/backup            (/dev/vx/dsk/ipasdg/backup_vol):314529872
blocks  4914519 files


      如果想在vxfs上面使用异步I/O,首先必须要安装一个叫做Quick I/O的模块,并且要启用Quick I/O,这个模块是需要单独向Veritas公司购买license的。默认的时候vxfs文件系统mount的时候是启用了Quick I/O的,如果在mount的时候指定了-o noqio的选项,那么Quick IO是被禁用的。


如果想查看在一个文件系统上是否采用了Quick
IO,常用的fsadminfstype这些命令都无法看出来,/etc/mnttab/etc/vfstab这些文件也没有记录相关的信息。这里   介绍一种方法可以查看文件是否是Quick I/O的文件:


ls -al   列出所有文件,包括Quick I/O文件和它的链接。


$ ls -al d* .d*


-rw-r--r-- 1 <oracle> dba 104890368 Oct
2 13:42 .dbfile


lrwxrwxrwx 1 <oracle> dba 17 Oct 2
13:42 dbfile -> \\ .dbfile::cdev:vxfs:


ls -lL   显示是否Quick I/O被成功安装和启用。


$ ls -lL dbfile


crw-r--r-- 1 <oracle> dba 45, 1 Oct 2
13:42 dbfile


第一个字符c,表明这是一个裸字符设备文件,如果没有这个字符则表明Quick I/O没有正确安装或者是没有一个合法的license
key


       确认文件系统启用了Quick I/O后,然后就可以给Oracle配置异步I/O了,在Oracle的初始化参数中配置DISK_ASYNCH_IO
= TRUE,然后重启数据库让其生效。


      因为启用了Quick I/O后,在OS级别上是消除了缓冲的,所以数据库的buffer cache在启用了Quick I/O后是应该需要增加的。


 


三、     如何检测在VXFS文件系统上是否支持异步I/O


  对于Solaris操作系统可以使用下面的一段代码来检测系统是否支持异步I/O


原代码如下:


/*


* Quick kaio test. Read 1k bytes from a file
using async I/O.


* To compile:


* cc -o aio aio.c -laio


* To run:


* aio file_name


*/


#include <stdio.h>


#include <sys/types.h>


#include <sys/fcntl.h>


#include <sys/aio.h>


#define BSIZE 1024


main(int argc, char *argv[])


{


aio_result_t res;


char buf[BSIZE];


int fd;


if ((fd=open(argv[1], O_RDONLY)) == -1) {


perror("open");


exit(-1);


}


aioread(fd, buf, BSIZE, 0L, SEEK_SET,
&res);


aiowait(0);


if (res.aio_return == BSIZE) {


printf("aio succeeded\
");


close(fd);


exit(0);


}


perror("aio");


}


然后使用root用户编译:


# cc -o aio aio.c -laio


这样就可以用来检测系统是否支持异步I/O了。


对于vxfs上的裸设备,不需要启用quick I/O就是可以直接支持异步I/O的:


# truss -t kaio,lwp_create ./aio
/dev/rdsk/c0t0d0s1


kaio(5, 0xFFBEF640, 0x00000000, 0xFF21FB68,
0x00000000, 0xFFBEF648, 0x00000000) = 0


lwp_create(0xFFBEF640, 0, 0xFF21FF5C)           = 2


lwp_create()    (returning as new lwp ...)      = 0


kaio(AIOREAD, 3, 0xFFBEF9C0, 1024, 0,
0xFFBEFDC0) = 0


kaio(AIOWAIT, 0x00000000)                       = 4290706880


aio succeeded


从上面的测试中可以看出,'aio succeeded'表明裸设备上的异步I/O操作是成功了的,并且异步I/O的读写是通过AIOREADAIOWRITE来实现的。


 


四、     如何查看VXFS文件系统上异步I/O的性能


如何去查看采用了异步I/Ovxfs文件系统的性能呢,我们可以用sar命令来简单的进行观察,主要查看%usr%sys%wio%idle这几列的值。我们一般都可以明显的看到CPU消耗在等待I/O上的时间比不采用异步I/O之前有明显的减少。


先来看没有使用异步I/O情况:


    %usr   
%sys    %wio   %idle


20:05:13      
2      23      
1      74


20:05:23      
2      24       1     
73


20:05:33      
2      24       1     
73 


Response time = 4 min 22 secs .


Oracle stats .


Statistic                                    Total   per Second   
per Trans --------------------------------- ----------------
------------ ------------


CPU used by this session                    25,188         99.6         25.2


CPU used when call started                  25,188         99.6         25.2


 


使用了异步I/O情况:


            
%usr    %sys    %wio  
%idle


19:53:37     
17       9       0     
74


19:53:42     
16       8       2     
74


19:53:47     
16       7       2     
75


19:53:57     
17       7       0     
75 


Response time = 37 secs .


Oracle stats . Statistic                                    Total   per Second   
per Trans --------------------------------- ---------------- ------------
------------


CPU used by this session                     2,119         96.3          2.1


CPU used when call started                   2,119         96.3          2.1


  从上面的比较数据我们不难看出,使用了异步I/O后的响应时间大大的缩短,从原来的四分多钟减少到37秒,cpu的使用率也大大的降低,Oracle通过调用Solaris上的异步I/OAIOREADAIOWRITE来实现异步I/O读写。但是,如果在没有启用Quick I/Ovxfs文件系统上设置了Oracle的异步I/OOracle的性能不会提高而且会变得极其低下,造成CPU的时间绝大多数消耗在I/O等待上的情况。当然,如果系统本来就不是很繁忙,I/O不是很多,CPU又足够的多,也可能体现不出来这种问题。这个问题是Oracle上的一个bug。因此,如果没有使用Quick I/O的话,在vxfs文件系统上还是不建议使用异步I/O的。


  大致做了一个测试如下:


  没有启用Quick I/Ovsfs的文件系统下,设置了数据库的初始化参数DISK_ASYNCH_IO
= TRUE,然后让数据库正常的写入数据,在os上跟踪Oracle后台的dbwr进程,查看其trace,就可以发现如果没有启用Quick
I/O,实际上数据库设置了异步I/O,还是没法在os级别上实现异步I/O的。


ps -ef |grep ora_


oracle 16813     1 
0   Nov 03 ?        0:02 ora_pmon_ORCL


oracle 16819     1 
0   Nov 03 ?        0:53 ora_ckpt_ORCL


oracle 16831     1 
0   Nov 03 ?        0:00 ora_d000_ORCL


oracle 16823     1 
0   Nov 03 ?        2:31 ora_smon_ORCL


oracle 16815     1 
0   Nov 03 ?       52:41 ora_dbw0_ORCL


oracle 16825     1 
0   Nov 03 ?        0:01 ora_reco_ORCL


oracle 16827     1 
0   Nov 03 ?        0:02 ora_cjq0_ORCL


oracle 16829     1 
0   Nov 03 ?        0:00 ora_s000_ORCL


oracle 16817     1 
0   Nov 03 ?       96:24 ora_lgwr_ORCL


oracle 16835     1 
0   Nov 03 ?        4:11 ora_arc1_ORCL


oracle 16833     1 
0   Nov 03 ?        4:14 ora_arc0_ORCL


 


truss -fl -p 16815


16815/1:       
lwp_cond_signal(0xFFFFFFFF7CB8FF70)             = 0


16815/26:   
lwp_cond_wait(0xFFFFFFFF7CB8FF70, 0xFFFFFFFF7CB8FF80, 0x00000000) = 0


16815/1:        kaio(AIOWAIT,0xFFFFFFFF7CB7DF70)   Err#22 EINVAL


16815/26:   
pread64(408, "1B02\\0\\0\\080\\0 2\\0\\0D09D".., 8192, 102400) =
8192


16815/1:    
kaio(AIOWAIT,0xFFFFFFFF7CB7DF70)  
Err#22 EINVAL             = 0


16815/26:       kaio(AIONOTIFY, 27977120) = 0


16815/1 :   
 kaio(AIOREAD, 408, 0x01B98DE0,
2048, 110592, 0x01A8486C) Err#48 ENOTSUP


  注意到调用kaio(AIOREAD,...)的时候返回了一个OS的错误,errno = 48# ENOTUP, 表明没有启用quick I/Ovxfs文件系统是不支持异步I/O的。这个并不是一个应用级别的错误,而是solaris异步I/O库调用的,产生这个错误表明文件系统并不支持核心的异步I/O,并且使用了一个同步进程调用pread取代了,而只是在应用级别上模拟异步I/O而已。


 


五、     如何转换VXFS文件系统上数据文件为支持异步I/O的数据文件


正常来说对于要Oracle数据库使用具有quick I/O的数据文件,应该先预先分配具有quick
I/O特性的数据文件,然后将数据文件加入到相应的Oracle数据库表空间中去,可以使用qiomkfile命令预先分配具有quick I/O特性的数据文件:


/usr/sbin/qiomkfile
-s 500M /oradata/test.dbf


Qiomkfile这个命令在Veritasquick I/O包中提供,上述命令将会在vxfs的文件系统的/oradata目录下建立两个文件,一个是.test.dbf,一个是链接文件test.dbf指向.test.dbfOracle数据库中就可以使用这个链接文件test.dbf做为表空间的数据文件。


那如何将已有的vxfs文件系统上的Oracle数据库转换成启用了Quick I/O上的Oracle数据库呢?Veritas Database Edition
for Oracle提供了两个脚本文件用来转换,一个是getdbfiles.sh,一个是mkqio.sh,两个脚本都存放在/opt/VRTSordba/bin目录下。前提是在转换之前数据库的数据文件必须是分布在vxfs的文件系统上的。


  Getdbfiles.sh这个脚本是用来从Oracle数据库的系统表中得到所有的数据文件的名字和位置等相关信息,必须要用oracle用户来运行的,得到的信息存储在一个叫mkqio.dat文件中。


   Mkqio.sh这个脚本是用来处理mkqio.dat文件中包含的所有数据文件,并将它们转换成Quick
I/O上的数据文件,这个脚本也最好用oracle用户来执行,避免一些权限的问题出现,在运行完getdbfiles.sh脚本后,必须要先完全关闭数据库后才能执行mkqio.sh脚本。如果转换的时候出现什么问题,可以使用mkqio.sh
-uQuick I/O上的文件转换回普通vxfs上的文件,需要注意的是这个脚本只能用于转换vxfs上的数据库文件,如果数据文件本身并不是建立在vxfs文件系统上,那么运行了getdbfiles.sh后,必须手工编辑mkqio.dat文件去掉那些不是在vxfs文件系统上的数据文件。


  还有一种简单的方法也同样可以实现vxfs上的数据文件转换为quick
I/O的数据文件,通过前面我们知道建立具有quick I/O的数据文件的时候会生成一个实际的文件和一个链接文件,于是就可以通过一下步骤来实现非quick
I/O的数据文件转换为quick I/O的数据文件。首先正常的关闭Oracle数据库,然后对那些非quick I/O的数据文件分别执行以下两个命令:


mv
< datafile> .< datafile>


ln
-s .< datafile>::cdev:vxfs: < datafile>


这样就将那些非quick I/O的数据文件转换为了具有quick I/O的数据文件。


 


以上是对Solaris上的vxfs文件系统上的Oracle数据库使用异步I/O的初探,当然我们还可以通过操作系统上的对I/O分析的一些其他方法进行更加详细深入的研究,因为不在此篇文章论述范围之内,这里就不详细阐述分析了,如果有兴趣的朋友可以去深入研究一下,对操作系统上异步I/O的库文件定义入手,深入的发掘出操作系统Solaris上异步I/O的内部机制。




本文作者:叶梁(Coolyl)
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论