Question

Je suis en train de faire un chemin d'insertion qui s'exécute avec succès.Lorsque j'essaie de traçage de l'exécution, j'ai l' ORA-12838: cannot read/modify an object after modifying it in parallel.

SQL> insert into emp_big select * from emp_big_temp;

411843 rows created.

Elapsed: 00:00:00.89

Execution Plan
----------------------------------------------------------
Plan hash value: 3203427748

-----------------------------------------------------------------------------------------
| Id  | Operation                | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |              |   357K|    45M|  1164   (1)| 00:00:14 |
|   1 |  LOAD TABLE CONVENTIONAL | EMP_BIG      |       |       |            |          |
|   2 |   TABLE ACCESS FULL      | EMP_BIG_TEMP |   357K|    45M|  1164   (1)| 00:00:14 |
-----------------------------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
         15  recursive calls
      31909  db block gets
      12829  consistent gets
          0  physical reads
   34685216  redo size
        845  bytes sent via SQL*Net to client
        802  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
     411843  rows processed

SQL> rollback;

Rollback complete.

Elapsed: 00:00:00.18
SQL>
SQL> insert /*+ append */ into emp_big select * from emp_big_temp;

411843 rows created.

Elapsed: 00:00:00.18

Execution Plan
----------------------------------------------------------
ERROR:
ORA-12838: cannot read/modify an object after modifying it in parallel


SP2-0612: Error generating AUTOTRACE EXPLAIN report

Statistics
----------------------------------------------------------
          0  recursive calls
       4438  db block gets
       4283  consistent gets
          0  physical reads
       7648  redo size
        829  bytes sent via SQL*Net to client
        816  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
     411843  rows processed

Questions:

  1. Table emp_big a le degré de parallélisme est à 1, selon select table_name, degree from user_tables.Pourquoi Oracle de la force d'insertion parallèles?
  2. Pourquoi ne l'aide autotrace trace cause ORA-12838?
Était-ce utile?

La solution

Réponse à la sortie d'origine:

Ce n'est pas causé par traçage.Vous obtiendrez la même erreur, même sans traçage, tout en répétant le même chemin direct de l'insertion.Question d'un commit après la première insertion.

C'est documentée de la restriction: ORA-12700 à ORA-19400

ORA-12838:impossible de lire/modifier un objet après l'avoir modifié en parallèle

Cause: Dans la même transaction, une tentative a été faite pour ajouter ou lire instructions de modification sur une table après qu'il a été modifié en en parallèle ou directement en charge.Ce n'est pas permise.

Action:Réécrire la transaction, ou la diviser en deux opérations:un contenant la première modification et la deuxième contenant l'parallèle modification de l'opération.

Réponse à la nouvelle sortie, après la modification:

Ok, si vous avez un pas en arrière, et vous avez commencé une nouvelle transaction.Dans ce cas, traçage est vraiment le coupable, indirectement.La règle ci-dessus s'applique toujours, et que la description ci-dessus dit, même une lecture de référence sera la cause de l'erreur ci-dessus.Si le traçage est activé, il est implicitement fonctionne quelque chose comme ceci (après l'original de votre déclaration a été fini):

EXPLAIN PLAN SET STATEMENT_ID='PLUSxxxxxx' FOR insert /*+ append */ into emp_big select * from emp_big_temp;

Vous pouvez facilement vérifier cela en permettant à la errorstack trace de l'erreur 12838 (c'est bien dans un environnement sandbox pour cette courte démo, mais ce n'est pas comment je pourrais le faire sur une vraie base de données):

alter system set events '12838 trace name errorstack level 3';

Si je lance ce maintenant:

SQL> create table t1 as select * from dba_objects where 1=2;

Table created.

SQL> alter system set events '12838 trace name errorstack level 3';

System altered.

SQL> set autotrace on
SQL> insert /*+ append */ into t1 select * from dba_objects;

20079 rows created.


Execution Plan
----------------------------------------------------------
ERROR:
ORA-12838: cannot read/modify an object after modifying it in parallel

Je vais trouver l'erreur et un fichier de trace dans le journal des alertes.Le fichier de trace contient ceci:

dbkedDefDump(): Starting a non-incident diagnostic dump (flags=0x0, level=3, mask=0x0)
----- Error Stack Dump -----
ORA-12838: cannot read/modify an object after modifying it in parallel
----- Current SQL Statement for this session (sql_id=5x12x8czsd3t9) -----
EXPLAIN PLAN SET STATEMENT_ID='PLUS730007' FOR insert /*+ append */ into t1 select * from dba_objects

Et c'est ce qui provoque l'erreur, parce que c'est toujours la même transaction.Vous pouvez le tester, même sans traçage:

SQL> rollback;

Rollback complete.

SQL> set autotrace off
SQL> insert /*+ append */ into t1 select * from dba_objects;

20079 rows created.

SQL> explain plan for insert /*+ append */ into t1 select * from dba_objects;
explain plan for insert /*+ append */ into t1 select * from dba_objects
*
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel


SQL> select count(*) from t1;
select count(*) from t1
                     *
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel
Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top