A fellow DBA supported an application that had a process that compiled a number of packages every night as part of a scheduled script. Sample command:
ALTER PACKAGE schema.package_name COMPILE PACKAGE; ERROR at line 1: ORA-04021: timeout occurred while waiting to lock object
Over the last couple of days this script began to fail every night. I used the below SQL to identify the blocking session:
select * from gv$active_session_history where sample_time > sysdate - (interval '1' day) and sql_opname = 'ALTER PACKAGE' and not blocking_Session is null order by sample_time ;
This SQL returned the information identifying the blocks with the sample time exactly matching the script’s scheduled run time. I used the sample time, blocking session id, session serial and instance id and ran the below SQL:
select * from gv$active_session_history where sample_time between to_date('07-AUG-17 08.01 PM', 'dd-mon-yy hh.mi pm') and to_date('07-AUG-17 09.32 PM', 'dd-mon-yy hh.mi pm') and session_id = and session_serial# = and inst_id = order by sample_time ;
This provided me the last sql_id that the blocking session had executed.
select * from gv$sql where inst_id = and sql_id in 'sql id' ;
The last SQL that the blocking session had executed happened to be a select. However, working on the assumption that it had previously performed a DML, I cancelled the session and the ALTER PACKAGES script was able to execute successfully.