◆データブロック単位タンイでのデッドロックについて
@データブロックとは?
・データブロックとはOracleにおける最小サイショウレベルの記憶キオク容量ヨウリョウ単位タンイです。
 特定トクテイスウ連続レンゾクしたデータブロックのことをエクステントといい、1つ以上のエクステントの集合をセグメントといいます。
  テーブルのデータはカナラずエクステント単位タンイ確保カクホされます。(かなり乱暴ランボウえば セグメント=テーブル です。)
ヒョウ領域リョウイキ
                                 
テキスト ボックス: 「おまけ」
1番大きな容量単位は表領域(テーブルスペース)です。
この表領域には複数のセグメントを配置可能です。
つまり1つの表領域に複数のテーブルを格納する事が
可能という事です。
現在の基幹システムは
全てのテーブルを SLMS という表領域に格納しているようです。

※また表領域は論理的な領域であり
 1データファイル=1表領域とは限りません。
 Nデータファイル=1表領域 という事もありえます。
   
                   
 
 
    エクステント     エクステント    
          セグメント  
                       
    エクステント            
                       
                       
  データブロック  
                                 
また、データブロックのサイズは初期ショキパラメータファイルにて指定シテイされたサイズとなります。(デフォルトは8K)
以前のOracleは、タシかデータブロックサイズをデータベース単位タンイでしか設定セッテイできませんでしたが、
10gは表領域単位でデータブロックサイズを設定セッテイできるようです。(そのような記事キジをどこかでんだがします。)
Oracle はデータのみをデータブロック単位タンイオコナうそうなので、データブロックサイズは結構ケッコウ重要ジュウヨウです。
Aデータブロックの内部ナイブ構造コウゾウとITL
データブロック
テキスト ボックス: ITL
 
         
テキスト ボックス:  データブロックには、「ヘッダ部」、「データ部」があり(簡単にいうと)、
ヘッダ部で管理する情報の中に ITLというものがあります。

 このITL(Interested Transaction List) は、
「そのブロック内のデータをどのトランザクションが更新中か」 というデータを保持しており
全ての更新処理は ITLの割り当てをまず最初に行います。また1つのITLは1つの
トランザクションの情報しか持てません。

 ひとつのデータブロックにいくつのITLを持つかはテーブル(や索引)の作成時にINITRANS で
指定する事ができます。(初期値:1)
    ヘッダ
   
           
   
   
    データ
  データ  
   
   
           
データブロック
           
テキスト ボックス:  ITLが不足した場合、MAXTRANSの値まで自動拡張されます。
 ※MAXTRANSの初期値:255
  但しデータブロックによって拡張可能な最大値は変わるようです。
   
   
           
    ブロックサイズ ITLの最大値サイダイチ
    2k 41
りない場合バアイ     4k 84
自動ジドウ拡張カクチョウされる。   データ   8k 169
    16k 255
    32k 255
           
BITLの獲得カクトクちによるデッドロック
                       
       
                       
       
  データ     データ  
       
                       
データブロック1 データブロック2
C調査チョウサ
まず、どのテーブルで「い」が発生ハッセイしているのかめるコト必要ヒツヨウです。
といっても、データブロックはオブジェクトマイ別々ベツベツ領域リョウイキ使用シヨウされるので、一概イチガイにテーブルのみが対象タイショウとはえません。
つまり、テーブルデータ、索引サクインデータ、外部ガイブ参照サンショウデータ、などもデータブロックを使用シヨウしているとコトです。
なので、どのテーブルのどのオブジェクトの登録時にそれが発生しているかを突き止めねばなりません。
調査チョウサ@ ・・・ テーブルを特定トクテイ
どのテーブルの更新コウシン発生ハッセイしているかは、更新コウシンログをうまくればめるコトができるとオモいます。
スベての更新コウシン処理ショリ最終的サイシュウテキに Daoクラスの u_exec メソッドを使用シヨウするので、そこにログ出力シュツリョクれればハヤいとオモいます。)
調査チョウサA ・・・ テーブルオブジェクトを特定トクテイ
タトえば、在庫ザイコテーブルのシュキー制約セイヤクをはずせばデッドロックが解消カイショウされれば、T_ZAIKO_PK が使用シヨウしているデータブロックで
デッドロックが発生しているというコトになります。
スベての制約セイヤクをはずしても、まだ解消カイショウされないときはテーブルデータを登録トウロクしているデータブロックそのものでデッドロックが
起こっているとカンガえてよいとオモいます。
※うろオボえですが、たしか在庫ザイコロケーションの制約セイヤクのうちのどれかだったがします。
 充分ジュウブン調査チョウサをしていなかったので、かなり自信ジシンありませんが。
D解決カイケツアン
前述ゼンジュツしましたが、ITLが不足フソクすると通常ツウジョウ自動ジドウ拡張カクチョウされます。にもかかわらず拡張できずに「待ち」が発生していると言う事は、
データブロックナイアタラしいITLを作成サクセイするだけの領域リョウイキ不足フソクしている というコトです。
方法ホウホウ1」
・オブジェクト作成サクセイに INITRANS を指定シテイして最初から余分ヨブンにITLを確保カクホしておく。
 (制約セイヤクなどの作成サクセイにも USING INDEX を使ツカったりして指定シテイできるハズです。)
方法ホウホウ2」
・オブジェクト作成時に、PCTFREE を指定シテイして領域リョウイキ余分ヨブンる。
テキスト ボックス: Oracle はデータブロックを作成する際に、各データブロックに更新データ用の空き領域を確保します。(初期値:たぶん10%)
例えば、備考データが未入力の商品データが登録されたとします。
しばらくしてそのデータの備考欄が入力されると、そのレコードに必要な領域は増える事になりますよね。
こういう時の為に、前もって確保しているのがデータブロックの空き領域です。

空き領域はテーブルや索引の作成時に PCTFREE にて指定できます。データブロックサイズ 8K、PCTFREE 10 で作成した場合、
約 800kbの領域が更新データ用の空き領域として確保されます。通常は1レコードのサイズ、データブロックのサイズ、
データブロックのヘッダサイズ、投入されるデータ内容等を考慮して、この空き領域をテーブルや索引毎に設定します。

またこの領域は、たとえ1レコード分以上の領域が余っていても、新規レコードには使用されません。
(PCTFREE以外の部分で1レコード分の領域が確保できないときは、次のデータブロックに登録されます。)

そして、どうもこの空き領域は ITLの自動拡張時にも利用されるらしいのです。
どちらの方法ホウホウるにしても、「1つのデータブロックに登録トウロクできるデータリョウってしまう」 という不具合フグアイはありますが。。
 (ブロックヘッダを最初から余分に確保してしまう為)
以上イジョウは、ワタクシからの調査チョウサアン、および解決カイケツアンです。(あくまでもアンです。)
またOrace 内部構造に関しては説明を簡潔にする為に 必要ヒツヨウ最小限サイショウゲンコトしかいていませんがご容赦ヨウシャネガいます。