【发布时间】:2013-05-04 20:23:51
【问题描述】:
我想知道为什么批量插入(使用直接路径)锁定整个表的核心原因(引擎所做的段、块、锁的机制),所以如果我插入到分区中,我不能截断另一个不受插入影响(显然)的分区。
传统的插入(没有附加提示)允许截断一些不受影响的分区。(注意我说的是非提交事务。)
下面是一个例子来说明它。
让我们成为一张桌子:
CREATE TABLE FG_TEST
(COL NUMBER )
PARTITION BY RANGE (COL)
(PARTITION "P1" VALUES LESS THAN (1000),
PARTITION "P2" VALUES LESS THAN (2000));
Insert into table fg_test values (1);
insert into table fg_test values (1000);
commit;
第 1 节:
insert into table fg_test select * from fg_test where col >=1000;
--1 rows inserted;
第 2 节:
alter table fg_test truncate partition p1;
--table truncated
第 1 节:
rollback;
insert /*+append */ into table fg_test select * from fg_test where col >=1000;
--1 rows inserted;
第 2 节:
alter table fg_test truncate partition p1;
--this throws ORA-00054: resource busy and acquire with NOWAIT specified
--or timeout expired
Doc on Diret-Path Insert 在这个问题上非常突然,只是说:
在直接路径插入期间,数据库获得排他锁 表(或分区表的所有分区)。因此, 用户不能执行任何并发插入、更新或删除 对表的操作,以及并发索引的创建和构建 不允许操作。
How Direct-Path INSERT Works 没有解释为什么所有分区都需要锁。 为什么传统的插入不会锁定不受影响的分区? (我的直觉是锁是在块级完成的)
【问题讨论】:
-
行级别的常规插入锁,表定义也受共享锁保护以防止其被修改。 Oracle 中没有任何块级锁,都是行、(子)分区或表级别的。
标签: sql oracle locking bulkinsert