记录日常工作关于系统运维,虚拟化云计算,数据库,网络安全等各方面问题。

最近在做数据迁移,发现用数据库泵要比用DML语言(insert)快很多,大概一个8G左右的表数据库几分钟就可以导入成功,而用DML语言需要2-3个小时才能完成。

最初以为机器性能不行,想起来最进接触的Linux HugePages相关知识。

通过后来学习发现在数据库内存为AMM管理模式下,不支持Linux HugePages。 

关于相关说明:HugePages and Oracle Database 11g Automatic Memory Management (AMM) on Linux (文档 ID 749851.1)

Linux HugePages说明:http://blog.csdn.net/zhouyh139/article/details/8662768#comments

查看v$log表,发现绝大多数日志为active状态。遂将DML语言改为并行nologging形式:

insert /*+position(t1,4)*/  into  t1  select /*+position(t2,4)*/  * from t2  nolongging;

发现还是不行,依旧很慢。无奈给数据库做了一个statspack。发现问题:

 Top 5 Timed Events                                                   Avg %Total               

~~~~~~~~~~~~~~~~~~                                                wait  Call                

Event                                             Waits   Time (s)  (ms)   Time              

----------------------------------------- ------------ ----------- ------  ------                 

db file async I/O submit             208        1,740  8367  42.6                   

free buffer waits                          804        1,552  1930  38.0                  

rdbms ipc reply                           150         282    1880   6.9                    

log file parallel write                   1,776     219     124     5.4                    

db file scattered read                 3,299     107      33      2.6                   

 -------------------------------------------------------------                                             

发现db file async I/O submit等待事件,且每个等待高达8367秒。同时还伴有free buffer waits等待事件,先查询后者如下:
这个等待事件出现是因为dbwr没有及时将dirty buffer写到磁盘,造成server process得到不到free buffer。造成dbwr写脏块慢的原因主要由以下几种情况:

  • 1、i/o慢

检查v$filestat,是否大量磁盘写操作发生;通过iostat等操作系统命令查看磁盘写情况。

可以通过换更快速磁盘及I/O分担的方法解决i/o慢的问题。

  • 2、buffer cache设置过小造成dbwr刷新缓慢 

通过V$DB_CACHE_ADVICE获得较合理的buffer cache大小并进行调整。

  • 3、 buffer cache设置过大造成dbwr不能及时刷新

增加dbwr进程。如果多个cpu,建议通过修改db_writer_processes增加dbwr进程;如果是单个cpu,建议通过修改dbwr_io_slaves增加dbwr slave进程。来提高dbwr刷新速度。

 

通过分析锁定问题是第一种I/O慢, 通过查看IO状态确定如此:

[root@localhost oracle]# iostat -k -x 1 10

avg-cpu:  %user   %nice %system %iowait  %steal   %idle

           5.88    0.00    0.75    7.88    0.00   85.50

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util

sda              48.00  5315.00 155.00 104.00 18520.00 20668.00   302.61     3.13   12.03   3.67  95.00

sda1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sda2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sda3              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sda4              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sda5             48.00  5315.00 155.00 104.00 18520.00 20668.00   302.61     3.13   12.03   3.66  94.90

sdb               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sdb1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sdc               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sdc1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

 

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util

sda               0.00   163.00  0.00 163.00     0.00  1304.00    16.00     1.00    6.13   6.12  99.70

sda1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sda2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sda3              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sda4              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sda5              0.00   163.00  0.00 163.00     0.00  1304.00    16.00     1.00    6.13   6.12  99.70

sdb               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sdb1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sdc               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

sdc1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

 

 

发现/dev/sda5即/U01这块盘的IO一直是接近100%,但是我做了一个系统测试发现写的能力又不是那么弱.

 

[oracle@localhost ~]$ time dd if=/dev/zero of=/u01/testio.dmp bs=8k count=300000
300000+0 records in                                                                                                               
300000+0 records out                                                                                                              
2457600000 bytes (2.5 GB) copied, 7.13211 seconds, 345 MB/s                    

real 0m7.193s                                                                                           
user 0m0.124s                                                                                          
sys 0m4.328s    

 

于是放狗去找,在metalink上找到一篇关于该问题的描述:

'db file async I/O submit' when FILESYSTEMIO_OPTIONS=NONE (文档 ID 1274737.1)。但该文章说在11.2.0.3中已经解决这个问题了。

但在11.2.0.3中已经将该BUG解决,我的版本为11.2.0.3.7的,不存在该问题。通过学习查找汇总:

在11G中,默认异步IO是打开的:

SQL> show parameterdisk_asynch_io                      

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

 

 但是实际filesystemio_options并没有设置
 SQL> show parameter filesystem

    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    filesystemio_options                 string      none


filesystemio_options有4中状态:

·        ASYNCH - Enabled asynchronous I/O where possible.

·        DIRECTIO- Enabled direct I/O where possible.

·        SETALL- Enabled both direct I/O and asynchronous I/O where possible.

·        NONE - Disabled both direct I/O and asynchronous I/O.

也就是说目前数据库默认filesystemio_options不是支持同步或异步I/O的,所以我想用异步IO就需要将数据库开启支持的状态。

 

  • 开启数据库异步IO测试数据库性能

在Oracle11gR2中AIO默认已经是开启的了。可以通过ldd或者nm来检查oracle是否已经启用了AIO支持,有输出代表已经启用。 

[oracle@localhost ~]$  /usr/bin/ldd $ORACLE_HOME/bin/oracle | grep libaio

 libaio.so.1 => /usr/lib64/libaio.so.1 (0x00002b497fa42000)

[oracle@localhost ~]$ /usr/bin/nm $ORACLE_HOME/bin/oracle | grep io_getevent

                 w io_getevents@@LIBAIO_0.4

 

proc文件系统包含了两个虚拟文件,它们可以用来对异步 I/O的性能进行优化:

/proc/sys/fs/aio-nr文件提供了系统范围异步 I/O请求现在的数目。

/proc/sys/fs/aio-max-nr文件是所允许的并发请求的最大个数。最大个数通常是 64KB,这对于大部分应用程序来说都已经足够了。

检查异步I/O是否在使用

  根据[Note 370579.1],可以通过查看slabinfo统计信息查看操作系统中AIO是否运行,slab是Linux的内存分配器,AIO相关的内存结构已经分配,kiocb值的第二列和第三列非0即是已使用。与kernel 2.4.x不同,没有显示kiobuf,因为从kernel 2.5.43开始,kiobuf已经从内核中被移除。

kioctx:

AIO上下文在内核空间对应数据结构kioctx,它保存异步IO的所有信息:

[root@localhost datadp]# grep kio /proc/slabinfo

kioctx                35     84    320   12    1 : tunables   54   27    8 : slabdata      7      7      0

kiocb                  0      0    256   15    1 : tunables  120   60    8 : slabdata      0      0      0

--以上为我数据库没有设置filesystemio_options参数以前的一个状态,当我设置该参数后查看如下,再次测试将一个8G左右的表insert的时候:

 

[javascript] view plaincopy
  1. SQL> alter system set filesystemio_options=setall scope=spfile;    
  2. System altered.    
  3. SQL> shutdown immediate     
  4. Database closed.    
  5. Database dismounted.    
  6. ORACLE instance shut down.    
  7. SQL> startup    
  8. SQL> sho parameter filesystemio_options    
  9. NAME TYPE VALUE    
  10. ------------------------------------ ----------- ----------------------------  
  11. filesystemio_options string SETALL   

 

[root@localhost datadp]# grep kio /proc/slabinfo

kioctx                26     60    320   12    1 : tunables   54   27    8 : slabdata      5      5      0

kiocb                165    165    256   15    1 : tunables  120   60    8 : slabdata     11     11      2

[root@localhost datadp]# grep kio /proc/slabinfo

kioctx                35     60    320   12    1 : tunables   54   27    8 : slabdata      5      5      0

kiocb                338    420    256   15    1 : tunables  120   60    8 : slabdata     28     28    188

如上可以发现系统有异步I/O在使用了

检查系统IO情况,发现虽然也是100%,但写入新能从原来的2M提高到130M/S左右,此时I/O的性能大大的提高了。通过时间对比同样是8000W的记录修改后执行时间提高了7倍多。

 

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.50    0.00    1.00   22.35    0.00   76.15

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00 20038.00  2.00 353.00     8.00 103716.00   584.36   132.62  390.83   2.82 100.10
sda1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda3              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda4              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda5              0.00 20038.00  2.00 353.00     8.00 103716.00   584.36   132.62  390.83   2.82 100.10
sdb               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdc              39.00     0.00 162.00  0.00 10380.00     0.00   128.15     1.13    7.04   2.01  32.50
sdc1             39.00     0.00 162.00  0.00 10380.00     0.00   128.15     1.13    7.04   2.01  32.50

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.13    0.00    7.51   40.55    0.00   51.81

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00 38869.00  2.00 522.00     8.00 156856.00   598.72   143.07  277.58   1.91 100.10
sda1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda3              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda4              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda5              0.00 38869.00  2.00 522.00     8.00 156856.00   598.72   143.07  277.58   1.91 100.10
sdb               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdc               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdc1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

 

查看statspack的报告:

 

Top 5 Timed Events                                                    Avg %Total

~~~~~~~~~~~~~~~~~~                                                   wait   Call

Event                                            Waits    Time (s)   (ms)   Time

----------------------------------------- ------------ ----------- ------ ------

log file switch (checkpoint incomplete)             15         802  53444   29.2

db file async I/O submit                        27,298         560     21   20.4

log file parallel write                          5,354         317     59   11.6

db file scattered read                           5,567         267     48    9.7

db file parallel write                          31,696         214      7    7.8

          -------------------------------------------------------------

同样发现虽然有db file async I/O submit  的等待事件,但可以发现平均每个等待只为21ms,大大降低了,说明很有效。

 

  • 同样在做实验修改数据库参数配置:

也就是说系统默认情况下,是走系统的caches来和数据库文件进行数据传输。但由于系统BUG,当请求异步IO的时候出现了严重的等待,我们关闭异步IO查看DML性能情况。

[javascript] view plaincopy
  1. SQL> alter system set disk_asynch_io=false scope=spfile;     
  2. System altered.    
  3. SQL> alter system set filesystemio_options=none scope=spfile;    
  4. System altered.    
  5. SQL> startup force    

清空缓存:

ALTER SYSTEM FLUSH SHARED_POOL;
ALTER SYSTEM FLUSH BUFFER_CACHE;
ALTER SYSTEM FLUSH GLOBAL CONTEXT;

SQL > insert  /*+position(t1,4)*/  into  t1  select /*+position(t2,4)*/ * from t2  nolongging;

查看I/O状况,发现此时系统I/0被占满

avg-cpu: %user   %nice %system %iowait  %steal   %idle

          0.00    0.00    0.12  12.38    0.00   87.50

Device:        rrqm/s   wrqm/s   r/s  w/s    rkB/s    wkB/s avgrq-sz avgqu-sz  await  svctm  %util

sda              0.00   422.00  2.00 186.00    8.00  2372.00    25.32    1.13    5.96   5.30 99.60

sda1             0.00     0.00  0.00 0.00     0.00     0.00    0.00     0.00    0.00  0.00   0.00

sda2             0.00     0.00  0.00 0.00     0.00     0.00    0.00     0.00    0.00  0.00   0.00

sda3             0.00     0.00  0.00 0.00     0.00     0.00    0.00     0.00    0.00  0.00   0.00

sda4             0.00     0.00  0.00 0.00     0.00     0.00    0.00     0.00    0.00  0.00   0.00

sda5             0.00   422.00  2.00 186.00    8.00  2372.00    25.32    1.13    5.96   5.30 99.60

sdb              0.00     0.00  0.00 0.00     0.00     0.00    0.00     0.00    0.00  0.00   0.00

sdb1             0.00     0.00  0.00 0.00     0.00     0.00    0.00     0.00    0.00  0.00   0.00

sdc              0.00     0.00  0.00 0.00     0.00     0.00    0.00     0.00    0.00  0.00   0.00

sdc1             0.00     0.00  0.00 0.00     0.00     0.00    0.00     0.00    0.00  0.00   0.00

 

可以发现sda5使用率100%,且只有2M多一些的写入量。statspack报告中出现大量的db file parallel write等待事件,说明虽然没有了异步IO的等待事件,但I/O的性能却急剧下降。


补充: 

1、使用操作系统的caches
    
操作系统和设备控制器提供了数据库缓存,这些不直接与数据库的缓存管理相冲突。尽管如此,这些架构可能消耗资源当有很少的或没有性能利益。当数据库文件存储在Linux或者UNIX文件系统上时,这种情况就显而易见了。默认情况下,所有的数据库I/O都要通过文件系统的缓存。
    在一些Linux和UNIX系统上,直接I/O是可用的对于文件存储来说。这个协议允许数据库文件存取在文件系统范围内,绕过文件系统缓存。直接的I/O节约了CPU资源斌并且允许文件系统缓存是独立的在没有数据库活动的时候,例如program texts 和spool files.
     尽管操作系统的的cache经常是冗余的因为数据库的cache buffers blocks。在一些情况下,数据库不能用database buffer cache。在这些情况下,使用直接I/O或者裸设备可能产生更严重的性能问题比使用系统的buffer。例如

·         Reads or writes to the TEMP tablespace

·         Data stored in NOCACHE LOBs

·         Parallel Query slaves reading data

 

2、同步IO和异步IO的区别:

在同步文件IO中,线程启动一个IO操作然后就立即进入等待状态,直到IO操作完成后才醒来继续执行。
而异步文件IO方式中,线程发送一个IO请求到内核,然后继续处理其他的事情,内核完成IO请求后,将会通知线程IO操作完成了。

   如果IO请求需要大量时间执行的话,异步文件IO方式可以显著提高效率,因为在线程等待的这段时间内,CPU将会调度其他线程进行执行,如果没有其他线程需要执行的话,这段时间将会浪费掉(可能会调度操作系统的零页线程)。如果IO请求操作很快,用异步IO方式可能更低效,此时同步IO方式会较优。
   同步IO在同一时刻只允许一个IO操作,也就是说对于同一个文件句柄的IO操作是序列化的,即使使用两个线程也不能同时对同一个文件句柄同时发出读写操作。重叠IO允许一个或多个线程同时发出IO请求。
   异步IO在请求完成时,通过将文件句柄设为有信号状态来通知应用程序,或者应用程序通过GetOverlappedResult察看IO请求是否完成,也可以通过一个事件对象来通知应用程序。

3、相关参数介绍
在oracle里为了提高io的速度,常用参数db_writer_processes和 dbwr_io_slaves 
    在数据库里事务数非常高,或db cache很大,一个DBWn process跟不上数据的load,我们可以调整这两个参数,这两个参数的作用就是增加io读写进程,启用异步io,加快io的速度 
多个 slaves 可以并行写数据文件,而多个dbwr也可以并行写数据文件 
一个 dbwr 多个 slaves是 dbwr搜集dirty  buffer而 slaves写数据文件 
多个dbwr 可以并行地搜集dirty buffer 并且并行地写数据文件 
但是如果系统支持AIO一般不用设置多dbwr 或者 io slaves 
db_writer_processes:在多cpu,多磁盘的环境,一般是每8个cpu一个dbwr进程 

什么时候配置这两个参数 
如果系统的io是瓶颈是,检查os是否支持异步io,如果支持异步io,但目前没有使用,那就启用异步io来缓解io瓶颈。如果os不支持异步io, 
或os已经启用异步io,但io还是瓶颈,那我们可以配置多个dbwr进程。配置这两个参数是要注意,大都是如下 
一个db_writer_processes,多个dbwr_io_slaves 
多个db_writer_processes,dbwr_io_slaves不启用

转载请标明出处【 linux 下filesystemio_options disk_asynch_io 导致的I/O性能下降】。

《www.micoder.cc》 虚拟化云计算,系统运维,安全技术服务.

网站已经关闭评论