Oracle導致Redo日志暴增的SQL語句排查


一、概述

最近數據庫頻繁不定時的報出一些耗時長的SQL,甚至SQL執行時間過長,導致連接斷開現象。下面是一些排查思路。

二、查詢日志的大小,日志組情況

SELECT L.GROUP#,
       LF.MEMBER,
       L.ARCHIVED,
       L.BYTES / 1024 / 1024 "SIZE(M)",
       L.MEMBERS
FROM V$LOG L,
     V$LOGFILE LF
WHERE L.GROUP# = LF.GROUP#;

查詢結果:

 

 從上圖可以看出目前共分為10個日志組,每個日志組2個文件,每個文件大小為3G。

三、查詢Oracle最近幾天每小時歸檔日志產生數量

SELECT SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH:MI:SS'), 1, 5)                             Day,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '00', 1, 0)) H00,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '01', 1, 0)) H01,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '02', 1, 0)) H02,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '03', 1, 0)) H03,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '04', 1, 0)) H04,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '05', 1, 0)) H05,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '06', 1, 0)) H06,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '07', 1, 0)) H07,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '08', 1, 0)) H08,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '09', 1, 0)) H09,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '10', 1, 0)) H10,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '11', 1, 0)) H11,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '12', 1, 0)) H12,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '13', 1, 0)) H13,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '14', 1, 0)) H14,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '15', 1, 0)) H15,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '16', 1, 0)) H16,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '17', 1, 0)) H17,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '18', 1, 0)) H18,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '19', 1, 0)) H19,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '20', 1, 0)) H20,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '21', 1, 0)) H21,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '22', 1, 0)) H22,
       SUM(DECODE(SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH24:MI:SS'), 10, 2), '23', 1, 0)) H23,
       COUNT(*)                                                                           TOTAL
FROM v$log_history a
WHERE first_time >= to_char(sysdate - 10)
GROUP BY SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH:MI:SS'), 1, 5)
ORDER BY SUBSTR(TO_CHAR(first_time, 'MM/DD/RR HH:MI:SS'), 1, 5) DESC;

查詢結果

 

從上圖可以看出業務高峰期每小時產生40個日志文件左右(目前設定的每個日志文件大小為3G),平均1.5分鍾產生一個3G的日志文件。而oracle官方建議Redo日志平均30分鍾切換一次最好

四、查看最近2小時"塊改變"最多的segment

redo大量產生必然是由於大量產生"塊改變"。從awr視圖中找到"塊改變"最多的segment。

這是查詢最近2小時(120分鍾)的,begin_interval_time> sysdate - 120/1440,大家也可以自定義修改查詢最近多少分鍾的。

 1 select *
 2 from (SELECT to_char(begin_interval_time, 'YYYY_MM_DD HH24:MI') snap_time,
 3              dhsso.object_name,
 4              SUM(db_block_changes_delta)
 5       FROM dba_hist_seg_stat dhss,
 6            dba_hist_seg_stat_obj dhsso,
 7            dba_hist_snapshot dhs
 8       WHERE dhs.snap_id = dhss.snap_id
 9         AND dhs.instance_number = dhss.instance_number
10         AND dhss.obj# = dhsso.obj#
11         AND dhss.dataobj# = dhsso.dataobj#
12         AND begin_interval_time > sysdate - 120 / 1440
13       GROUP BY to_char(begin_interval_time, 'YYYY_MM_DD HH24:MI'), dhsso.object_name
14       order by 3 desc)
15 where rownum <= 5;

查詢結果:

 

五、從awr視圖中找出步驟四中排序靠前的對象涉及的SQL

說明:LIKE '%MON_MODS$%'中MON_MODS是步驟1中查詢出來的OBJECT_NAME

 1 SELECT to_char(begin_interval_time, 'YYYY_MM_DD HH24:MI'),
 2        dbms_lob.substr(sql_text, 4000, 1),
 3        dhss.instance_number,
 4        dhss.sql_id,
 5        executions_delta,
 6        rows_processed_delta
 7 FROM dba_hist_sqlstat dhss,
 8      dba_hist_snapshot dhs,
 9      dba_hist_sqltext dhst
10 WHERE UPPER(dhst.sql_text) LIKE '%MON_MODS$%'
11   AND dhss.snap_id = dhs.snap_id
12   AND dhss.instance_Number = dhs.instance_number
13   AND dhss.sql_id = dhst.sql_id;

查詢結果

 

六、從ASH相關視圖找到執行這些SQL的session、module和machine

1 select * from dba_hist_active_sess_history WHERE sql_id = 'c9n8kv7afchtd';
2 select * from v$active_session_history where sql_Id = 'c9n8kv7afchtd';
c9n8kv7afchtd是SQL_ID,替換第二步查詢的結果SQL_ID列

 七、排查問題SQL

通過第四步,我們確定了導致產生大量redo日志主要涉及三張表,再通過第五步確定了每張表排名前五的SQL。針對這些產生大量Redo日志的SQL,就是需要做優化的地方。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM