一、背景:
某產品升級腳本報錯
‘and i am waiting very much time and now see a error’
| SQL>@upgrade.sql Porcedure created. PL/SQL procedure successfully completed Procedure created. Procedure dropped. Table truncated. Index created. Table created. 1 row craeted. Commit complete. Function created. CREATE OR REPLACE PROCEDURE update_onlineuser(lasttime in varchar2,segname in varchar2,tablename varchar2) * ERROR at line 1: ORA-04021:timeout occurred while waiting to lock object Procedure created. PL/SQL produre successfully completed. |
二、分析:
ORA-04021:等待鎖定對象時發生超時
腳本里含有create or replace procedure,如果存儲過程正在執行就會發生這種情況。而業務存儲過程是oracle的job定時調用的(每10秒)(不知道是否由於存儲過程執行時間超過10s造成存儲過程一直執行而導致腳本執行等待超時?)所以執行腳本前要先停止job,並且要停止正在執行的存儲過程或函數。
三、解決辦法:
1. 以DBA用戶登陸數據庫,在數據庫執行以下語句,為了job不執行,以免后面的執行腳本失敗
-->查看job_queue_processes參數的值
SQL> show parameter job;
SQL>alter system set job_queue_processes=0;
2. 查詢是否有正在執行的函數或存儲過程,所致對象鎖
SQL>select name
from v$db_object_cache
where owner='WISGDB'
and type in('PROCEDURE','FUNCTION')
and locks > 0
adn pins > 0;
如果能查詢出記錄,說明有存儲過程或函數在執行,需要等待存儲過程自己結束或者手工停止。
3. 手工停止正在執行的存儲過程(第二部如果沒有結果不需要執行此步驟)
SQL>select sid,serial#,status
from v$session a
where a.sid in (select sid
from v$access
where owner='WISGDB'
and OBJECT in (select name
from v$db_objuect_cache
where owner='WISGDB'
and type in ('PROCEDURE','FUNCTION')
and locks > 0
and pins > 0));
需要使用一下sql手工停止,用每一條記錄的SID,SERIAL字段值代替下面sql的SID與SERIAL#字樣
SQL>alter system kill session 'sid,serial#';
4.在wisgdb用戶下執行xxx數據庫腳本(執行前需確保第二部的SQL查詢結果為空)
5. 以DBA用戶登陸數據庫,恢復JOB
SQL>alter system set job_queue_processes=20;(與之前保持一致)
