Home > 2012年06月
2012年06月 Archive
db2dartで学ぶDB2ストレージ・アーキテクチャ その3
- 2012-06-21 Thu 22:30:45
- db2
今までの記事
db2dartで学ぶDB2ストレージ・アーキテクチャ その1 表スペース内のエクステントについて
db2dartで学ぶDB2ストレージ・アーキテクチャ その2 SMPの拡張タイミングについて
DB2の表スペースの内部構造について検証している今回のシリーズも、これで3回目の更新となります。
db2dartというツールを使って、表スペースの内部構造を調べていくという、やればやるほど誰得な企画になって参りました。
でもやりかけちゃったんで、とことん突き詰めて行きたいとおもいます。
1回目の記事では、表スペースの領域確保の仕組みについて、基本的な事柄を確認しました。
それから2回目の記事では、表スペース内の空きエクステント情報を管理するSMP(スペース・マップ・ページ)が拡張されるタイミングを検証しました。
3回目の今日は、オブジェクト毎に取られるEMP(エクステント・マップ・ページ)について確認していきます。
まずは軽く復習です。
表スペースを作成した直後、コンテナー内には4つのエクステントが確保されているんでした。
そして、この表スペース内に表を作成すると、表のEMPと、データ・エクステントで2エクステントが最初に確保されます。
このEMPの中に、その表が確保したエクステントの位置情報が格納されています。
そして、最初のデータ・エクステントが一杯になると、あとは1エクステントずつデータ・エクステントを拡張していきます。
はい、ここで疑問です。
データ・エクステントが増加していくと、EMPに格納されている情報も増加します。
ということは、いつかEMPエクステントも溢れてしまうのでは?
ということでデータを増幅させて内部動作を確認してみました。
前回までと同じように、適当な表スペースを作成し、そこに表を作成し、ひたすらデータを増幅させます。
ある程度データ量が増えたら、db2dartをつかってEMPのダンプをとります。
そんで出てきた結果が以下のような感じになります。
まずこの中の、
この部分が、表を作成した時に取られた初期EMPの先頭ページ番号を表しています。
今回はエクステント・サイズが4で、1つ目に作成した表なので12ページから4ページ分がEMPエクステントです。
そして、
この部分が、EMPページのページIDと、その中に何エクステント分の情報が入っているかという情報です。
今回はページID12番には、1000個のエクステント情報があると言っています。
そして、その後ろの
が、そのEMPページで管理しているエクステントの、先頭ページ番号になります。
数えると確かに1000個ありました。
したがって、このダンプ結果の「EMP pool page: nn」のところを見ていけば、いくつEMPエクステントが取られたのかが確認できます。
さらにいうと、
「先頭EMPエクステント」の「最終ページ」
には、拡張されたEMPの位置が記録されています。
今回の先頭EMPエクステントは、ページIDが、12, 13, 14, 15 の4ページあります。
この中の最終ページ(==ページID5)の中に、拡張されたEMPがあるということです。
それが上記のダンプ結果の
の部分になります。
ここをみれば、どのくらい拡張されたのか一目で分かります。
とうことで、表毎に取られるEMP(エクステント・マップ・ページ)の位置が確認できました。
それでは次に、ページ・サイズによる違いを見てみます。
当然ページ・サイズが大きくなれば、1つのEMPページで、より多くの情報が格納できるはず。
ということで、各ページ・サイズで表スペースを作成し、データを増幅してダンプをとります。
やることは上と同じなので割愛。
結果としてはこうなりました。
このEMPも、領域見積もりの結果に1割くらい多めにしておけば十分に吸収できるサイズでしょう。
ただ、厳密にシビアな見積りが必要な場合には、当然考慮する必要があります。
※この検証は9.1で実施しており、新しいバージョンでは動作が違う可能性があります。
では今回はここまで。
次回からはINDEXのエクステントのとり方を検証してみたいと思っています。
db2dartで学ぶDB2ストレージ・アーキテクチャ その1 表スペース内のエクステントについて
db2dartで学ぶDB2ストレージ・アーキテクチャ その2 SMPの拡張タイミングについて
DB2の表スペースの内部構造について検証している今回のシリーズも、これで3回目の更新となります。
db2dartというツールを使って、表スペースの内部構造を調べていくという、やればやるほど誰得な企画になって参りました。
でもやりかけちゃったんで、とことん突き詰めて行きたいとおもいます。
1回目の記事では、表スペースの領域確保の仕組みについて、基本的な事柄を確認しました。
それから2回目の記事では、表スペース内の空きエクステント情報を管理するSMP(スペース・マップ・ページ)が拡張されるタイミングを検証しました。
3回目の今日は、オブジェクト毎に取られるEMP(エクステント・マップ・ページ)について確認していきます。
まずは軽く復習です。
表スペースを作成した直後、コンテナー内には4つのエクステントが確保されているんでした。
エクステントID 開始ページ番号 終了ページ番号 役割
------------------------------------------------------
なし なし なし コンテナー・タグ
0 0 3 表スペース・ヘッダー
1 4 7 SMP(スペース・マップ・ページ)
2 8 11 オブジェクト表データ
そして、この表スペース内に表を作成すると、表のEMPと、データ・エクステントで2エクステントが最初に確保されます。
エクステントID 開始ページ番号 終了ページ番号 役割
------------------------------------------------------
なし なし なし コンテナー・タグ
0 0 3 表スペース・ヘッダー
1 4 7 SMP(スペース・マップ・ページ)
2 8 11 オブジェクト表データ
3 12 15 表のEMP
4 16 19 表のデータエクステント
このEMPの中に、その表が確保したエクステントの位置情報が格納されています。
そして、最初のデータ・エクステントが一杯になると、あとは1エクステントずつデータ・エクステントを拡張していきます。
エクステントID 開始ページ番号 終了ページ番号 役割
------------------------------------------------------
なし なし なし コンテナー・タグ
0 0 3 表スペース・ヘッダー
1 4 7 SMP(スペース・マップ・ページ)
2 8 11 オブジェクト表データ
3 12 15 表のEMP
4 16 19 表のデータエクステント
5 20 23 表のデータエクステント
・・・・
はい、ここで疑問です。
データ・エクステントが増加していくと、EMPに格納されている情報も増加します。
ということは、いつかEMPエクステントも溢れてしまうのでは?
ということでデータを増幅させて内部動作を確認してみました。
前回までと同じように、適当な表スペースを作成し、そこに表を作成し、ひたすらデータを増幅させます。
ある程度データ量が増えたら、db2dartをつかってEMPのダンプをとります。
db2dart <DB名> /DEMP /OI <オブジェクトID> /TSI <表スペースID>
そんで出てきた結果が以下のような感じになります。
Object specific mapping info:
-----------------------------
DAT extent anchor: 12
Traversing extent map for object type: 0
Pool: 7, Object: 4 EMP page class: 64,
EMP pool page: 12, # entries: 1000
Page LSN = 0001 3B37 FE46
Pool relative page #'s :
16 20 24 28 32
36 40 44 48 52
56 60 64 68 72
〜〜中略〜〜
3956 3960 3964 3968 3972
3976 3980 3984 3988 3992
3996 4000 4004 4008 4012
Pool: 7, Object: 4 EMP page class: 64,
EMP pool page: 13, # entries: 1000
Page LSN = 0001 3BF7 4AF2
Pool relative page #'s :
4016 4020 4024 4028 4032
4036 4040 4044 4048 4052
〜〜中略〜〜
7976 7980 7984 7988 7992
7996 8000 8004 8008 8012
Pool: 7, Object: 4 EMP page class: 64,
EMP pool page: 14, # entries: 1000
Page LSN = 0001 3CB6 979E
Pool relative page #'s :
8016 8020 8024 8028 8032
8036 8040 8044 8048 8052
〜〜中略〜〜
11976 11980 11984 11988 11992
11996 12000 12004 12008 12012
Pool: 7, Object: 4 EMP page class: 64,
EMP pool page: 15, # entries: 32
Page LSN = 0001 9963 2E43
Pool relative page #'s :
12016 28020 44024 60028 76032
92036 108040 124044 140052 156056
172060 188064 204068 220072 236076
252080 268088 284092 300096 316100
332104 348108 364112 380116 396124
412128 428132 444136 460140 476144
492148 508152
Pool: 7, Object: 4 EMP page class: 64,
EMP pool page: 12016, # entries: 1000
Page LSN = 0001 3D75 E4E6
Pool relative page #'s :
12020 12024 12028 12032 12036
12040 12044 12048 12052 12056
〜〜後略〜〜
まずこの中の、
DAT extent anchor: 12
この部分が、表を作成した時に取られた初期EMPの先頭ページ番号を表しています。
今回はエクステント・サイズが4で、1つ目に作成した表なので12ページから4ページ分がEMPエクステントです。
そして、
EMP pool page: 12, # entries: 1000
この部分が、EMPページのページIDと、その中に何エクステント分の情報が入っているかという情報です。
今回はページID12番には、1000個のエクステント情報があると言っています。
そして、その後ろの
Pool relative page #'s :
16 20 24 28 32
36 40 44 48 52
56 60 64 68 72
〜〜中略〜〜
3956 3960 3964 3968 3972
3976 3980 3984 3988 3992
3996 4000 4004 4008 4012
が、そのEMPページで管理しているエクステントの、先頭ページ番号になります。
数えると確かに1000個ありました。
したがって、このダンプ結果の「EMP pool page: nn」のところを見ていけば、いくつEMPエクステントが取られたのかが確認できます。
さらにいうと、
「先頭EMPエクステント」の「最終ページ」
には、拡張されたEMPの位置が記録されています。
今回の先頭EMPエクステントは、ページIDが、12, 13, 14, 15 の4ページあります。
この中の最終ページ(==ページID5)の中に、拡張されたEMPがあるということです。
それが上記のダンプ結果の
EMP pool page: 15, # entries: 32
Page LSN = 0001 9963 2E43
Pool relative page #'s :
12016 28020 44024 60028 76032
92036 108040 124044 140052 156056
172060 188064 204068 220072 236076
252080 268088 284092 300096 316100
332104 348108 364112 380116 396124
412128 428132 444136 460140 476144
492148 508152
の部分になります。
ここをみれば、どのくらい拡張されたのか一目で分かります。
とうことで、表毎に取られるEMP(エクステント・マップ・ページ)の位置が確認できました。
それでは次に、ページ・サイズによる違いを見てみます。
当然ページ・サイズが大きくなれば、1つのEMPページで、より多くの情報が格納できるはず。
ということで、各ページ・サイズで表スペースを作成し、データを増幅してダンプをとります。
やることは上と同じなので割愛。
結果としてはこうなりました。
・表の作成時に、初期EMPエクステントが確保される
・初期EMPエクステントの最終ページには、拡張したEMPエクステントの位置が記録される
・ページサイズが4Kの場合、EMP1ページにつき、1000エクステントが管理できる
・ページサイズが8Kの場合、EMP1ページにつき、2026エクステントが管理できる
・ページサイズが16Kの場合、EMP1ページにつき、4074エクステントが管理できる
・ページサイズが32Kの場合、EMP1ページにつき、8170エクステントが管理できる
このEMPも、領域見積もりの結果に1割くらい多めにしておけば十分に吸収できるサイズでしょう。
ただ、厳密にシビアな見積りが必要な場合には、当然考慮する必要があります。
※この検証は9.1で実施しており、新しいバージョンでは動作が違う可能性があります。
では今回はここまで。
次回からはINDEXのエクステントのとり方を検証してみたいと思っています。
db2dartで学ぶDB2ストレージ・アーキテクチャ その2
- 2012-06-06 Wed 23:56:27
- db2
前回の記事はこちら
db2dartで学ぶDB2ストレージ・アーキテクチャ その1 表スペース内のエクステントについて
db2dartで学ぶDB2ストレージ・アーキテクチャ その2 SMPの拡張タイミングについて
前回はDB2の表スペースの基本的な概念を確認した上で、コンテナー上にエクステントが取られていく様子を確認しました。
今回は、表スペースのいわばヘッダー領域として取られる"コンテナー・タグ"、”表スペース・ヘッダー”、"SMP(スペース・マップ・ページ)"、"オブジェクト表データ"のうち、SMPの挙動について確認します。
SMP(スペース・マップ・ページ)
参考:http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp?topic=%2Fcom.ibm.db2.luw.admin.dbobj.doc%2Fdoc%2Fc0008085.html
SMPは、DB2が新たにエクステントを確保しようとした際に、表スペースのどの位置が空きエクステントなのかを判別するために使用される情報を持っている。らしい。
表スペースの作成直後の状態(以下)では、空きエクステント情報のためのエクステントが1つ取られている。
だとすると、エクステントの数が増えていくことでSMP内の情報も多くなり、やがてあふれることになるはず。
ということで、何エクステントごとにSMPエクステントが拡張されるのか試してみました。
やった内容は前回と同じで、
1.表スペース作成
2.表作成
3.ひたすらデータ増幅
4.頃合いを見てdb2dart
という流れです。
SMPの情報は以下のオプションで取得できます。
DはdumpのDかな?
TSがTableSpaceで、Fはなんだろう。
Formatかな。Fileかな。
まぁとにかくデータを増幅して、ひたすらエクステントを拡張しながら何か変化がでるまでdb2dartのレポートを見ていきます。
表スペースの作成直後
まず、表スペースを作成した直後のレポートをみると、こんな部分が見つかりました。
今回はextentsizeを4ページで作成しているため、上で書いたようにページ番号4からSMPがあるはずです。
そして、4番から始まったSMPエクステントの最終ページ番号は7になるので、上記レポートの内容と一致します。
更に、「SMP extent number of the last initialized SMP extent: 0」の通り、まだSMPエクステントは、初期にとられた1つしかないということも確認できます。
データ増幅後
では、ひたすらデータを追加していき、db2dartのレポートに変化がでるまで続けます。
あまりこまめに繰り返してもかったるいので、データを追加するスクリプトを流しつつ、15分おきくらいに様子をみていたところ、レポートに次のような出力がでてきました。
「SMP extent number of the last initialized SMP extent: 4」は、SMPエクステントが4回拡張されたということになるはず。
うっかりデータ増幅を放置しすぎて、いつの間にか拡張を繰り返していたようです。
途中のSMPエクステントがどこなのか、今の時点ではわかりませんが、下記のような状態になっているということです。
この/DTSFオプションにより、最後にあるSMPの位置は確認できるが、途中にあるSMPについては確認できません。
これを判別するために、次のようなことを考えました。
今、表スペースに格納されているオブジェクトは表が1つのみ。
ということは、表のエクステント・マップを出力すれば、それ以外のエクステントがSMPである可能性が高いのでは?
ということで、さっそく表のエクステント・マップを出力します。
表のエクステント・マップの出力方法は前回の記事で書いた通り。
で、その結果が以下のようなものになります。
エクステントが多すぎてページ番号が偉い桁数になってますが、とりあえずは出ました。
で、目視で抜けたエクステントを探すのはしんどいので、抜けを探すスクリプトで可視化しました。
ここで「EMP」と表示しているのは、表のエクステント・マップ情報をもつEMPエクステントのエクステント番号。
「OTHER」としているのが、表のデータおよびEMPエクステント以外のエクステントです。
つまり結果として、32000, 64000, 9600, 12800 の4つが表以外のエクステントであることが分かる。
SMPエクステントの拡張タイミング
上記の結果から、まだ確証は無いが、おそらく32000エクステント毎にSMPが拡張していることが予測できた。
この32000という数値の根拠を調査するために、SPMエクステントのページ・ダンプを出力して中身を見てみることにする。
ページ・ダンプの取得は/DPオプションを使用する。
ページ番号4から4ページ分(初期SMPエクステント)のページ・ダンプを確認すると、各ページ毎に、0050の行の17ビットから、0FF0の行の16ビットまでほぼ全てに1が立っている。
それに対し、512000番から4ページ分(最終SPMエクステント)のページ・ダンプでは、0050の行の17ビット目から1が立っているのは変わらないが、0470の行から0になっている。
このことから、0050の17ビット移行、0FF0の16ビットまでが、エクステントの空きを表しているのではないかと仮説を立ててみる。
この仮説を確認するために、上記ビットの数を確認すると、0050の17ビット〜0FF0の16までで、8000ビットある。
現在のエクステントサイズは1エクステント4ページなので、1つのSPMエクステントで、8000*4=32000エクステントが管理できることになる。
この数値は、上で確認したSPMエクステントの拡張タイミングと一致する。
したがって、ページサイズが4Kの場合、8000*エクステントサイズ(ページ数)毎に、SPMエクステントが拡張されることがわかった。
で、そうなると、当然ページサイズが異なれば、1ページで管理できるビット数も変わるはず。
ページサイズが8K,16K32Kの場合ではどうなるのか、同様の手順でダンプを取りながら確認した。
作業の流れは同じなので、途中経過は割愛するけど、結果として以下のタイミングでSMPエクステントが拡張されることを確認できた。
ページサイズによるSMPエクステントの拡張タイミング
SMPエクステントの拡張タイミングは以下の通り。
そんなわけで、表スペースには、表や索引のエクステント以外のものがちょくちょく取られることが確認できました。
領域見積もりの際には、一応考慮に入れておくべきかなぁとは思いますが、全体のサイズからすると誤差みたいなもんなんで、通常良く言われる「見積もり結果より1割程度大きめにとっとこうね」で十分だと思います。
それよりも、今回の検証の中で表のデータエクステント以外を洗い出してみたところ、表のEMP(エクステント・マップ・ページ)が結構な頻度で拡張していることがわかりました。
多分こっちのほうが見積もりに与える影響が大きそうなので、次回はEMPの拡張タイミングを探って行きたいと思います。
いやー、それにしてもプロプラな製品のダンプを見ながら解析するのって楽しいですね。
とくにページ・ダンプは色々みれて面白いです。
後で別エントリーにする予定ですが、例えば索引のエクステントって、複数索引で同じエクステントに同居してたりとか、ルート・ページがどうやら共有されているっぽいとか。
ちょっとまだ調査中ですけど、色々と見えてくるものがあってしばらくはこれで遊べそうです。
それではまた次回まで。
※このエントリーは個人の見解であり、内容の正確性の保証はありません。
間違いなど見つけられた場合はコメントなど頂けると助かります。
db2dartで学ぶDB2ストレージ・アーキテクチャ その1 表スペース内のエクステントについて
db2dartで学ぶDB2ストレージ・アーキテクチャ その2 SMPの拡張タイミングについて
前回はDB2の表スペースの基本的な概念を確認した上で、コンテナー上にエクステントが取られていく様子を確認しました。
今回は、表スペースのいわばヘッダー領域として取られる"コンテナー・タグ"、”表スペース・ヘッダー”、"SMP(スペース・マップ・ページ)"、"オブジェクト表データ"のうち、SMPの挙動について確認します。
SMP(スペース・マップ・ページ)
参考:http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp?topic=%2Fcom.ibm.db2.luw.admin.dbobj.doc%2Fdoc%2Fc0008085.html
SMPは、DB2が新たにエクステントを確保しようとした際に、表スペースのどの位置が空きエクステントなのかを判別するために使用される情報を持っている。らしい。
表スペースの作成直後の状態(以下)では、空きエクステント情報のためのエクステントが1つ取られている。
エクステントID 開始ページ番号 終了ページ番号 役割
------------------------------------------------------
なし なし なし コンテナー・タグ
0 0 3 表スペース・ヘッダー
1 4 7 SMP(スペース・マップ・ページ)
2 8 11 オブジェクト表データ
だとすると、エクステントの数が増えていくことでSMP内の情報も多くなり、やがてあふれることになるはず。
ということで、何エクステントごとにSMPエクステントが拡張されるのか試してみました。
やった内容は前回と同じで、
1.表スペース作成
2.表作成
3.ひたすらデータ増幅
4.頃合いを見てdb2dart
という流れです。
SMPの情報は以下のオプションで取得できます。
db2dart <DB名> /DTSF
DはdumpのDかな?
TSがTableSpaceで、Fはなんだろう。
Formatかな。Fileかな。
まぁとにかくデータを増幅して、ひたすらエクステントを拡張しながら何か変化がでるまでdb2dartのレポートを見ていきます。
表スペースの作成直後
まず、表スペースを作成した直後のレポートをみると、こんな部分が見つかりました。
SMP page for first free extent: 4 -- 初期SMPの先頭ページ番号
SMP page for last allocated tablespace extent. 7 -- 直近で獲得されたSMPの最後のページ番号
SMP extent number of the last initialized SMP extent: 0 -- SMPエクステントが拡張された回数
今回はextentsizeを4ページで作成しているため、上で書いたようにページ番号4からSMPがあるはずです。
そして、4番から始まったSMPエクステントの最終ページ番号は7になるので、上記レポートの内容と一致します。
更に、「SMP extent number of the last initialized SMP extent: 0」の通り、まだSMPエクステントは、初期にとられた1つしかないということも確認できます。
データ増幅後
では、ひたすらデータを追加していき、db2dartのレポートに変化がでるまで続けます。
あまりこまめに繰り返してもかったるいので、データを追加するスクリプトを流しつつ、15分おきくらいに様子をみていたところ、レポートに次のような出力がでてきました。
SMP page for first free extent: 4
SMP page for last allocated tablespace extent. 512003
SMP extent number of the last initialized SMP extent: 4
「SMP extent number of the last initialized SMP extent: 4」は、SMPエクステントが4回拡張されたということになるはず。
うっかりデータ増幅を放置しすぎて、いつの間にか拡張を繰り返していたようです。
途中のSMPエクステントがどこなのか、今の時点ではわかりませんが、下記のような状態になっているということです。
ページサイズ:4k、エクステント・サイズ:4ページの場合
エクステントID 開始ページ番号 終了ページ番号 役割
------------------------------------------------------
なし なし なし コンテナー・タグ
0 0 3 表スペース・ヘッダー
1 4 7 SMP(スペース・マップ・ページ)
2 8 11 オブジェクト表データ
3 12 15 big_tab1のEMP
4 16 19 big_tab1のデータエクステント
5 20 23 big_tab2のデータエクステント
〜〜中略〜〜
不明 不明 不明 2つ目のSPMエクステント
〜〜中略〜〜
不明 不明 不明 3つ目のSPMエクステント
〜〜中略〜〜
不明 不明 不明 4つ目のSPMエクステント
〜〜中略〜〜
128000 512000 512003 5つ目のSPMエクステント
〜〜後略〜〜
------------------------------------------------------
この/DTSFオプションにより、最後にあるSMPの位置は確認できるが、途中にあるSMPについては確認できません。
これを判別するために、次のようなことを考えました。
今、表スペースに格納されているオブジェクトは表が1つのみ。
ということは、表のエクステント・マップを出力すれば、それ以外のエクステントがSMPである可能性が高いのでは?
ということで、さっそく表のエクステント・マップを出力します。
表のエクステント・マップの出力方法は前回の記事で書いた通り。
db2dart <DB名> /DEMP /OI <表のオブジェクトID> /TSI <表スペースID>
で、その結果が以下のようなものになります。
Object specific mapping info:
-----------------------------
DAT extent anchor: 12
Traversing extent map for object type: 0
Pool: 7, Object: 4 EMP page class: 64,
EMP pool page: 12, # entries: 1000
Page LSN = 0001 3B37 FE46
Pool relative page #'s :
16 20 24 28 32
36 40 44 48 52
〜〜中略〜〜
520380 520384 520388 520392 520396
520400 520404 520408 520412 520416
520420 520424
エクステントが多すぎてページ番号が偉い桁数になってますが、とりあえずは出ました。
で、目視で抜けたエクステントを探すのはしんどいので、抜けを探すスクリプトで可視化しました。
-- *** EMP and Other Extents ***
-- ExtentId:3 EMP
-- ExtentId:3004 EMP
-- ExtentId:7005 EMP
-- ExtentId:11006 EMP
-- ExtentId:15007 EMP
-- ExtentId:19008 EMP
-- ExtentId:23009 EMP
-- ExtentId:27010 EMP
-- ExtentId:31011 EMP
-- Extent Id:32000 OTHER
-- ExtentId:35013 EMP
-- ExtentId:39014 EMP
-- ExtentId:43015 EMP
-- ExtentId:47016 EMP
-- ExtentId:51017 EMP
-- ExtentId:55018 EMP
-- ExtentId:59019 EMP
-- ExtentId:63020 EMP
-- Extent Id:64000 OTHER
-- ExtentId:67022 EMP
-- ExtentId:71023 EMP
-- ExtentId:75024 EMP
-- ExtentId:79025 EMP
-- ExtentId:83026 EMP
-- ExtentId:87027 EMP
-- ExtentId:91028 EMP
-- ExtentId:95029 EMP
-- Extent Id:96000 OTHER
-- ExtentId:99031 EMP
-- ExtentId:103032 EMP
-- ExtentId:107033 EMP
-- ExtentId:111034 EMP
-- ExtentId:115035 EMP
-- ExtentId:119036 EMP
-- ExtentId:123037 EMP
-- ExtentId:127038 EMP
-- Extent Id:128000 OTHER
ここで「EMP」と表示しているのは、表のエクステント・マップ情報をもつEMPエクステントのエクステント番号。
「OTHER」としているのが、表のデータおよびEMPエクステント以外のエクステントです。
つまり結果として、32000, 64000, 9600, 12800 の4つが表以外のエクステントであることが分かる。
SMPエクステントの拡張タイミング
上記の結果から、まだ確証は無いが、おそらく32000エクステント毎にSMPが拡張していることが予測できた。
この32000という数値の根拠を調査するために、SPMエクステントのページ・ダンプを出力して中身を見てみることにする。
ページ・ダンプの取得は/DPオプションを使用する。
db2dart <DB名> /DP /TSI <表スペースID> /PS <開始ページ番号> /NP <ページ数>
ページ番号4から4ページ分(初期SMPエクステント)のページ・ダンプを確認すると、各ページ毎に、0050の行の17ビットから、0FF0の行の16ビットまでほぼ全てに1が立っている。
0050 *00000000 00000000 11111111 11111111
0FF0 *11111111 11111111 00000000 00000000
それに対し、512000番から4ページ分(最終SPMエクステント)のページ・ダンプでは、0050の行の17ビット目から1が立っているのは変わらないが、0470の行から0になっている。
0470 *11111111 00001011 00000000 00000000* *................*
このことから、0050の17ビット移行、0FF0の16ビットまでが、エクステントの空きを表しているのではないかと仮説を立ててみる。
この仮説を確認するために、上記ビットの数を確認すると、0050の17ビット〜0FF0の16までで、8000ビットある。
現在のエクステントサイズは1エクステント4ページなので、1つのSPMエクステントで、8000*4=32000エクステントが管理できることになる。
この数値は、上で確認したSPMエクステントの拡張タイミングと一致する。
したがって、ページサイズが4Kの場合、8000*エクステントサイズ(ページ数)毎に、SPMエクステントが拡張されることがわかった。
で、そうなると、当然ページサイズが異なれば、1ページで管理できるビット数も変わるはず。
ページサイズが8K,16K32Kの場合ではどうなるのか、同様の手順でダンプを取りながら確認した。
作業の流れは同じなので、途中経過は割愛するけど、結果として以下のタイミングでSMPエクステントが拡張されることを確認できた。
ページサイズによるSMPエクステントの拡張タイミング
SMPエクステントの拡張タイミングは以下の通り。
ページサイズ 管理エクステント数
-----------------------------------------------
4K 8000 * エクステントサイズ
8K 16208 * エクステントサイズ
16K 32592 * エクステントサイズ
32K 65360 * エクステントサイズ
そんなわけで、表スペースには、表や索引のエクステント以外のものがちょくちょく取られることが確認できました。
領域見積もりの際には、一応考慮に入れておくべきかなぁとは思いますが、全体のサイズからすると誤差みたいなもんなんで、通常良く言われる「見積もり結果より1割程度大きめにとっとこうね」で十分だと思います。
それよりも、今回の検証の中で表のデータエクステント以外を洗い出してみたところ、表のEMP(エクステント・マップ・ページ)が結構な頻度で拡張していることがわかりました。
多分こっちのほうが見積もりに与える影響が大きそうなので、次回はEMPの拡張タイミングを探って行きたいと思います。
いやー、それにしてもプロプラな製品のダンプを見ながら解析するのって楽しいですね。
とくにページ・ダンプは色々みれて面白いです。
後で別エントリーにする予定ですが、例えば索引のエクステントって、複数索引で同じエクステントに同居してたりとか、ルート・ページがどうやら共有されているっぽいとか。
ちょっとまだ調査中ですけど、色々と見えてくるものがあってしばらくはこれで遊べそうです。
それではまた次回まで。
※このエントリーは個人の見解であり、内容の正確性の保証はありません。
間違いなど見つけられた場合はコメントなど頂けると助かります。
db2dartで学ぶDB2ストレージ・アーキテクチャ その1
- 2012-06-03 Sun 17:15:44
- db2
db2dartで学ぶDB2ストレージ・アーキテクチャ その1 表スペース内のエクステントについて
db2dartで学ぶDB2ストレージ・アーキテクチャ その2 SMPの拡張タイミングについて
最近、DB2絡みのお仕事が回ってきているので暇を見つけて勉強しております。
その中で、DB2がエクステントを確保する仕組みについて、いくつか気になる点があったので調べてみました。
そして、調べていく過程でdb2dartというツールの存在を知り、さらに色々と掘り下げてみたところ他社製品(というかORACLE)とは領域の扱い方が違う点などを発見できたので、少しずつまとめてみたいと思います。
とりあえず、基本的なエクステント管理の仕組みについて確認したあとで、内部のエクステント・マップを確認する方法などを紹介したいと思っています。
多分、1回のエントリーでは書ききれないので、複数回になる予定です。
ということで、今回は「その1」としました。
では、以下から本題です。
DB2の表スペース
Oracleなど表領域、テーブルスペースといった呼び方になりますが、DB2の文化圏では「表スペース」と呼ばれています。
基本的な概念はOracleと同じで、"表スペース"という論理構造に対し、"コンテナー"という物理構造を割り当て、データを格納するために使用するというものですね。
"コンテナー"という言い方なのは、ファイルだけでなく、デバイスやディレクトリも使用できるため、「データファイル」とは呼ばずに"コンテナー"になります。

SMSとDMS
で、この表スペースは大きく2種類に分類ができて、「SMS表スペース」と「DMS表スペース」になります。
SMSは、コンテナーとしてディレクトリを使用し、領域管理はOSに投げっぱなしとなります。
DMSはDB2が領域管理を行い、コンテナーとしてデータファイルまたはデバイスが使用できます。
SMSの場合、この後書く予定の内部動作がかなり違っていますのでご了承ください。
今回はDMSを前提として調査を行なっています。
ページ、エクステント、コンテナー
最初に基本的な用語を確認しておきます。
DB2も他の製品と同じように、I/Oの最小単位は「ページ」になります。
Oracleでは「データ・ブロック」と呼んでいるものですね。
ページ・サイズは表スペース毎に指定が可能で、それぞれ4K, 8K, 16K, 32K のいずれかになります。
デフォルトは4Kです。
そして、このページが連続する1つの固まりがエクステントになります。
エクステントは、表スペース内で、オブジェクトに領域が割り当てられる際の単位となり、デフォルトでは1エクステント32ページになります。
コンテナーは、表スペースに割り当てられたデータファイル、あるいはデバイスなどのことになります。
ということで、マニュアルでいうとこちら(http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp?topic=%2Fcom.ibm.db2.luw.admin.dbobj.doc%2Fdoc%2Fc0004939.html&resultof=%22SMP%22%20%22smp%22%20)にひと通りの説明があります。
エクステント・マップの確認(db2dart)
この中に色々と気になる点があるのですが、とりあえず最初の疑問点として、エクステントの状態を確認できないのか?ということです。
Oracleでは、dba_segments や db_extents を検索することで、オブジェクト毎のエクステントの位置が確認できます。
db2でも、
を叩くことで、表スペース内にエクステントがいくつ確保され、あと何ページの空きがあるのかということはわかりますが、表毎にエクステントが連続領域に取られているのか、断片化しているのかということは、このコマンドでは判別できません。
そこで、エクステントの状態を確認する方法がないかマニュアルを漁ってみると、db2dartというツールを見つけました。
http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp?topic=%2Fcom.ibm.db2.luw.admin.cmd.doc%2Fdoc%2Fr0003477.html&resultof=%22db2dart%22%20
このツールは、コンテナーのファイルが壊れていないかを検査できる、ということなのですが、それ以外に表スペースの情報やページなどをダンプとして吐き出す機能を持っています。
マニュアルにはあまり詳しい説明がないので、試行錯誤しながらの調査でしたが、こいつを使ってエクステント・マップを確認することができました。
とりあえず使い方、構文です。
・DB別名:接続先のDBの名前を指定(ちょっと不正確な言い方ですがとりあえず)
・DEMP:表のEMP(エクステント・マップ・ページ)をダンプする
・/OI:表のオブジェクトIDを指定
・/TSI:表スペースのIDを指定
表のオブジェクトIDと表スペースIDは以下のSQLで予め確認しておくこと。
サンプルコード
-- 表スペース作成
db2 "create large tablespace spmtbs managed by database using(file 'spmtbs.dat' 10000) autoresize yes extentsize 4"
-- 表作成
db2 "create table big_tab1(a varchar(3000)) in spmtbs"
-- データ増幅
db2 "insert into big_tab1 values('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')"
db2 "update big_tab1 set a = replace(a, 'a', 'aaaaaaaaaa')"
db2 "update big_tab1 set a = replace(a, 'a', 'aaaaaaaaaa')"
db2 "insert into big_tab1 select * from big_tab1" -- 2 rows
db2 "insert into big_tab1 select * from big_tab1" -- 4 rows
・・・
-- db2dart実行
db2 terminate
db2dart sample /DEMP /OI 4 /TSI 7
解説
今回は1エクステント4ページの表スペースを作成しました。
表スペースを作成した時点で、内部では4つのエクステントが取られています。
コンテナー毎に、1エクステントのヘッダー領域が取られます。
でも、list tablespaces show detail やその他表スペース関連の情報を取得するコマンドでは、このコンテナー・タグの情報は出力されません。
問答無用で1エクステント削られます。
更に言うと、各エクステントには、エクステントIDが振られていますが、コンテナー・タグには割り振られません。そして、コンテナー内のページにもページIDが振られますが、コンテナー・タグの持つページにはIDがありません。
その後ろに来るのが表スペースのヘッダー情報。
その後ろが、SMP(スペース・マップ・ページ)で、これは表スペース内の空きエクステントの情報を持っています。(後ほどコレについても検証する予定)
オブジェクト表データというのは、この表スペース内に格納されているオブジェクトの情報を持つエクステント。
ということで、4エクステントが取られているわけです。
そんで、表スペースの中に表を1つ作成すると、表のヘッダーエクステントと、データ用のエクステントの2つが最初に取られます。
このヘッダーのエクステントが、EMP(エクステント・マップ・ページ)で、表のエクステント・マップが格納されているらしいです。
そして表のデータを増やしていき、最初に確保したデータエクステントが満タンになると、1エクステントずつ拡張していきます。
db2dart /DEMP の結果を見ていきます。
まず、ここが該当する表の最初に確保したEMPエクステントの開始ページ番号です。
今回は12番のページで始まるエクステントが、最初のEMPエクステントであることがわかります。
Poolが表スペースのID、Object: 4 が表のID
12番のページから始まるEMPには、エクステント情報が1000個格納されているという意味。
ココらへんはまた後で詳しく検証する予定。
ここに並んでいる数値が、この表のエクステントの開始ページ番号を表しています。
ということで、ここを見ればエクステントの配置がわかるということになります。
エクステント・マップを見たからどうだ、という話ではありませんが、これが確認できるとマニュアルに載っている様々な内部動作を、実際に確認し検証できます。
例えば、表スペース内の空きエクステント情報が入るSMPが溢れたら、どのように拡張されるのか。
今確認したEMPが溢れたらどうなるか。
ページ・サイズによって管理できるエクステント数は変わるのか。などなど…
そんなわけで、今後数回に渡りdb2dartを使って領域の使われ方を確認してきます。
あ、今回はdb2の9.1で検証しているのですが、バージョンによって内部構造は変わる可能性があります。
それと、9.1は既にサポート切れなので使用する際はご注意を。
それと、本ブログの内容は、あくまで個人的な見解ですのでご理解を。
db2dartで学ぶDB2ストレージ・アーキテクチャ その2 SMPの拡張タイミングについて
最近、DB2絡みのお仕事が回ってきているので暇を見つけて勉強しております。
その中で、DB2がエクステントを確保する仕組みについて、いくつか気になる点があったので調べてみました。
そして、調べていく過程でdb2dartというツールの存在を知り、さらに色々と掘り下げてみたところ他社製品(というかORACLE)とは領域の扱い方が違う点などを発見できたので、少しずつまとめてみたいと思います。
とりあえず、基本的なエクステント管理の仕組みについて確認したあとで、内部のエクステント・マップを確認する方法などを紹介したいと思っています。
多分、1回のエントリーでは書ききれないので、複数回になる予定です。
ということで、今回は「その1」としました。
では、以下から本題です。
DB2の表スペース
Oracleなど表領域、テーブルスペースといった呼び方になりますが、DB2の文化圏では「表スペース」と呼ばれています。
基本的な概念はOracleと同じで、"表スペース"という論理構造に対し、"コンテナー"という物理構造を割り当て、データを格納するために使用するというものですね。
"コンテナー"という言い方なのは、ファイルだけでなく、デバイスやディレクトリも使用できるため、「データファイル」とは呼ばずに"コンテナー"になります。

SMSとDMS
で、この表スペースは大きく2種類に分類ができて、「SMS表スペース」と「DMS表スペース」になります。
SMSは、コンテナーとしてディレクトリを使用し、領域管理はOSに投げっぱなしとなります。
DMSはDB2が領域管理を行い、コンテナーとしてデータファイルまたはデバイスが使用できます。
SMSの場合、この後書く予定の内部動作がかなり違っていますのでご了承ください。
今回はDMSを前提として調査を行なっています。
ページ、エクステント、コンテナー
最初に基本的な用語を確認しておきます。
DB2も他の製品と同じように、I/Oの最小単位は「ページ」になります。
Oracleでは「データ・ブロック」と呼んでいるものですね。
ページ・サイズは表スペース毎に指定が可能で、それぞれ4K, 8K, 16K, 32K のいずれかになります。
デフォルトは4Kです。
そして、このページが連続する1つの固まりがエクステントになります。
エクステントは、表スペース内で、オブジェクトに領域が割り当てられる際の単位となり、デフォルトでは1エクステント32ページになります。
コンテナーは、表スペースに割り当てられたデータファイル、あるいはデバイスなどのことになります。
ということで、マニュアルでいうとこちら(http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp?topic=%2Fcom.ibm.db2.luw.admin.dbobj.doc%2Fdoc%2Fc0004939.html&resultof=%22SMP%22%20%22smp%22%20)にひと通りの説明があります。
エクステント・マップの確認(db2dart)
この中に色々と気になる点があるのですが、とりあえず最初の疑問点として、エクステントの状態を確認できないのか?ということです。
Oracleでは、dba_segments や db_extents を検索することで、オブジェクト毎のエクステントの位置が確認できます。
db2でも、
db2 list tablespaces show detail
を叩くことで、表スペース内にエクステントがいくつ確保され、あと何ページの空きがあるのかということはわかりますが、表毎にエクステントが連続領域に取られているのか、断片化しているのかということは、このコマンドでは判別できません。
そこで、エクステントの状態を確認する方法がないかマニュアルを漁ってみると、db2dartというツールを見つけました。
http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/index.jsp?topic=%2Fcom.ibm.db2.luw.admin.cmd.doc%2Fdoc%2Fr0003477.html&resultof=%22db2dart%22%20
このツールは、コンテナーのファイルが壊れていないかを検査できる、ということなのですが、それ以外に表スペースの情報やページなどをダンプとして吐き出す機能を持っています。
マニュアルにはあまり詳しい説明がないので、試行錯誤しながらの調査でしたが、こいつを使ってエクステント・マップを確認することができました。
とりあえず使い方、構文です。
db2dart <DB別名> /DEMP /OI <オブジェクトID> /TSI <表スペースID>
・DB別名:接続先のDBの名前を指定(ちょっと不正確な言い方ですがとりあえず)
・DEMP:表のEMP(エクステント・マップ・ページ)をダンプする
・/OI:表のオブジェクトIDを指定
・/TSI:表スペースのIDを指定
表のオブジェクトIDと表スペースIDは以下のSQLで予め確認しておくこと。
db2 "SELECT tabname, tableid, tbspaceid FROM syscat.tables WHERE tabname='XXXXXX'"
サンプルコード
-- 表スペース作成
db2 "create large tablespace spmtbs managed by database using(file 'spmtbs.dat' 10000) autoresize yes extentsize 4"
-- 表作成
db2 "create table big_tab1(a varchar(3000)) in spmtbs"
-- データ増幅
db2 "insert into big_tab1 values('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')"
db2 "update big_tab1 set a = replace(a, 'a', 'aaaaaaaaaa')"
db2 "update big_tab1 set a = replace(a, 'a', 'aaaaaaaaaa')"
db2 "insert into big_tab1 select * from big_tab1" -- 2 rows
db2 "insert into big_tab1 select * from big_tab1" -- 4 rows
・・・
-- db2dart実行
db2 terminate
db2dart sample /DEMP /OI 4 /TSI 7
-- Object specific mapping info:
-- -----------------------------
-- DAT extent anchor: 12
-- Traversing extent map for object type: 0
-- Pool: 7, Object: 4 EMP page class: 64,
-- EMP pool page: 12, # entries: 1000
-- Page LSN = 0001 3B37 FE46
-- Pool relative page #'s :
-- 16 20 24 28 32
-- 36 40 44 48 52
-- 〜〜中略〜〜
-- 520380 520384 520388 520392 520396
-- 520400 520404 520408 520412 520416
-- 520420 520424
-- 〜〜後略〜〜
解説
今回は1エクステント4ページの表スペースを作成しました。
表スペースを作成した時点で、内部では4つのエクステントが取られています。
エクステントID 開始ページ番号 終了ページ番号 役割
------------------------------------------------------
なし なし なし コンテナー・タグ
0 0 3 表スペース・ヘッダー
1 4 7 SMP(スペース・マップ・ページ)
2 8 11 オブジェクト表データ
コンテナー毎に、1エクステントのヘッダー領域が取られます。
でも、list tablespaces show detail やその他表スペース関連の情報を取得するコマンドでは、このコンテナー・タグの情報は出力されません。
問答無用で1エクステント削られます。
更に言うと、各エクステントには、エクステントIDが振られていますが、コンテナー・タグには割り振られません。そして、コンテナー内のページにもページIDが振られますが、コンテナー・タグの持つページにはIDがありません。
その後ろに来るのが表スペースのヘッダー情報。
その後ろが、SMP(スペース・マップ・ページ)で、これは表スペース内の空きエクステントの情報を持っています。(後ほどコレについても検証する予定)
オブジェクト表データというのは、この表スペース内に格納されているオブジェクトの情報を持つエクステント。
ということで、4エクステントが取られているわけです。
そんで、表スペースの中に表を1つ作成すると、表のヘッダーエクステントと、データ用のエクステントの2つが最初に取られます。
このヘッダーのエクステントが、EMP(エクステント・マップ・ページ)で、表のエクステント・マップが格納されているらしいです。
エクステントID 開始ページ番号 終了ページ番号 役割
------------------------------------------------------
なし なし なし コンテナー・タグ
0 0 3 表スペース・ヘッダー
1 4 7 SMP(スペース・マップ・ページ)
2 8 11 オブジェクト表データ
3 12 15 big_tab1のEMP
4 16 19 big_tab1のデータエクステント
そして表のデータを増やしていき、最初に確保したデータエクステントが満タンになると、1エクステントずつ拡張していきます。
エクステントID 開始ページ番号 終了ページ番号 役割
------------------------------------------------------
なし なし なし コンテナー・タグ
0 0 3 表スペース・ヘッダー
1 4 7 SMP(スペース・マップ・ページ)
2 8 11 オブジェクト表データ
3 12 15 big_tab1のEMP
4 16 19 big_tab1のデータエクステント
5 20 23 big_tab1のデータエクステント
・・・・
db2dart /DEMP の結果を見ていきます。
DAT extent anchor: 12
まず、ここが該当する表の最初に確保したEMPエクステントの開始ページ番号です。
今回は12番のページで始まるエクステントが、最初のEMPエクステントであることがわかります。
Pool: 7, Object: 4 EMP page class: 64,
Poolが表スペースのID、Object: 4 が表のID
EMP pool page: 12, # entries: 1000
12番のページから始まるEMPには、エクステント情報が1000個格納されているという意味。
ココらへんはまた後で詳しく検証する予定。
Pool relative page #'s :
16 20 24 28 32
36 40 44 48 52
ここに並んでいる数値が、この表のエクステントの開始ページ番号を表しています。
ということで、ここを見ればエクステントの配置がわかるということになります。
エクステント・マップを見たからどうだ、という話ではありませんが、これが確認できるとマニュアルに載っている様々な内部動作を、実際に確認し検証できます。
例えば、表スペース内の空きエクステント情報が入るSMPが溢れたら、どのように拡張されるのか。
今確認したEMPが溢れたらどうなるか。
ページ・サイズによって管理できるエクステント数は変わるのか。などなど…
そんなわけで、今後数回に渡りdb2dartを使って領域の使われ方を確認してきます。
あ、今回はdb2の9.1で検証しているのですが、バージョンによって内部構造は変わる可能性があります。
それと、9.1は既にサポート切れなので使用する際はご注意を。
それと、本ブログの内容は、あくまで個人的な見解ですのでご理解を。
Home > 2012年06月
- タグクラウド
-
- Categories
- Monthly
- Recent Entries
- Recent Comments
- Recent Trackbacks
- Appendix
- Author:Nakunaru
データベース(ORACLEとかSQL ServerとかDB2とかMySQLとか)とか技術者教育とかプログラムとか。
気になる技術を少しずつ勉強していきます。