2016年10月27日下午,测试同事说测试数据库连接不上了,让我们DBA查看问题并解决一下。
   操作系统:Red Hat Enterprise Linux Server release 6.6 (Santiago)
    数据库版本:
[oracle@se31 ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.4.0 Production on Fri Oct 28 08:59:04 2016
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE 11.2.0.4.0 Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
   刚登陆上数据库服务器,发现服务器的IO已经被耗光:

    查看数据库告警日志,发现最大进程数告警:
Thu Oct 27 14:24:51 2016
ORA-00020: ???讴???)
 ORA-20 errors will not be written to the alert log for
 the next minute. Please look at trace files to see all
 the ORA-20 errors.
Process P198 submission failed with error = 20
Thu Oct 27 14:25:58 2016
ORA-00020: maximum number of processes (300) exceeded
 ORA-20 errors will not be written to the alert log for
 the next minute. Please look at trace files to see all
 the ORA-20 errors.
    数据库的最大进程数设置确实是300,但是测试库是针对测试用的,最大进程数设置稍微小点容易暴露项目得问题,并且平时测试没有出现过类似情况。
SQL> show parameter processes
NAME     TYPE VALUE
------------------------------------ ----------- ------------------------------
aq_tm_processes     integer 1
db_writer_processes     integer 3
gcs_server_processes     integer 0
global_txn_processes     integer 1
job_queue_processes     integer 1000
log_archive_max_processes     integer 4
processes     integer 300
SQL> 
   先排除最大进程数,继续查看数据库中的非空闲等待事件:
SQL> select event,count(*) from v$session where wait_class<>'Idle' group by event;
EVENT     COUNT(*)
---------------------------------------------------------- ----------
direct path read temp    5
latch free   23
SQL*Net message to client    2
   然后,按照等待事件查看相关会话执行的sql语句:
SQL> select sid from v$session where event='&event_name';
Enter value for event_name: latch free
old   1: select sid from v$session where event='&event_name'
new   1: select sid from v$session where event='latch free'
SID
-----------
11
26
52
56
67
113
120
139
189
244
245
265
267
291
315
326
363
402
414
423
434
447
22 rows selected.
SQL> set linesize 1000
col username for a15
col osuser for a15
select sid,wait_class_id,user#,username,lockwait,status,osuser,sql_id,PREV_SQL_ID from v$session where 
wait_class_id= 1893977003 and sid=&sid;SQL> SQL> SQL>   2  
Enter value for sid: 11
old   2: wait_class_id= 1893977003 and sid=&sid
new   2: wait_class_id= 1893977003 and sid=11
SID       WAIT_CLASS_ID      USER# USERNAME            LOCKWAIT      STATUS OSUSER          SQL_ID                  PREV_SQL_ID
----------- -------------               ---------- ---------------          ----------------     ----------   ---------------     -------------              -------------
11        1893977003          156      BMI_NANCHONG                        ACTIVE    ASP.NET v4.0 c8m5td2tmpcxg
   查看c8m5td2tmpcxg的sql语句:
SQL> select sql_fulltext from v$sqlarea where sql_id='c8m5td2tmpcxg';
select *
  from (select row_.*, rownum NumRow
          from (select b.table_par    as tablepar,
                       a.bill_no      as billcode,
                       b.item_date    as itemdate,
                       b.item_id      as itemid,
                       b.item_name    as name,
                       b.numbers,
                       b.price,
                       b.costs,
                       b.drug_spec    as specification s,
                       b.package_unit as itemunit,
                       
                       b.reject_money     as rejectmone y,
                       b.reject_num       as rejectnumber,
                       b.reject_reson     as rejectreso n,
                       a.admission_number as admiss ionnumber,
                       b.physician_name   as doctorna me,
                       b.deptname         as deptname,
                       a.patient_name     as patientnam e,
                       d.dosage_name      as dosagename,
                       
                       nvl(d.varchar01, zs.varchar01) as packages,
                       nvl(d.manu_name, zs.manu_name) as manuname,
                       a.PATIENT_ID as BillPatientI d,
                       a.ADMISSION_DATE as BillAdmi ssonDate,
                       a.DISCHARGE_DATE as BillDisc hargeDate,
                       b.hospital_remark as hospitalremark,
                       zdr.region_name as region_name
                  from dw_billdetail b
                 inner join dw_bill a
                    on b.pid = a.hisid
                   and b.table_par = a.table_par
                  left join dw_zd_drug d
                    on b. item_id = d.item_id
                  left join dw_zd_service zs
                    on b.item_id = zs.item_id
                  left join d w_zd_region zdr
                    on zdr.region_id = a.bmi_code
                 where 1 = 1
                   AND a.andit_manu_statu
                 s IN (:paramBillStatus0,
                             :paramBillStatus1,
                             :paramBillStatus2,
                             :paramBillStatus3)
                   and b.reject_money > 0
                   and a.hospital_id = :paramHosptialID4
                   and b.table_par >= :stabPar5
                   and b.table_par <= :etabPar6
                 order by b.pid, b.item_date) row_
         where rownum <= 50)
 where NumRow > 0

查看c8m5td2tmpcxg的子游标及执行计划情况:
SQL> select child_number,executions,buffer_gets,is_bind_sensitive BS,
is_bind_aware BA,is_shareable SH,plan_hash_value
from v$sql
where sql_id='&sql_id';  2    3    4  
Enter value for sql_id: c8m5td2tmpcxg
old   4: where sql_id='&sql_id'
new   4: where sql_id='c8m5td2tmpcxg'
CHILD_NUMBER EXECUTIONS BUFFER_GETS B B S PLAN_HASH_VALUE
------------           ----------         -----------         - - -       ---------------
  0                       18           669286643    Y N Y      3571375093
  1                        0           3013153881   Y N Y      3571375093
  2                        1                       380   Y N Y      1661143992
  3                        0                    78051   Y N Y      1661143992
  5                        0            870616787    N N Y      3571375093

经过查看只有0、1、3能看到执行计划,
select * from table(dbms_xplan.display_cursor('c8m5td2tmpcxg',0,'typical'));

select * from table(dbms_xplan.display_cursor('c8m5td2tmpcxg',1,'typical'))


select * from table(dbms_xplan.display_cursor('c8m5td2tmpcxg',2,'typical'))

其余的子游标对应的执行计划已经查不到了:
SQL> c/2/3
  1* select * from table(dbms_xplan.display_cursor('c8m5td5tmpcxg',3,'typical'))
SQL> /
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID: c8m5td5tmpcxg, child number: 3 cannot be found
SQL> c/3/5
  1* select * from table(dbms_xplan.display_cursor('c8m5td5tmpcxg',5,'typical'))
SQL> /
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID: c8m5td5tmpcxg, child number: 5 cannot be found
  另外一个等待事件的会话发起的sql语句还是:c8m5td5tmpcxg
SQL> select sid from v$session where event='&event_name';
Enter value for event_name: direct path read temp
old   1: select sid from v$session where event='&event_name'
new   1: select sid from v$session where event='direct path read temp'
SID
-----------
28
113
139
215
315
326
355
414
8 rows selected.
SQL> select wait_time,wait_class_id,state from v$session_wait where sid=&sid;
Enter value for sid: 28
old   1: select wait_time,wait_class_id,state from v$session_wait where sid=&sid
new   1: select wait_time,wait_class_id,state from v$session_wait where sid=28
 WAIT_TIME WAIT_CLASS_ID STATE
---------- ------------- -------------------
1    1740759767 WAITED KNOWN TIME
SQL> set linesize 1000
col username for a15
col osuser for a15
select sid,wait_class_id,user#,username,lockwait,status,osuser,sql_id,PREV_SQL_ID from v$session where 
wait_class_id= 1740759767 and sid=&sid;SQL> SQL> SQL>   2  
Enter value for sid: 28
old   2: wait_class_id= 1740759767 and sid=&sid
new   2: wait_class_id= 1740759767 and sid=28
SID WAIT_CLASS_ID      USER# USERNAME     LOCKWAIT      STATUS OSUSER SQL_ID        PREV_SQL_ID
----------- ------------- ---------- --------------- ---------------- ---------- --------------- ------------- -------------
28    1740759767 156 BMI_NANCHONG      ACTIVE ASP.NET v4.0 c8m5td2tmpcxg
   令人奇怪的是,这条sql语句上并没有并行相关的Hints,但是其执行计划里却体现出了并行执行QN,查看方案下的表并没有发现有开启并行的表:
SQL> select table_name,degree from user_tables where table_name in('DW_BILL','DW_BILLDETAIL','DW_ZD_DRUG','DW_ZD_SERVICE','DW_ZD_REGION');
TABLE_NAME                        DEGREE
---------------------------------------- --------------------
DW_BILL                             1
DW_BILLDETAIL                  1
DW_ZD_DRUG                    1
DW_ZD_REGION                 1
DW_ZD_SERVICE                1

经过与开发、测试同事了解,应用ASP.NET端的部署没有开启并行设置,然后查看了这几张表下的索引,果然索引下均有并行。


   看来是查询执行时,走了索引,触发了并行,耗尽了数据库的进程数,导致数据库对新连接无响应;接下来的处理措施是:查杀消耗CPU高的会话,取消掉索引的并行:
   按等待事件类型查杀会话:
SQL> select 'alter system kill session ',''''||a.sid||','||a.serial#||''';'
from v$session a  where event='latch free';  2  
'ALTERSYSTEMKILLSESSION'   ''''||A.SID||','||A.SERIAL#||''';'
-------------------------- ------------------------------------------------------------------------------------
alter system kill session  '11,85';
alter system kill session  '26,12795';
alter system kill session  '52,43';
alter system kill session  '56,3';
alter system kill session  '67,9473';
alter system kill session  '100,5';
alter system kill session  '120,37';
alter system kill session  '189,67';
alter system kill session  '244,19499';
alter system kill session  '245,9039';
alter system kill session  '265,13217';
alter system kill session  '267,237';
alter system kill session  '291,53';
alter system kill session  '363,8251';
alter system kill session  '402,39799';
alter system kill session  '423,2479';
alter system kill session  '434,1';
alter system kill session  '447,7877';
alter system kill session  '452,33';
19 rows selected.

SQL> select event,count(*) from v$session where wait_class<>'Idle' group by event;
EVENT                                                  COUNT(*)
---------------------------------------------------------- ----------
direct path read temp                              8
SQL*Net message to client                       1
SQL> select 'alter system kill session ',''''||a.sid||','||a.serial#||''';'
from v$session a  where event='&event_name';  2  
Enter value for event_name: direct path read temp
old   2: from v$session a  where event='&event_name'
new   2: from v$session a  where event='direct path read temp'
'ALTERSYSTEMKILLSESSION'   ''''||A.SID||','||A.SERIAL#||''';'
-------------------------- ------------------------------------------------------------------------------------
alter system kill session  '28,5109';
alter system kill session  '113,3';
alter system kill session  '139,15';
alter system kill session  '215,3';
alter system kill session  '315,5';
alter system kill session  '326,6017';
alter system kill session  '355,33';
alter system kill session  '414,3';
8 rows selected.
    杀完latch free、direct path read temp等待会话,数据库服务器的CPU恢复正常:

   接下来取消索引的并行:

由于修改sql相关对象的并行度,相当于其相关对象发生了DDL变更,会引起sql引擎对在相关对象上执行的sql语句重新解析,做完索引的并行度取消,
sql语句恢复正常,服务器没有发生并行使用过多的进程的情况:
   c8m5td2tmpcxg果然被重新硬解析,原来的5个子游标变成了现在的3个:
   SQL> select child_number,executions,buffer_gets,is_bind_sensitive BS,
is_bind_aware BA,is_shareable SH,plan_hash_value
from v$sql
where sql_id='&sql_id';  2    3    4  
Enter value for sql_id: c8m5td2tmpcxg
old   4: where sql_id='&sql_id'
new   4: where sql_id='c8m5td2tmpcxg'
CHILD_NUMBER EXECUTIONS BUFFER_GETS B B S PLAN_HASH_VALUE
------------ ---------- ----------- - - - ---------------
  1      0  3013153881 Y N Y      3571375093
  2      6      238503 Y N Y      3286212919
  3      0       78051 Y N Y      1661143992
   sql语句的执行计划恢复正常,没有了并行:

    如果你有不同见解或更好的解决思路,欢迎留言讨论!

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

转载于:http://blog.itpub.net/29357786/viewspace-2127263/

ORACLE 索引并行引起的direct path read temp和latch free等待导致进程数超过最大数相关推荐

  1. oracle direct path read temp,direct path read/read temp等待事件

    当会话从磁盘直接读取数据块到PGA(绕过SGA)时,发生direct path read/read temp等待事件 ,下图简要描述了这种方式的读取方式: 如果I/O子系统不支持异步I/Os,那么每个 ...

  2. 查询v$lock缓慢和direct path write temp等待

    v$lock是常用的enqueue lock队列锁动态性能视图,不管是用户自己部署的监控脚本也好.还是enterprise manager都多少会使用到该V$LOCK视图, 但是在10g中遇到了v$l ...

  3. oracle 11g禁用和强制direct path read

    一般在混合型环境中,大表在进行全表扫描或者走并行的时候一般会出现direct path read等待事件,如果在OLTP或者纯粹的DSS环境中,出现大量的direct path read直接路径读取, ...

  4. oracle direct path read temp,Oracle中的direct path read事件(转)

    在11g中,全表扫描可能使用direct path read方式,绕过buffer cache,这样的全表扫描就是物理读了. 在10g中,都是通过gc buffer来读的,所以不存在direct pa ...

  5. 生产环境 direct path read 与log file sync等待事件问题处理

    1. 2018-09-26 前7天awr报告(此期间 oracle 使用率为 4,022.34/6,179.76/24=2.71%) 由此看出最显著问题是 log file sync 等待事件,查看后 ...

  6. oracle 索引并行 hint,并行HINT并不一定起作用。

    今天又加班,憋屈的要死. 正无聊呢,同事过来问我个问题,为什么他通过HINT为查询指定了并行度5,但执行计划里却没有期待中的并行操作.这小子自从听我说了有并行这个东西后,对并行简直着了迷. 原语句如下 ...

  7. oracle直接路径读,direct path read直接路径读

    前言:传统的数据库读取的方式是先在内存中搜索,如果搜索不到数据,那么就在把数据从磁盘读到内存中,然后PGA再中SGA中获取数据,这样数据就缓存到内存中了,下次再次访问的时候,就可以直接从SGA中获取, ...

  8. oracle parallel 并行 设置 理解

    引子:以前一直没太关注oracle并行这个特性.前几天一个兄弟碰到的一个问题,才让我觉得这个东西还是有很多需要注意的地方,有必要仔细熟悉下.其实碰到的问题不复杂: 类似如下的一条语句:insert i ...

  9. 深入解析direct path read

     传统读取数据的方式是服务器进程通过读取磁盘,然后把数据加载到共享内存中,这样后面的进程就可以通过共享内存访问这些数据,不用再通过缓慢的磁盘读取来 完成.direct path read读取数据块 ...

最新文章

  1. win 2008 控制共享文件夹大小_Windows转Mac Win10局域网文件共享设置
  2. 洛谷——P1051 谁拿了最多奖学金
  3. view controller lifecycle discussion - beforeRendering
  4. 线上防雪崩利器——熔断器设计原理与实现
  5. Transformer太大了,我要把它微调成RNN
  6. pytorch 查看参数是否被训练 require_grad()
  7. div展示html文本,html – 使文本适合div
  8. python训练营微信广告发送机_python实现给微信公众号发送消息的方法
  9. 【mysql】使用脚本对mysql状态进行监控
  10. 类型的设计--方法:构造器、操作符、转换操作符和参数
  11. 【目标跟踪】基于matlab帧差法结合卡尔曼滤波行人姿态识别【含Matlab源码 1127期】
  12. php留言板回复功能,php简单的留言板与回复功能具体实现_PHP教程
  13. 深入浅出CChart 每日一课——快乐高四第二十课 七月流火,总复习之CChart多种编程模式
  14. 【Lv1-Lesson004】Imperative Sentences
  15. 瑞吉外卖——菜品展示功能(移动端)
  16. 深入浅出深度学习Pytroch
  17. 自建个人用服务器要多少钱,我想建立一个人网站,像19楼那样的论坛,是自建服务器便宜还是租用服务器便宜...
  18. java 使用md5_java中如何使用MD5进行加密
  19. 大数据东风下,Clickhouse这坨屎是怎么上天的
  20. ElementUI的el-tree实现懒加载查询和直接全部查询出来

热门文章

  1. eja智能压力变送器工作原理_HONEYWEL、 EJA 、罗斯蒙特变送器的工作原理
  2. Vue+SpringBoot+ElementUI实战学生管理系统-9.教师管理模块
  3. word中怎么看图片内存大小
  4. 误删除系统libselinux.so.1之后
  5. 用纯css实现下拉菜单的几种方式
  6. 阿里云大佬叮嘱我务必要科普这个 Elasticsearch API
  7. 电脑CPU名称修改装逼工具
  8. 安装有关软件出现无法访问windows Installer服务。
  9. Word交叉输入汉字和英文间距变大
  10. 精品展示案例(使用jQuery)