1

I am trying to understand the reason why i get the below error.

`ORA-04021: timeout occurred while waiting to lock object`

This error is thrown from a procedure while running the command alter table <<T_NAME>> truncate subpartition <<SUBPARTITION_NAME>>.

    v_dyncursor_stmt := 'with obj as (select /*+ materialize */ data_object_id, subobject_name from   user_objects where  object_name = UPPER(''' ||
                    p_table_name ||
                    ''') and object_type = ''TABLE SUBPARTITION'') select '||p_hint||' distinct subobject_name from ' ||
                    p_table_name || ' t, obj where data_object_id = DBMS_MView.PMarker(t.rowid) and ' || p_where;

/* log */
log_text(v_unit_name, 'INFO', 'Open cursor', v_dyncursor_stmt);

/* loop over partitions which needs to be truncated */
v_counter := 0;
open c_subpartitions for v_dyncursor_stmt;
loop
  FETCH c_subpartitions
    INTO v_subpartition_name;
  EXIT WHEN c_subpartitions%NOTFOUND;

  v_statement := 'alter table ' || p_table_name || ' truncate subpartition "' || v_subpartition_name || '"';

  execStmt(v_statement);

the code is calling above procedure twice and the first attempt is successful. it truncates the subpartition fine. In the second attempt it is failing... The execStmt function is given below, the error is thrown from EXCEUTE IMMEDITE line...

procedure execStmt(p_statement IN VARCHAR2) IS
  v_unit_name varchar2(1024) := 'execStmt';
v_simulate  varchar2(256);
begin
v_simulate := utilities.get_parameter('PART_PURGE_SIMULATE', '0');
if (v_simulate = '1') then
  log_text(v_unit_name, 'INFO', 'Statement skipped. (PART_PURGE_SIMULATE=1)', 
p_statement);
else
  /* log */
  log_text(v_unit_name, 'INFO', 'Executing statement', p_statement);

  EXECUTE IMMEDIATE p_statement;
end if;

end;

As this happens mostly over the weekend, i do not get a chance to inspect the lock tables to see what has locked the object. but i know for sure that it is a table which has alot of inserts happening. So my question is can an insert operation on a table prevent the above DDL ??

enter image description here

from oracle docs,i see that an insert aquires a SX lock which is explained as below,

A row exclusive lock (RX), also called a subexclusive table lock (SX), indicates that the transaction holding the lock has updated table rows or issued SELECT ... FOR UPDATE. An SX lock allows other transactions to query, insert, update, delete, or lock rows concurrently in the same table. Therefore, SX locks allow multiple transactions to obtain simultaneous SX and SS locks for the same table.

Divya MV
  • 2,021
  • 3
  • 31
  • 55
  • You should be able to `truncate partition` that is not a target of the running `insert`. Trying to truncate a partition with uncommited DML you will get `ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired`, so your problem with `ORA-04021` seems to have other cause. Is it possible you need to re-compile some invalid package that is in use, etc? – Marmite Bomber May 28 '21 at 14:22
  • @MarmiteBomber : how can i find out the invalid package ? if it helps...This issue does not happen all the time..it is intermittent. isn't ORA- 04021 also of the same nature as that of ORA-00054.. – Divya MV May 28 '21 at 14:32
  • 1
    Check the Notes 1054939.6 or 169139.1 (MOS User Required) you must first realize which object is causing the `ORA-04021` it need not be a package it can be a table as well or other types. This exception after compiling a used package is only the most *popular*. – Marmite Bomber May 28 '21 at 14:49
  • @MarmiteBomber ... Thank You, I see that the procedure altering the table is doing it through a dynamic cusror...i have updated the code in the question... could you please check this and suggest if there is a chance from the cursor creation.... ? – Divya MV May 29 '21 at 16:05
  • @MarmiteBomber ... I have added the part of the code . There are logs of opening cursor...but then the procedure fails .... can the dynamic cursor creation or execution of prepared statements make the pkg compile again ? Nobody is manually trying to update the same package. Could you please check one. I am not a DBA so have limited access or knowledge to check things further. – Divya MV May 31 '21 at 01:49

1 Answers1

0

This error happens because partition you are trying to truncate is in use at that time. And as mentioned by you, these insert statements are running that time, and it can affect DDL operation.

Alex
  • 815
  • 9
  • 19
purtu
  • 177
  • 3
  • 11