ITPub博客

首页 > 数据库 > Oracle > Direct IO

Direct IO

原创 Oracle 作者:dbs101 时间:2011-04-20 14:51:08 0 删除 编辑
什么是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写文件。

点击(此处)折叠或打开

  1. #define _GNU_SOURCE
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #include
  11. #define BLOCKSIZE 512
  12. int main()
  13. {
  14.  void *buffer;
  15.  int fd;
  16.  int i;
  17.  unsigned char *file="testfile";
  18.  char image[512];
  19.  //write
  20.  for(i=0;{
  21.   image[i]=66;
  22.  }//for
  23.  posix_**lign(&buffer, BLOCKSIZE, BLOCKSIZE);
  24.  memcpy(buffer, image, sizeof(image));
  25.  //int f = open(file, O_CREAT|O_TRUNC|O_WRONLY|O_DIRECT,0060);
  26.  fd = open(file,O_CREAT|O_RDWR|O_DIRECT,0060);
  27.  if (fd == -1)
  28.  {
  29.   printf("open %s failed ", file);
  30.   return (-1);
  31.  }
  32.  printf("%d",sizeof(image));
  33.  
  34.  write(fd, buffer, BLOCKSIZE);
  35.  close(fd);
  36.  free(buffer);
  37.  return 0;
  38. }


strace的输出结果中包含了O_DIRECT选项。
strace -o dio.out ./dio

点击(此处)折叠或打开

  1. open("testfile", O_RDWR|O_CREAT|O_DIRECT, 060) = 3


在oracle中启用Direct IO。

点击(此处)折叠或打开

  1. SQL> show parameter filesystem
  2. NAME                                 TYPE        VALUE
  3. ------------------------------------ ----------- ------------------------------
  4. filesystemio_options                 string      NONE
  5. alter system set filesystemio_options = 'DIRECTIO' scope=spfile;


在OPEN DATABASE是运行strace.
strace -o dbw.txt -p 10231
strace的输出结果:选项为O_DIRECT。

点击(此处)折叠或打开

  1. open("/u01/app/oracle11g/oradata/db11g42/system01.dbf", O_RDONLY|O_DIRECT|O_LARGEFILE) = 18

点击(此处)折叠或打开

  1. alter system set filesystemio_options = 'NONE' scope=spfile;

在OPEN DATABASE是运行strace.
strace -o dbw.txt -p 10419
strace的输出结果:选项为O_SYNC。

点击(此处)折叠或打开

  1. 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打开的时候:

点击(此处)折叠或打开

  1. [oracle@dbs4 19126]$ free -mt
  2.              total       used       free     shared    buffers     cached
  3. Mem:          1010        521        489          0          6        354
  4. -/+ buffers/cache:        160        850
  5. Swap:         2047         66       1980
  6. Total:        3058        587       2470
  7. 256 seconds


Direct IO关闭的时候:

点击(此处)折叠或打开

  1. [oracle@dbs4 19126]$ free -mt
  2.              total       used       free     shared    buffers     cached
  3. Mem:          1010        797        212          0          1        631
  4. -/+ buffers/cache:        164        846
  5. Swap:         2047        148       1898
  6. Total:        3058        946       2111

从测试看free内存增加,cache减少。不知道为什么Oracle不将Direct IO设置成默认值。可能
是有些设备不支持。

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

上一篇: direct path read temp
请登录后发表评论 登录
全部评论

注册时间:2010-12-18

  • 博文量
    92
  • 访问量
    437882