Direct IO

来源:互联网 发布:c 定义数组 编辑:程序博客网 时间:2024/05/16 03:16

http://space.itpub.net/25105315/viewspace-692962

 

Direct IO
Direct I/O就是当一个进程对系统文件进行IO操作的时候越过系统的文件写缓冲区和读缓存区。
文件系统缓冲区:当系统读写块设备,为了加快读写速度,系统维护了一个块缓冲区。当系统读
数据的时候,先去缓冲区中读,如果没有,再读写磁盘。当系统写数据的时候,先写数据到缓冲
区中。
Oracle数据库本身已经有自己的数据缓冲区,如果再加上系统文件的缓冲区。数据就被缓冲了俩
次,系统的内存就被浪费了。而且如果Oracle的数据库的块比系统文件的块小,那么就会造成系
统的浪费。比如Oracle的块大小是8K,系统文件的块大小是16K,那么Oracle单个读写一次就浪费
了8K的资源。
启用Direct IO
Linux内核2.4开始有Direct I/O功能, 也就是raw device裸设备。raw device可以在低级别被直
接地和并发地访问。最终块设备ext3也支持Direct IO。OCFS和ASM/ASMLib本身也支持Direct IO。
当然前提条件是存储设备需要支持VERYIO。
Direct IO可以用mount在整个文件系统范围内启用,也可以在应用中使用O_DIRECT打开文件。
Direct IO操作的块大小是512字节。
下面的c程序使用O_DIRECT写文件。
#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/fs.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#define BLOCKSIZE 512
int main()
{
 void *buffer;
 int fd;
 int i;
 unsigned char *file="testfile";
 char image[512];
 //write
 for(i=0;i<sizeof(image);i++)
 {
  image[i]=66;
 }//for
 posix_**lign(&buffer, BLOCKSIZE, BLOCKSIZE);
 memcpy(buffer, image, sizeof(image));
 //int f = open(file, O_CREAT|O_TRUNC|O_WRONLY|O_DIRECT,0060);
 fd = open(file,O_CREAT|O_RDWR|O_DIRECT,0060);
 if (fd == -1)
 {
  printf("open %s failed ", file);
  return (-1);
 }
 printf("%d",sizeof(image));
 
 write(fd, buffer, BLOCKSIZE);
 close(fd);
 free(buffer);
 return 0;
}
strace的输出结果中包含了O_DIRECT选项。
strace -o dio.out ./dio
 
open("testfile", O_RDWR|O_CREAT|O_DIRECT, 060) = 3
在oracle中启用Direct IO。
SQL> show parameter filesystem
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
filesystemio_options                 string      NONE
alter system set filesystemio_options = 'DIRECTIO' scope=spfile;
在OPEN DATABASE是运行strace.
strace -o dbw.txt -p 10231
strace的输出结果:选项为O_DIRECT。
open("/u01/app/oracle11g/oradata/db11g42/system01.dbf", O_RDONLY|O_DIRECT|O_LARGEFILE) = 18
alter system set filesystemio_options = 'NONE' scope=spfile;
在OPEN DATABASE是运行strace.
strace -o dbw.txt -p 10419
strace的输出结果:选项为O_SYNC。
open("/u01/app/oracle11g/oradata/db11g42/system01.dbf", O_RDWR|O_SYNC|O_LARGEFILE) = 18
O_SYNC和O_DIRECT二者都是确保写盘。不同在于O_SYNC还要经过内核的buffer,而O_DIRECT是
direct to disk的,使用应用程序自己的buffer。
测试:
环境:Oracle 11.2.0.2 Redhat Linux AS 5
相关的初始化参数:
*.db_writer_processes=4
*.filesystemio_options='DIRECTIO'
*.pga_aggregate_target=419430400
*.sga_max_size=419430400
*.sga_target=419430400
ROWS:9,999,999 rows
AVG_ROW_LEN: 95 bytes
QUERY: CREATE INDEX with parallel 4
Direct IO打开的时候:
[oracle@dbs4 19126]$ free -mt
             total       used       free     shared    buffers     cached
Mem:          1010        521        489          0          6        354
-/+ buffers/cache:        160        850
Swap:         2047         66       1980
Total:        3058        587       2470
256 seconds
Direct IO关闭的时候:
[oracle@dbs4 19126]$ free -mt
             total       used       free     shared    buffers     cached
Mem:          1010        797        212          0          1        631
-/+ buffers/cache:        164        846
Swap:         2047        148       1898
Total:        3058        946       2111
Elapsed: 00:04:20.75
260 seconds
从测试看free内存增加,cache减少。不知道为什么Oracle不将Direct IO设置成默认值。可能
是有些设备不支持。

原创粉丝点击