-
29-09-2020 - |
题
我正在执行成功执行的直接路径插入。当我尝试自动跟踪执行时,我得到了 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
问题:
- 桌子
emp_big
并行度设置为 1,根据select table_name, degree from user_tables
. 。为什么Oracle强制并行插入? - 为什么使用
autotrace trace
原因ORA-12838
?
解决方案
对原始输出的回答:
这不是由 autotrace 引起的。即使没有自动跟踪,只需重复相同的直接路径插入,您也会得到相同的错误。第一次插入后发出提交。
这是一个记录在案的限制: ORA-12700 到 ORA-19400
ORA-12838:并行修改对象后无法读取/修改对象
原因: 在同一交易内, ,尝试并行修改后,尝试在表上添加读取或修改语句 或直接负载. 。这是不允许的。
行动:重写交易,或将其分解为两项交易:一个包含初始修改,第二个包含并行修改操作。
编辑后回答新输出:
好的,你已经回滚了,并且开始了一个新的事务。在这种情况下,autotrace 确实是间接的罪魁祸首。上述规则仍然适用,并且正如上面的描述所述,即使是读取引用也会导致上述错误。如果启用了自动跟踪,它会隐式运行如下所示的内容(在原始语句完成后):
EXPLAIN PLAN SET STATEMENT_ID='PLUSxxxxxx' FOR insert /*+ append */ into emp_big select * from emp_big_temp;
您可以通过启用错误 12838 的错误堆栈跟踪来轻松确认这一点(对于这个简短的演示,在沙盒环境中没问题,但这不是我在真实数据库上执行此操作的方式):
alter system set events '12838 trace name errorstack level 3';
如果我现在运行这个:
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
我会在警报日志中找到错误和跟踪文件。跟踪文件包含以下内容:
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
这就是导致错误的原因,因为它仍然是同一事务。即使没有自动跟踪,您也可以测试它:
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