8

主要な理由 (エンジンが行うセグメント、ブロック、ロックの仕組み) を知りたい挿入によって(明らかに)影響を受けません。

従来の挿入 (追加ヒントなし) では、影響を受けていないパーティションを切り捨てることができます (コミットされていないトランザクションについて話していることに注意してください)。

それを説明するための例を以下に示します。

テーブルにしましょう:

 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

Diret-Path InsertのDocは、この件に関してかなり唐突で、次のように述べています。

ダイレクト・パス INSERT 中、データベースは表 (またはパーティション化された表のすべてのパーティション) に対して排他ロックを取得します。その結果、ユーザーはテーブルに対して同時挿入、更新、または削除操作を実行できず、同時インデックス作成および構築操作は許可されません。

How Direct-Path INSERT Worksは、すべてのパーティションにロックが必要な理由を説明していません。また、従来の挿入では、影響を受けていないパーティションがロックされないのはなぜですか? (私の直感では、ロックはブロックレベルで行われます)

4

2 に答える 2

7

あなたの前提は少し間違っています。パーティション拡張句を使用する場合、ダイレクト パス挿入はテーブル全体をロックしません。

セッション 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

The new question is: When the partition extension clause is NOT used, why do conventional and direct-path inserts have different locking mechanisms? This clarification makes the question easier, but without inside knowledge the answer below is still only a guess.


It was easier to code a feature that locks the entire table. And it runs faster, since there is no need to track which partitions are updated.

There's usually no need for a more fine-grained lock. Most systems or processes that use direct-path writes only update one large table at a time. If a more fine-grained lock is really needed, the partition extension clause can be used. It's not quite as convenient, since only one partition can be referenced at a time. But it's good enough 99.9% of the time.

于 2013-06-04T06:11:50.467 に答える
3

asktom.oracle.com で次の回答を見つけました。

Ask Tom: APPEND ヒントを使用した挿入

Tom は内部の仕組みの多くを説明していますが、Oracle が影響を受けるパーティションだけでなくテーブル全体をロックする理由まだ明らかではありません。

多分それは単なる設計上の決定です(たとえば、大きなかさばる直接ロードが1つの小さな未コミットのトランザクションによって潜在的にブロックされることを望まないため、すべてのパーティションをロックします...)

于 2013-05-10T13:21:15.217 に答える