暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle性能优化之'read by other session'等待事件

数据与人 2020-12-15
1690

Oracle性能优化之'read by other session'等待事件


问题背景:客户反应系统访问变慢,协助排查优化

 

1> 检查等待事件

    set linesize 200 
    col username for a15
    col event for a35
    col program for a20
    col cpu_p for 99.99
    select ta.*, round(ta.cpu_time tb.total_cpu * 100, 1) cpu_usage from (select s.username, s.program, s.event, s.sql_id, sum(trunc(m.cpu)) cpu_time, count(*) sum from v$sessmetric m, v$session s where (m.physical_reads > 100 or m.cpu > 100 or m.logical_reads > 100) and m.session_id = s.sid and m.session_serial_num = s.serial# and s.status = 'ACTIVE' and username is not null group by s.username, s.program, s.event, s.sql_id order by 5 desc) ta, (select sum(cpu) total_cpu from v$sessmetric) tb where rownum < 11;

      select event,count(1) from  v$session_wait group by event order by  2 desc;

      大量read by other session等待事件。

       

      2> 查看相关sql

      找到read by other session的SQL,同时可以取一个AWR报告看看TOP SQL,都指向同一SQL。

        select sid,
        s.username,
        s.program,
        s.action,
        logon_time,
        q.sql_text,
        q.SQL_FULLTEXT,
        q.sql_id
        from v$session s
        left join v$sql q on s.sql_hash_value = q.hash_value
        where s.sid in (select sid
        from v$session_wait
        where event in ('read by other session'));


        3> 执行一下SQL,查看SQL执行计划。

         但是SQL很明显是走了一个错误的索引。

          select count(*) as pageno
          from table1
          where targetid = :"SYS_B_0"
          and msgId in
          (select msgId from table2 where userId = :"SYS_B_1")
          and classname not in (:"SYS_B_2", :"SYS_B_3", :"SYS_B_4")
          and dateTime


          4> 错误的执行计划很可能是表统计信息不准确。

          经查询,果然是表2统计信息不准确。收集统计信息或者加hint解决问题。

            execute dbms_stats.gather_table_stats(ownname => 'owner', tabname =>'table2', estimate_percent =>DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO', cascade => TRUE);

            备注:

            read by other session这个等待事件其实是oracle IO问题一个比较常见的场景,会话a在进行把磁盘上的数据块读到内存(data buffer cache)中这个操作,

            会话b,会话c 同时也请求这个数据块。

            因为会话a还完全读入内存(data buffer cache),

            就导致了b,c read by other session。

            所以会话a一般是db file sequential read  或 db file scattered read。

            也是一种热块现象。

             

            当出现该问题如何解决?

            一般出现该问题是由于sql导致的,或者是由于磁盘设备可能导致。

            当出现该问题的时候,首先需要定位sql。

            方法一:通过ash获得细粒度的报告,查看top sql statement 获得sql。

            方法二:通过sql语句直接获得:

             

            当前正在发生的问题:

              select sql_fulltext from v$sql a,v$session b where a.sql_id=b.sql_id and b.event='read by other session';


              历史曾经发生的

                select a.sql_id,sql_fulltext from v$sql a,dba_hist_active_sess_history b where a.sql_id=b.sql_id and b.event='read by other session';

                往往read by other session伴随着db file sequential read事件的出现。

                另外可以查看涉及对象信息,此处就是p1,p2,p3

                  SELECT p1 "file#", p2 "block#", p3 "class#"
                  FROM v$session_wait WHERE event = 'read by other session';

                  通过p1,p2,p3获得热点对象:

                    SELECT relative_fno, owner, segment_name, segment_type FROM dba_extents
                    WHERE file_id = &file
                    AND &block BETWEEN block_id AND block_id + blocks - 1;

                    另外,也可以 直接查看热点块的信息,如查看热点块导致的sql语句:

                      select sql_text
                      from v$sqltext a,
                      (select distinct a.owner, a.segment_name, a.segment_type
                      from dba_extents a,
                      (select dbarfil, dbablk
                      from (select dbarfil, dbablk from x$bh order by tch desc)
                      where rownum < 11) b
                      where a.RELATIVE_FNO = b.dbarfil
                      and a.BLOCK_ID <= b.dbablk
                      and a.block_id + a.blocks > b.dbablk) b
                      where a.sql_text like '%' || b.segment_name || '%'
                      and b.segment_type = 'TABLE'
                      order by a.hash_value, a.address, a.piece;

                      查看热点块对象:

                        SELECT E.OWNER, E.SEGMENT_NAME, E.SEGMENT_TYPE
                        FROM DBA_EXTENTS E,
                        (SELECT *
                        FROM (SELECT ADDR, TS#, FILE#, DBARFIL, DBABLK, TCH
                        FROM X$BH
                        ORDER BY TCH DESC)
                        WHERE ROWNUM < 11) B
                        WHERE E.RELATIVE_FNO = B.DBARFIL
                        AND E.BLOCK_ID <= B.DBABLK
                        AND E.BLOCK_ID + E.BLOCKS > B.DBABLK;


                        找到sql之后需要做的就是查看执行计划,判断问题所在,并进行优化。

                         1、对于在shared pool存在的cursor可以通过如下命令查看执行计划

                          select * from table(dbms_xplan.display_cursor('sql_id',null,'allstats'));

                          2、对于历史可以通过查看awr信息获得:

                            select * from table(dbms_xplan.display_awr('sql_id'));

                            另外对于设备引起的需要查看磁盘读写信息,可以通过vmstat 2 200进行判断。





                            往期回顾


                            Oracle性能优化之'Streams AQ: enqueue blocked on low memory'等待事件
                            Oracle性能优化之'latch free:Result Cache:RC Latch'等待事件
                            Oracle性能优化之sql嵌套循环改写案例


                            客官长按关注

                            吾辈自强不息


                            文章转载自数据与人,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                            评论