◆データブロック単位でのデッドロックについて |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@データブロックとは? |
|
|
|
・データブロックとはOracleにおける最小レベルの記憶容量単位です。 |
|
|
特定数の連続したデータブロックのことをエクステントといい、1つ以上のエクステントの集合をセグメントといいます。 |
|
|
テーブルのデータは必ずエクステント単位で確保されます。(かなり乱暴に言えば セグメント=テーブル です。) |
|
|
|
表領域 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
エクステント |
|
|
|
|
エクステント |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
セグメント |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
エクステント |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
データブロック |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
また、データブロックのサイズは初期化パラメータファイルにて指定されたサイズとなります。(デフォルトは8K) |
|
|
以前のOracleは、確かデータブロックサイズをデータベース単位でしか設定できませんでしたが、 |
|
|
10gは表領域単位でデータブロックサイズを設定できるようです。(そのような記事をどこかで読んだ気がします。) |
|
|
|
Oracle はデータの読み込みをデータブロック単位で行うそうなので、データブロックサイズは結構重要です。 |
|
|
|
|
Aデータブロックの内部構造とITL |
|
|
|
データブロック |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ヘッダ部 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
データ部 |
|
|
|
|
データ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
データブロック |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ブロックサイズ |
|
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 を指定して空き領域を余分に取る。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
どちらの方法を取るにしても、「1つのデータブロックに登録できるデータ量が減ってしまう」 という不具合はありますが。。 |
|
|
(ブロックヘッダを最初から余分に確保してしまう為) |
|
|
|
|
以上は、私からの調査案、および解決案です。(あくまでも案です。) |
|
|
またOrace
内部構造に関しては説明を簡潔にする為に 必要最小限の事しか書いていませんがご容赦願います。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|