2013-05-10 10 views
7

コアの理由(エンジンのセグメント、ブロック、ロックの仕組み)を知りたいのですが、ダイレクトパスを使用してバルク挿入がテーブル全体をロックするのはなぜですかパーティションに挿入することで、(明らかに)影響を受けていない別のパーティションを切り捨てることはできません。パーティションテーブルとテーブルレベルロックへのバルク挿入

(APPENDヒントなし)従来のインサートは、いくつかのnonaffectedのパーティションを切り捨てることが可能。(私は非COMMITED取引について話すことに注意してください。)

例以下は、それをilustrateします。

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には、すべてのパーティションでロックが必要な理由が説明されていません。 従来のインサートでは影響を受けていないパーティションがロックされないのはなぜですか?私はasktom.oracle.comにfollwing答えを見つけることが

+1

従来の挿入ロックは行レベルでロックされ、テーブル定義も共有ロックによって保護され、変更が防止されます。 Oracleにはブロックレベルのロックはありません。すべての行、(サブ)パーティションまたはテーブルレベルです。 –

答えて

5

です。ダイレクト・パス・インサートは、パーティション拡張句を使用すると、表全体をロックしません。

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

新しい質問がある:パーティション拡張句を使用しない場合は、なぜ従来のダイレクト・パス・インサートは異なるロックを持っていますメカニズム?この説明によって問題は簡単になりますが、内部の知識がなければ、以下の答えはまだ推測されていません。


テーブル全体をロックする機能をコーディングする方が簡単でした。更新されるパーティションを追跡する必要がないため、実行速度が向上します。

通常、より細かいロックは必要ありません。ダイレクト・パス・ライトを使用するほとんどのシステムまたはプロセスは、一度に1つの大きな表のみを更新します。より細かいロックが本当に必要な場合は、パーティション拡張節を使用できます。一度に参照できるパーティションは1つだけなので、それほど便利ではありません。しかし、99.9%の時間で十分です。

+0

+1この素晴らしいことを知っていい(パーティション句の影響) –

+0

@JonHellerだから、パーティション拡張を使ってテーブルに直接パスを挿入すると、そのパーティションは 'COMMIT'が発行されるまでロックされます。あれは正しいですか?私は "パーティションのロック"も、私の無知を許しているのかどうかはわかりません。 – Annjawn

3

(私の直感ではロックがブロック・レベルで行われているということです):

Ask Tom: Inserts with APPEND Hint

トムは、内部の仕組みの多くを説明したが、その理由なぜ Oracleはテーブル全体をロックし、影響を受けるパーティションだけでなく、まだ明確ではありません。

多分それはあなたの前提が少し間違っているだけで設計上の決定(例えば、潜在的に1つの小さめの未コミットのトランザクションによってブロックされる大きなかさばるダイレクト・ロードを望むため、すべてのパーティションをロックしていない...)

+0

あなたの答えをありがとう。 –

関連する問題