Oracle等待事件之03(Db file parallel read/write)

  1. 查看oracle 版本信息
[oracle@mpdb ~]$ sqlplus file_center/123456

#SQL> set sqlformat ansiconsole

SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0  Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

一、 启用异步IO
ORACLE数据库是从ORACLE 9i Release 2开始支持异步IO特性的。之前的版本是不支持异步IO特征的。另外在ORACLE 9i R2和 ORACLE 10g R1中默认是禁用异步特性的,直到ORACLE 10g R2才默认启用异步IO特性。
那么如何启用ORACLE数据库的异步IO特性呢? 我们可以按照下面步骤操作:

1:首先要确认ORACLE数据库所在的系统平台(操作系统)是否支持异步IO

目前流行的Linux/Unix平台基本上都支持异步IO,但是一些老旧的版本就不一定了。可以搜索一下相关文档了解清楚。

2: 检查是否安装libaio、libaio-devel相关包(似乎libaio-devel包不是必须的,测试环境没有libaio-devel似乎也OK,当然最好也一起安装)

[oracle@mpdb ~]$ rpm -qa | grep aio 
libaio-devel-0.3.107-10.el6.x86_64
libaio-0.3.107-10.el6.x86_64

3:检查系统是否支持异步I/O

#根据文档[Note 370579.1] ,可以通过查看slabinfo统计信息查看操作系统中AIO是否运行,slab是Linux的内存分配器,AIO相关的内存结构已经分配,
#kiocb值的第二列和第三列非0即是已使用
[oracle@mpdb ~]$ cat /proc/slabinfo | grep kio 
kioctx               105    170    384   10    1 : tunables   54   27    8 : slabdata     17     17      0
kiocb                  0      0    256   15    1 : tunables  120   60    8 : slabdata      0      0      0

#kiocb值的第二列和第三列非0表示系统已经启用异步IO。如上所示,表示异步I/O没有在使用。
  1. 修改、优化系统内核参数
#如 非 1048576 則 修改参数fs.aio-max-nr = 1048576
[oracle@mpdb ~]$ cat /proc/sys/fs/aio-max-nr
1048576

5:检查ORACLE软件是否支持开启AIO

#如下所示有输出值,表示ORACLE软件支持开启AIO,其实从ORACLE 9i R2开始,ORACLE就已经支持开启异步IO(AIO)了。
#不过10GR1以前版本需要手动开启AIO,相对而言要麻烦一些。
[oracle@mpdb ~]$ /usr/bin/ldd $ORACLE_HOME/bin/oracle | grep libaio
                libaio.so.1 => /lib64/libaio.so.1 (0x000000303fc00000)
[oracle@mpdb ~]$ /usr/bin/nm $ORACLE_HOME/bin/oracle | grep io_getevent
                 w io_getevents@@LIBAIO_0.4

6:数据库级别启用异步I/O

SQL> show parameter disk_asynch_io;
NAME                     TYPE    VALUE
------------------------------------ ----------- ------------------------------
disk_asynch_io               boolean     TRUE

SQL> show parameter filesystemio_options
NAME                     TYPE    VALUE
------------------------------------ ----------- ------------------------------
filesystemio_options             string  none

SQL> alter system set filesystemio_options = setall scope=spfile;

SQL> alter system set disk_asynch_io = true scope=spfile;

#关于参数filesystemio_options有四个值: asynch、directio, setall,none. 一般建议设置为setall比较合适
#ASYNCH : 在文件系统文件上启用异步I/O,在数据传送上没有计时要求
#DIRECTIO : 在文件系统文件上启用直接I/O,绕过buffer cache
#SETALL : 在文件系统文件上启用异步和直接I/O
#NONE : 在文件系统文件上禁用异步和直接I/O

7: 设置完成后重启数据库,验证异步IO特性是否启用。

#如下所示, kiocb的第二、三列都不为0,表示ORACLE的异步IO特性已经启用
[oracle@mpdb ~]$ cat /proc/slabinfo | grep kio 
kioctx                70     70    384   10    1 : tunables   54   27    8 : slabdata      7      7      0
kiocb                180    180    256   15    1 : tunables  120   60    8 : slabdata     12     12      0

8.查看数据文件是否开启异步IO

Select Name, Asynch_Io From V$datafile f, V$iostat_File i
Where f.File# = i.File_No And (Filetype_Name = 'Data File' Or Filetype_Name = 'Temp File');

二、測試等待事件

  1. Db file parallel read
这是一个很容易引起误导的等待事件,实际上这个等待事件和并行操作(比如并行查询,并行DML)没有关系。 
这个事件发生在数据库恢复的时候,当有一些数据块需要恢复的时候,Oracle会以并行的方式把他们从数据文件中读入到内存中进行恢复操作。
这个等待事件包含三个参数:
Files: 操作需要读取的文件个数。
Blocks: 操作需要读取的数据块个数。
Requests: 操作需要执行的I/O次数。

#會話1
SQL> col event format a40                  
SQL> select event,TOTAL_WAITS,AVERAGE_WAIT from v$system_event where upper(event) like 'DB FILE%';

EVENT                              TOTAL_WAITS      AVERAGE_WAIT
---------------------------------------- ----------- ------------
db file sequential read               597661          .67
db file scattered read                982954         1.12
db file parallel write                 14453         1.53
db file parallel read                  23805         1.53
  1. 創建測試表
#會話2
create table test_wait3 
as 
select rownum row_no, 
rpad('M',9,'A') ca, 
rpad('M',9,'B') cb, 
rpad('M',9,'C') cc
from dual connect by level<=100000;

#會話1
SQL> select event,TOTAL_WAITS,AVERAGE_WAIT from v$system_event where upper(event) like 'DB FILE%';

EVENT                    TOTAL_WAITS AVERAGE_WAIT
---------------------------------------- ----------- ------------
db file sequential read               736506          .64
db file scattered read               1162611         1.13
db file parallel write                 17078         1.51
db file parallel read                  31402         1.46

  1. 開始測試
#會話2
SQL> insert into test_wait3 select * from test_wait3;

#會話1
SQL> select event,TOTAL_WAITS,AVERAGE_WAIT from v$system_event where upper(event) like 'DB FILE%';

EVENT                    TOTAL_WAITS AVERAGE_WAIT
---------------------------------------- ----------- ------------
db file sequential read               743751          .64
db file scattered read               1175046         1.12
db file parallel write                 17204          1.5
db file parallel read                  31403         1.46

  1. Db file parallel write
这是一个后台等待事件,它同样和用户的并行操作没有关系,它是由后台进程DBWR产生的,当后台进程DBWR向磁盘上写入脏数据时,会发生这个等待。
DBWR会批量地将脏数据并行地写入到磁盘上相应的数据文件中,在这个批次作业完成之前,DBWR将出现这个等待事件。如果仅仅是这一个等待事件,
对用户的操作并没有太大的影响,当伴随着出现free buffer waits等待事件时,说明此时内存中可用的空间不足,这时候会影响到用户的操作,
比如影响到用户将脏数据块读入到内存中。当出现db file parallel write等待事件时,可以通过启用操作系统的异步I/O的方式来缓解这个等待。当使用异步I/O时,DBWR不再需要一直等到所有数据块全部写入到磁盘上,
它只需要等到这个数据写入到一个百分比之后,就可以继续进行后续的操作。
这个等待事件有两个参数:
Requests: 操作需要执行的I/O次数。
Timeouts: 等待的超时时间。

4.1 .关闭ASYNC I/O:

SQL> show parameter sync

NAME                     TYPE    VALUE
------------------------------------ ----------- ------------------------------
disk_asynch_io               boolean     TRUE
tape_asynch_io               boolean     TRUE

SQL> alter system set disk_asynch_io = false scope=spfile;

SQL> shutdown immediate;

SQL> startup;

SQL> show parameter sync
NAME                     TYPE    VALUE
------------------------------------ ----------- ------------------------------
disk_asynch_io               boolean     FALSE
tape_asynch_io               boolean     TRUE

4.2 關閉async i/o 後測試

SQL> col event format a40
SQL> select event,TOTAL_WAITS,AVERAGE_WAIT from v$system_event where upper(event) like 'DB FILE%';

EVENT                    TOTAL_WAITS AVERAGE_WAIT
---------------------------------------- ----------- ------------
db file sequential read     38184        1.06
db file scattered read      20540        1.66
db file single write        516           .66
db file parallel write      32            59.52
db file parallel read       60            44.51

#會話2 & 會話3 
begin
    for i in 1..100000 loop
        execute immediate 'insert into test_wait3(row_no) values ('||i||')';
                commit;
    end loop;
end;
/

#會話1
SQL> select event,TOTAL_WAITS,AVERAGE_WAIT from v$system_event where upper(event) like 'DB FILE%';
EVENT                    TOTAL_WAITS AVERAGE_WAIT
---------------------------------------- ----------- ------------
db file sequential read                59887         1.36
db file scattered read                 52301         1.69
db file single write                 516          .66
db file parallel write               490        17.45
db file parallel read               1437        15.34

SQL> r
  1* select event,TOTAL_WAITS,AVERAGE_WAIT from v$system_event where upper(event) like 'DB FILE%'
EVENT                    TOTAL_WAITS AVERAGE_WAIT
---------------------------------------- ----------- ------------
db file sequential read                83711         1.31
db file scattered read                 61955         1.78
db file single write                 516          .66
db file parallel write               626        19.36
db file parallel read               3821          9.5

4.3 開啟ASYNC I/O

SQL> alter system set disk_asynch_io = true scope=spfile;

SQL> shutdown immediate;

SQL> startup;

SQL>  show parameter sync

NAME                     TYPE    VALUE
------------------------------------ ----------- ------------------------------
disk_asynch_io               boolean     TRUE
tape_asynch_io               boolean     TRUE

4.4 開啟ASYNC I/O 後測試

#會話1
SQL> select event,TOTAL_WAITS,AVERAGE_WAIT from v$system_event where upper(event) like 'DB FILE%';

EVENT                    TOTAL_WAITS AVERAGE_WAIT
---------------------------------------- ----------- ------------
db file sequential read                19827         1.21
db file scattered read                 14751         1.81
db file parallel write               221          .91
db file parallel read                 50         7.94


#會話2 & 會話3 
begin
    for i in 1..100000 loop
        execute immediate 'insert into test_wait3(row_no) values ('||i||')';
                commit;
    end loop;
end;
/

#會話1
SQL> select event,TOTAL_WAITS,AVERAGE_WAIT from v$system_event where upper(event) like 'DB FILE%';
EVENT                    TOTAL_WAITS AVERAGE_WAIT
---------------------------------------- ----------- ------------
db file sequential read                21508          1.2
db file scattered read                 23483         1.42
db file parallel write               293          .91
db file parallel read                 52         7.96

SQL> r
  1* select event,TOTAL_WAITS,AVERAGE_WAIT from v$system_event where upper(event) like 'DB FILE%'
EVENT                    TOTAL_WAITS AVERAGE_WAIT
---------------------------------------- ----------- ------------
db file sequential read                23763         1.22
db file scattered read                 31145         1.61
db file parallel write               660         1.29
db file parallel read                 89         6.14

  1. 總結
db file parallel write 的 AVERAGE_WAIT 對比
關閉async i/o   AVERAGE_WAIT 的值為 : 19.36
開啟async i/o   AVERAGE_WAIT 的值為 : 1.29  (改善很明顯)

V$SYSTEM_EVENT中的常用列:
EVENT:等待事件名称
TOTAL_WAITS:此项事件总等待次数
TIME_WAITED:此项事件的总等待时间(单位:百分之一秒)
AVERAGE_WAIT:此项事件的平均等待用时(单位:百分之一秒)(time_waited/total_waits)
TOTAL_TIMEOUTS:此项事情总等待超时次数
TIME_WAITED_MICRO:等待事件总时间(以微秒为单位)
TOTAL_WAITS_FG:前台会话的等待事件的总数
TOTAL_TIMEOUTS_FG:前台会话的超时等待的总数
TIME_WAITED_FG:前台会话等待的总时间(百分之一秒)
AVERAGE_WAIT_FG:前台会话等待的平均时间(百分之一秒)
TIME_WAITED_MICRO_FG:等待事件总时间(以微秒为单位)

你可能感兴趣的:(Oracle等待事件之03(Db file parallel read/write))