21:10分收到告警,數(shù)據(jù)庫會話500多個,一下來精神了,開機干活,告警有些延遲。
登陸數(shù)據(jù)庫已是21:15,檢查會話都已正常,難道是告警故意搞事?保險起見開始仔細看看吧
select to_char(sample_time,'YYYY-MM-DD hh24:mi:ss') mtime,count(*) c from ash_11_30 where
sample_time > to_date('2021-11-30 21:02:00','YYYY-MM-DD hh24:mi:ss')
and
sample_time< to_date('2021-11-30 21:10:30','YYYY-MM-DD hh24:mi:ss')
group by to_char(sample_time,'YYYY-MM-DD hh24:mi:ss')
order by 1,2

看到這個我發(fā)現(xiàn)問題絕對沒有那么簡單,21:04開始,會話在緩慢的增長,一直持續(xù)6分鐘,最高達到550個,然后在21:26又突然恢復正常了,不可思議。那么這6分鐘數(shù)據(jù)庫到底經(jīng)歷了什么,如果時間在長點數(shù)據(jù)庫會話會達到上千,那我只能殺頭謝罪了…
還是好好分析分析吧
select * from (
select to_char(sample_time,'YYYY-MM-DD hh24:mi:ss') mtime,count(*) c ,sql_id,event ,blocking_session ,blocking_session_serial# from ash_11_30 where
sample_time > to_date('2021-11-30 21:02:00','YYYY-MM-DD hh24:mi:ss')
and
sample_time< to_date('2021-11-30 21:10:30','YYYY-MM-DD hh24:mi:ss')
group by to_char(sample_time,'YYYY-MM-DD hh24:mi:ss') ,sql_id,event,blocking_session,blocking_session_serial#
order by 1,2) where c >10


看到這里等待事件enq: TX - row lock contention就一下松了一口氣,心里憑經(jīng)驗猜測肯定是慢SQL。通過查詢到的兩個阻塞源進一步分析。
21:04開始阻塞源為7296,60065,21:10:24阻塞源變成2877,50237
來吧一個一個分析吧。。
2877,50237
select to_char(sample_time,'YYYY-MM-DD hh24:mi:ss') mtime,session_id,session_type,sql_id, event,blocking_session ,blocking_session_serial#
from dba_hist_active_sess_history where session_id =2877 and session_serial#=50237
and
sample_time > to_date('2021-11-30 21:00:00','YYYY-MM-DD hh24:mi:ss')
and
sample_time< to_date('2021-11-30 21:10:30','YYYY-MM-DD hh24:mi:ss')


好吧阻塞源指向了7296,其實也很好理解,21:04開始阻塞源就是7296,上面查詢只是確認是否只有7296為阻塞源。
select to_char(sample_time,'YYYY-MM-DD hh24:mi:ss') mtime,session_id,session_type,sql_id, event,blocking_session ,blocking_session_serial#
from dba_hist_active_sess_history where session_id =7296 and session_serial#=60065 and
sample_time > to_date('2021-11-30 20:50:00','YYYY-MM-DD hh24:mi:ss')
and
sample_time< to_date('2021-11-30 21:11:00','YYYY-MM-DD hh24:mi:ss')


SQL 1gxh36ahnkf8y 從21:03:07開始執(zhí)行 執(zhí)行到21:10:20 才結束,執(zhí)行了7分13秒,通過查詢SQL文本確認為同一個表的update
那么這個SQL有問題嗎?
SQL文本如下
update table_eve
set to_es = -1
where exists (select id
from table_eve
where to_es = -4
and time < sysdate - 6 / 24)
查看執(zhí)行計劃

很顯然SQL有性能問題,下面怎么做呢,別著急加索引,他的SQL寫的也不對,使用exists的時候不應該加上列的關聯(lián)條件嗎。這坑!!
update table_eve a
set to_es = -1
where exists (select id
from table_eve b
where to_es = -4
and time < sysdate - 6 / 24
and a.id=b.id)

好了做個總結可以下班了
總結
21:03:07問題SQL開始執(zhí)行,由于要update的數(shù)據(jù)量較大 ,全表掃描時間較長,造成大量的對相同表update的語句阻塞,顯而易見的可以看到會話數(shù)量程指數(shù)增長,到21:10:25會話數(shù)量急劇下降瞬間恢復正常,其實很簡單,這個問題SQL21:10:20執(zhí)行完了,所以堆積的update都在瞬間執(zhí)行完了。




