当前位置: 首页 > Oracle, oracle 10g, oracle 11g > 正文

ORACLEl数据库log group不足及dbwn进程太少导致加载数据很慢问题

在使用外部表及imp向ORACLE数据库加载数据的时候,发现加载速度特别慢,加载一张1G多的数据需要2个小时,加载7G多的数据需要将近一下午的时间,经过分析发现大量等待都是log file switch和log buffer space等待事件。

SQL> select sql_id,OSUSER,MACHINE,TERMINAL,PROGRAM,EVENT,STATE  from v$session where username='CHGSHS';

PROGRAM                              EVENT                                     STATE
-----------------------------------  ----------------------------------------  ----------
sqlplus@SL010A-ISITDB3 (TNS V1-V3)   log file switch (checkpoint incomplete)   WAITING

/
PROGRAM                              EVENT                                     STATE
-----------------------------------  ----------------------------------------  ----------
sqlplus@SL010A-ISITDB3 (TNS V1-V3)   log buffer space                          WAITING

检查发现当前数据库有4组redo日志,每个redo文件500M,而且除CURRENT日志组外,其他日志组均是ACTIVE状态。

    GROUP# SEQUENCE#      BYTES     MEMBERS ARC STATUS 
---------- ---------- ---------- ---------- --- -------
         1       1075  524288000          1 NO  ACTIVE 
         2       1076  524288000          1 NO  ACTIVE 
         3       1077  524288000          1 NO  ACTIVE 
         4       1078  524288000          1 NO  CURRENT

日志切换要等到日志状态为INACTIVE状态才可以,这就需要等内存中的数据写入到数据文件中,可见目前磁盘写入速度不足,导致内存中的数据无法及时写入到磁盘,经查看,当前数据库只有3个数据写进程(dbwn)。

SQL> show parameter db_w

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_writer_processes                  integer     3

针对这种情况,最有效的方法是增大数据写进程的个数,但是调整数据写进程需要重启数据库才能生效,如果数据库不能及时重启,可以增加日志组来缓解这个问题,我这里增加了6组1GB的日志,增加后非常快新增的日志就被用到了,而且也全都是ACTIVE状态,也就是为解决这个问题,10个日志组还不够。

    GROUP#    THREAD#  SEQUENCE#      BYTES  BLOCKSIZE    MEMBERS ARC STATUS 
---------- ---------- ---------- ---------- ---------- ---------- --- -------
         1          1       1015  524288000        512          1 NO  ACTIVE 
         2          1       1016  524288000        512          1 NO  ACTIVE 
         3          1       1017  524288000        512          1 NO  ACTIVE 
         4          1       1018  524288000        512          1 NO  ACTIVE 
         5          1       1009 1073741824        512          1 NO  CURRENT
         6          1       1008 1073741824        512          1 NO  ACTIVE 
         7          1       1009 1073741824        512          1 NO  ACTIVE 
         8          1       1010 1073741824        512          1 NO  ACTIVE 
         9          1       1013 1073741824        512          1 NO  ACTIVE 
        10          1       1014 1073741824        512          1 NO  ACTIVE 

10 rows selected.

虽然增加日志组没有起到根本问题,但是数据加载速度明显加快,虽然也很难接受。最终的解决方法还是调整数据写进程。

SQL> alter system set db_writer_processes=10 scope=spfile;

System altered.

这里将数据写进程调整为10个,之前的3个是默认值,这个默认值是根据CPU的核数计算出来的,默认是CPU核数除以8,当前的数据服务器是24核,所以默认值就是3。

SQL> show parameter cpu

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cpu_count                            integer     24
parallel_threads_per_cpu             integer     2
resource_manager_cpu_allocation      integer     24

这里因为要加快数据加载的速度设置为10个数据写进程,数据写进程并不是越多越好,设置的多了,占用的CPU资源也就越多,生产环境需要根据相关的需求进行设置,一般来讲,生产环境服务器的CPU都比较多,默认值基本也够用了,比如40核的3850服务器,默认数据写进程就是5个,如果不是BI系统,基本够用了。

调整完数据写进程,在闲时重启数据库,再次加载数据速度明显提升,通过外部表的方式加载30G的数据,开8个并行,10分钟以内即可完成,之前可能需要一天一宿,而且在数据加载时,在也没有遇到日志等待的问题。

    GROUP#    THREAD#  SEQUENCE#      BYTES  BLOCKSIZE    MEMBERS ARC STATUS  
---------- ---------- ---------- ---------- ---------- ---------- --- --------
         1          1       1075 1073741824        512          1 NO  ACTIVE  
         2          1       1076 1073741824        512          1 NO  ACTIVE  
         3          1       1077 1073741824        512          1 NO  ACTIVE  
         4          1       1078 1073741824        512          1 NO  ACTIVE  
         5          1       1079 1073741824        512          1 NO  CURRENT 
         6          1       1068 1073741824        512          1 NO  INACTIVE
         7          1       1069 1073741824        512          1 NO  INACTIVE
         8          1       1070 1073741824        512          1 NO  INACTIVE
         9          1       1073 1073741824        512          1 NO  INACTIVE
        10          1       1074 1073741824        512          1 NO  INACTIVE

10 rows selected.

重启数据库后,将之前的4组500M的日志组也调整到了1GB。

这个优化,最终的解决方法就是增加了数据写进程(dbwn,也有人叫dbwr)的个数,使内存中的数据可以快速写入到磁盘,加快了检查点的完成时间,减少了日志等待的问题,可见优化效果非常明显。

本文固定链接: https://www.dbdream.com.cn/2016/04/oraclel%e6%95%b0%e6%8d%ae%e5%ba%93log-group%e4%b8%8d%e8%b6%b3%e5%8f%8adbwn%e8%bf%9b%e7%a8%8b%e5%a4%aa%e5%b0%91%e5%af%bc%e8%87%b4%e5%8a%a0%e8%bd%bd%e6%95%b0%e6%8d%ae%e5%be%88%e6%85%a2%e9%97%ae%e9%a2%98/ | 信春哥,系统稳,闭眼上线不回滚!

该日志由 dbdream 于2016年04月11日发表在 Oracle, oracle 10g, oracle 11g 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: ORACLEl数据库log group不足及dbwn进程太少导致加载数据很慢问题 | 信春哥,系统稳,闭眼上线不回滚!
关键字: , , ,

ORACLEl数据库log group不足及dbwn进程太少导致加载数据很慢问题:等您坐沙发呢!

发表评论

快捷键:Ctrl+Enter