Skip to Main Content
  • Questions
  • DB Change from 12.1 to 12.2 RAC getting ORA-02297

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Andrej.

Asked: May 14, 2018 - 10:06 am UTC

Last updated: July 23, 2018 - 10:34 am UTC

Version: 12.2

Viewed 1000+ times

You Asked


We recently changed from a 12.1 Single Instance to a 12.2 Version running in a RAC environment with two nodes.

Wa are now facing the problem that a PL/SQL procedure nearly takes factor 3 longer to run than on the single instance.

Our Administrators already identified that each Statment executes in the same time. We already tried to connect directly to a single node in hope that the procedure behaves like on the single instance but it does not.

The second issue is, that the uncahnged procedure (it does it job withaout any issue for the past 3 years) comes up with the following error.

Caused by: java.sql.SQLException: ORA-20000: ORA-02297: Constraint (SCHEMA.SPIL_PK) kann nicht deaktiviert werden - Abhängigkeiten sind vorhanden: Fehlgeschlagen => ALTER TABLE SPIEL DISABLE CONSTRAINT SPIL_PK
ORA-06512: in "<SCHEMA>.PR_CLEAR_DATABASE", Zeile 59
ORA-06512: in "<SCHEMA>.PR_CLEAR_DATABASE", Zeile 59
ORA-06512: in Zeile 1


The procedure:
CREATE OR REPLACE PROCEDURE pr_CLEAR_DATABASE
AS

  CURSOR lc_select_table
  IS
    SELECT TABLE_NAME
    FROM USER_TABLES
    WHERE TABLE_NAME NOT IN ('SCHEMA_VERSION', 'KMS') 
       AND TABLE_NAME NOT LIKE 'QRTZ_%' 
    ORDER BY 1;
    
  CURSOR lc_enable_constraints
  IS
    SELECT 
     CONSTRAINT_NAME,
     TABLE_NAME
   FROM 
     USER_CONSTRAINTS
   WHERE 
     STATUS         = 'DISABLED'
     AND CONSTRAINT_TYPE IN ('P','R')
     AND TABLE_NAME NOT  IN ('SCHEMA_VERSION') 
     AND TABLE_NAME NOT LIKE 'QRTZ_%'
   ORDER BY R_CONSTRAINT_NAME DESC;
    
  CURSOR lc_disable_constraints
  IS
    SELECT 
     CONSTRAINT_NAME,
     TABLE_NAME
   FROM 
     USER_CONSTRAINTS
   WHERE 
     STATUS         = 'ENABLED'
     AND CONSTRAINT_TYPE IN ('P','R')
     AND TABLE_NAME NOT  IN ('SCHEMA_VERSION') 
     AND TABLE_NAME NOT LIKE 'QRTZ_%'
   ORDER BY R_CONSTRAINT_NAME ASC;
    
  lv_user            VARCHAR2(128);
  lv_sql             VARCHAR2(512);
BEGIN
 
  SELECT USER INTO lv_user FROM DUAL;
  IF ((lv_user='SYSTEM') OR (lv_user='SYS')) THEN
    RETURN;
  END IF;
  
  EXECUTE IMMEDIATE 'PURGE RECYCLEBIN';
  
  -- DISABLE table's constraints
  FOR lv_constraint IN lc_disable_constraints
  LOOP
    lv_sql := 'ALTER TABLE ' || lv_constraint.TABLE_NAME || ' DISABLE CONSTRAINT ' || lv_constraint.CONSTRAINT_NAME;
    BEGIN
      EXECUTE IMMEDIATE lv_sql ;
    EXCEPTION
    WHEN OTHERS THEN
      raise_application_error ( -20000, SQLERRM || ': Fehlgeschlagen => ' || lv_sql);
    END;
  END LOOP;
  
  -- TRUNCATE tables
  FOR lv_table IN lc_select_table
  LOOP
    --get table name
    lv_sql := 'TRUNCATE TABLE ' || lv_table.TABLE_NAME;
    BEGIN
      EXECUTE IMMEDIATE lv_sql ;
    EXCEPTION
    WHEN OTHERS THEN
      raise_application_error ( -20000, SQLERRM || ': Fehlgeschlagen => ' || lv_sql);
    END;
  END LOOP;
  
  -- ENABLE table's constraints
  FOR lv_constraint IN lc_enable_constraints
  LOOP
    lv_sql     := 'ALTER TABLE ' || lv_constraint.TABLE_NAME || ' ENABLE CONSTRAINT ' || lv_constraint.CONSTRAINT_NAME;
    BEGIN
      EXECUTE IMMEDIATE lv_sql ;
    EXCEPTION
    WHEN OTHERS THEN
      raise_application_error ( -20000, SQLERRM || ': Fehlgeschlagen => ' || lv_sql);
    END;
  END LOOP;
END;
/

and Chris said...

You get an ORA-02297 when you try and disable a PK which has an enabled FK pointing to it:

create table t1 (
  x int not null primary key
);
create table t2 (
  x int references t1 (x)
);

alter table t1 modify primary key disable ;

ORA-02297: cannot disable constraint (CHRIS.SYS_C0010760) - dependencies exist


Which means either:

- Someone added a new FK after the migration
- The constraint names changed during the migration

You're only sorting the constraints by name. So really you lucky this hasn't happened before. So either you need to change the cursor to get the FKs first:

ORDER BY CONSTRAINT_TYPE DESC, R_CONSTRAINT_NAME ASC


Or only select the PKs and use the cascade option:

alter table t1 modify primary key disable cascade;

Table T1 altered.

select status from user_constraints
where  constraint_type in ( 'P', 'R' )
and    table_name like 'T_';

STATUS     
DISABLED   
DISABLED  


When it comes to the performance change, there's only one answer I can give:

Trace your session to see what it's doing!

Ideally do the same on the original system so you can see what's taking longer.

Anything else is a wild guess (=> probably wrong). For details on how to do this, see:

https://blogs.oracle.com/sql/how-to-create-an-execution-plan#tkprof

If you're struggling to interpret the results, post your findings and we'll help out.

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Andrej Flieger, May 22, 2018 - 10:03 am UTC

We discovered that the behaviour did not occur, if we are turning one node down. -> It runs without error and in the same time than a single instance.

Furthermore our admins identified, that the two instances are differently configured in terms of block size.

Might this be a cause for this behaviour?
Chris Saxon
May 22, 2018 - 10:25 am UTC

What do you mean the instances have different block sizes?? All instances in RAC should have the same DB_BLOCK_SIZE. If they're different something fishy is going on.

And which behaviour did not occur? The error or the process taking longer?

Have you checked that the query returns all the foreign keys before the primary keys? Is it returning a different order when you go single instance?

Andrej Flieger, May 22, 2018 - 12:05 pm UTC

Neither the performance issue nor the ORA-02297 happens on the single Instance or on the RAC with only one running node.

I think i need to try to get to the admins, to identify the differences between the two nodes, because as already mentioned they said that the nodes are different in terms of DB_BLOCK_SIZE and probably more parameters.

What might be the parameters that must be identcal to each Node inside a RAC.
Chris Saxon
May 22, 2018 - 1:48 pm UTC

The parameters where isinstance_modifiable is 'FALSE' should be the same on all RAC nodes:

select * from v$parameter
where  isinstance_modifiable = 'FALSE';

Andrej Flieger, July 23, 2018 - 9:43 am UTC

What we discovered is, that the procedure takes three times longer on the RAC with two nodes than it took on the single instance.
On the RAC with two nodes enabled we got zhe following:
Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  PGA memory operation                          995        0.00          0.02
  gc cr block 2-way                               5        0.00          0.01
  gc current block 2-way                          2        0.00          0.00
  library cache lock                           1092        0.02          0.90
  library cache pin                            1146        0.10          1.00
  enq: IV -  contention                       13123        0.03         11.95
  row cache lock                                926        0.01          0.64
  Compression analysis                         2896        0.00          0.07
  enq: JZ - Join group dictionary                 1        0.00          0.00
  KJC: Wait for msg sends to complete            12        0.02          0.07
  enq: TM - contention                           16        0.00          0.00
  latch: ges resource hash list                   5        0.00          0.00
  gc current grant 2-way                         20        0.00          0.00
  reliable message                               14        0.01          0.02
  enq: RO - fast object reuse                    14        0.00          0.00
  db file sequential read                         7        0.00          0.00
  enq: CR - block range reuse ckpt                7        0.00          0.00
  acknowledge over PGA limit                      1        0.01          0.01
  kdic_do_merge                                  28        0.00          0.00
  latch free                                      1        0.00          0.00

 702  user  SQL statements in session.
  669  internal SQL statements in session.
 1371  SQL statements in session. 


On the single instance or on the RAC with only one node enabled we got the following
Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  reliable message                               20        0.00          0.00
  enq: RO - fast object reuse                     7        0.00          0.01
  db file sequential read                         7        0.00          0.00
  enq: CR - block range reuse ckpt                7        0.00          0.01

  723  user  SQL statements in session.
 1105  internal SQL statements in session.
 1828  SQL statements in session.


Chris Saxon
July 23, 2018 - 10:34 am UTC

Hmmm, lots of waits on "enq: IV - contention". You're going to have to contact support on this one.

There are some bugs related to this ( such as this https://support.oracle.com/knowledge/Oracle%20Database%20Products/2028503_1.html ). But they seem different to your issue.

More to Explore

SQL

The Oracle documentation contains a complete SQL reference.