【前言】
遇到 oracle 異常 和 解決實踐 系列文章 整理分享
雜症一、oracle死鎖
一、症狀:
執行SQL或程序時,程序沒有響應或SQL執行一直處於執行狀態,沒有成功,也沒有報錯。
二、病理:
當對數據庫某個表的某一記錄做更新或刪除等操作,執行完畢后該條語句不提交事務,假如其他人同時也對該數據庫執行一條對於這一記錄做更新操作的語句。則在執行的時候就會處於等待狀態,便陷入死鎖,一直沒有執行成功,也沒有報錯。
三、病因定位:
1)檢查數據庫確定 是否 真實存在死鎖,若有 哪台機器哪個程序。
SQL>select username, lockwait, status, machine, program from v$session where sid in (select session_id from v$locked_object);
Username:死鎖語句所用的數據庫用戶;
Lockwait :死鎖的狀態,如果有內容表示被死鎖。
Status :狀態,active表示被死鎖
Machine :死鎖語句所在的機器。
Program :產生死鎖的語句主要來自哪個應用程序。
2)確定死鎖后,還可以檢查是哪個語句產生死鎖等待。
SQL>select sql_text from v$sql where hash_value in (select sql_hash_value from v$session where sid in (select session_id from v$locked_object))
四、治療:
方式一:查詢未提交事務的SQL,大概率是其引起。
SQL>select s.sid, s.username, s.osuser, s.program, to_char(s.LOGON_TIME, 'yyyymmdd hh24:mi:ss') as LOGON_TIME, to_char(t.START_DATE, 'yyyymmdd hh24:mi:ss') as START_DATE, s.status, (select q.SQL_TEXT from v$sql q where q.LAST_ACTIVE_TIME = t.START_DATE and rownum <= 1) as SQL_TEXT from v$session s, v$transaction t where s.sADDR = t.SES_ADDR;
可以檢查到是誰在什么時候執行哪條SQL 沒有提交事務,找到對應的人,讓其提交事務,提交完成便問題解決。
方式二:若找不到對應的人,則可以通過kill掉死鎖的session進程
SQL>SELECT l.SESSION_ID, l.OS_USER_NAME, s.USERNAME, l.OBJECT_ID, l.ORACLE_USERNAME FROM v$locked_object l , v$session s WHERE l.SESSION_ID = s.SID
其中
進程 SID=10 的SQL為 未提交事務的SQL;
進程 SID=133 的SQL為 死鎖中的SQL
SQL>select sql_text from v$sql where hash_value in (select sql_hash_value from v$session where sid in (133))
SQL> alter system kill session '10,133';
方式三:獲取oracle進程,直接kill掉oracle進程然后重啟不建議(或 直接重啟數據庫)
# ps -ef|grep ora_dbw0_$Oracle_SID # kill -9 sid
重啟數據庫
# su oracle # sqlplus /nolog SQL> conn /as sysdba SQL> shutdown immediate; SQL> startup;
轉自:https://blog.csdn.net/heshushun/article/details/80422137