我想知道为什么大容量插入(带有直接路径)锁定整个表的核心原因(引擎所做的段、块、锁的机制),所以如果我插入到一个分区中,我不能截断另一个分区,它不会受到插入(显然)的影响。
传统的insert(没有附加提示)允许截断一些不受影响的分区。(请注意,我说的是非交换事务。)
下面举一个例子来稀释它。
让我们坐一张桌子:
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 expiredDoc关于Diret插入在这个问题上相当突然,只是说:
在直接路径插入期间,数据库获取表(或分区表的所有分区)上的独占锁。因此,用户无法在表上执行任何并发插入、更新或删除操作,并且不允许并发索引创建和生成操作。
直接路径插入的工作原理没有解释为什么所有分区都需要锁。以及为什么常规插入不锁定未受影响的分区?(我的直觉是锁是在块级完成的)
发布于 2013-06-04 06:11:50
你的前提有点错误。如果使用分区扩展子句,直接路径插入不会锁定整个表.
第1场会议:
insert /*+append */ into fg_test partition (p2)
select * from fg_test where col >=1000;第2场会议:
alter table fg_test truncate partition p1;
--table truncated新的问题是:当不使用分区扩展子句时,为什么常规路径插入和直接路径插入有不同的锁定机制?这一澄清使问题变得更容易,但在没有内部知识的情况下,下面的答案仍然只是猜测。
更容易编写锁定整个表的特性。而且它运行得更快,因为不需要跟踪更新了哪些分区。
通常不需要更细粒度的锁。大多数使用直接路径写入的系统或进程一次只更新一个大表.如果确实需要更细粒度的锁,则可以使用分区扩展子句。这不太方便,因为一次只能引用一个分区。但这已经足够了99.9%的时间。
发布于 2013-05-10 13:21:15
我在asktom.oracle.com上找到了如下答案:
Tom解释了许多内部工作,但是Oracle锁定整个表并不仅影响分区的原因还不清楚。
也许这只是一个设计决策(例如,不希望大的、庞大的直接负载可能被一个小的未实现的事务阻塞,从而锁定所有分区……)
https://stackoverflow.com/questions/16477377
复制相似问题