Your SlideShare is downloading. ×
20140531 JPUGしくみ+アプリケーション分科会 勉強会資料
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

20140531 JPUGしくみ+アプリケーション分科会 勉強会資料

1,187
views

Published on

Published in: Technology

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,187
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
24
Comments
0
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. PostgreSQLのデータ構造と内容を知る - 便利な外部ツールの一部紹介 - JPUGしくみ + アプリーケーション分科会 勉強会 2014.5.31 笠原辰仁 @kasa_zip
  • 2. アジェンダ ● はじめに ● PostgreSQLを構成するデータ ● 構造、状況を把握するツール群 ● 各種ツールの使い方と代表的な利用例
  • 3. はじめに ● 本日は、PostgreSQLのデータ構造やその内容を 知るために有用なツールとその簡単な使い方を紹 介します ● 最近はプレ勉強会や永安氏の公開している PostgreSQL internals など、PostgreSQLの内 部を深く知るための手段や機会が増えてきました – http://www.postgresqlinternals.org/index.php/ ● 内部構造を知る上で、理解の手助けになれば・・ ● また、最近はPostgreSQLの利用シーンも増えて おり、データ破損などの調査も必要になるケース が増えているので・・・
  • 4. PostgreSQLを構成するデータ ● 代表的なデータ 名称 説明 格納先 テーブル テーブルデータ。デフォルトでは8kBブ ロックの固まりで、1GBファイル1単位に 分割されている。 $PGDATA/base $PGDATA/global <テーブルスペース >/<識別子>/ インデックス インデックスデータ。基本的な構成は テーブルデータと同じ。 $PGDATA/base $PGDATA/global< テーブルスペース>/< 識別子>/ FSM(Free Space Map) テーブル内に存在する空き領域の場所と 大まかな空きサイズをマッピングした ファイル。 テーブルと同じ VM(Visibility Map) テーブルのブロック単位での可視マップ ファイル。1ブロック1bit1で管理。不要 レコードがなければ1 テーブルと同じ 一時ファイル ディスクソートやハッシュ処理時に生成 される一時ファイル。処理終了時に削除 される。 $PGDATA/base/pg sql_tmp
  • 5. PostgreSQLを構成するデータ ● 代表的なデータ 名称 説明 格納先 トランザクションログ DBに変更を行った処理のログ $PGDATA/pg_xlog/ コミットログ 各トランザクションのコミット状況 を記録しているログ $PGDATA/pg_clog/ 制御ファイル XIDなどインスタンスの重要なメタ データを記録しているファイル (pg_control 512byte 固定) $PGDATA/global/ 稼働統計情報ファイル 内部で取得されている稼働統計情報 のファイル。 $PGDATA/pg_stat/ $PGDATA/pg_stat_tmp/ Multixactファイル (名前適当) 共有ロック状態を記録しているファ イル。 $PGDATA/pg_multixact/ Serialファイル (名前適当) SSIトランザクションのコミット状況 を記録しているファイル。 $PGDATA/pg_serial/ サブトランザクション ファイル SAVEPOINTを使用したサブトラン ザクションの状況を記録している ファイル。 $PGDATA/subtrans/ スナップショット ファイル pg_export_snapshot()でエクスポー トしたスナップショット情報。 $PGDATA/pg_snapshots/
  • 6. PostgreSQLを構成するデータ ● 代表的なデータ 名称 説明 格納先 PreparedTransaction ファイル 2フェーズコミット用のプリペアトラ ンザクションの状態を記録てしてい るファイル。 $PGDATA/pg_twophas e/ Filenodeマップファイル pg_classを経由しないアクセスが実 施されるシステムカタログのOIDと 物理ファイルのマップファイル (pg_filenode.map 512byte 固定) $PGDATA/global/ $PGDATA/base/ relationキャッシュファ イル 各種リレーションのキャッシュファ イル(backendの初期化高速用) (pg_internal.init) $PGDATA/global/ $PGDATA/base/ 設定ファイル PostgreSQLの設定ファイル (postgresql.conf) $PGDATA アクセス制御ファイル PostgreSQLのホストベースのアク セス制御ファイル (pg_hba.conf) $PGDATA 起動コマンドファイル PostgreSQLを起動した際のコマン ドを記録したファイル (postmaster.opts) $PGDATA
  • 7. 便利なツール群(主に開発) ● データ構造や属性の確認に便利 名称 説明 解析対象 PostgreSQL起 動 pg_filedump (外部ツール) テーブルやインデックスデータの物理 イメージをダンプして可視化するツー ル。 pagseinspectがあればほぼ不要・・ テーブル インデックス 不要 pg_xlogdump (9.3からcontrib) トランザクションログの内容を可視化 するツール。 トランザク ションログ 不要 pageinspect (8.3からcontrib) テーブルやインデックス、FSMのメタ 情報(主にヘッダ情報)を可視化する ツール テーブル インデックス FSM 必要
  • 8. 便利なツール群(主に検証・運用) ● データの統計的な俯瞰、確認に便利 名称 説明 解析対象 PostgreSQL起 動 pgstattuplet (contrib) テーブルやインデックスの不 要領域や断片化状況を数値化 するツール。 テーブル インデックス 必要 pg_buffercache (contrib) テーブルやインデックスが PostgreSQLの共有バッファ にどれだけ格納されているか を数値化するツール。 テーブル インデックス 必要 pg_fincore (外部ツール) テーブルやインデックスがOS のファイルキャッシュにどれ だけ格納されているかを数値 化するツール。 テーブル インデックス 必要 pg_freespacemap (contirb) FSMにマッピングされている 空き領域状況を数値化する ツール。 FSM 必要
  • 9. テーブル/インデックスの ページ構造を調べる * +-----------------------+---------------------------------+ * | PageHeaderData | linp1 linp2 linp3 ... | * +---------------+------+---------------------------------+ * | ... linpN | | * +---------------+-----------------------------------------+ * | ^ pd_lower | * | | * | v pd_upper | * +-------------+-------------------------------------------+ * | | tupleN ... | * +-------------+-----------------------+-------------------+ * | ... tuple3 tuple2 tuple1 | "special space"| * +--------------------------------------+-------------------+ * ^ pd_special ●
  • 10. pageinspect ● contribに付属しているツール ● contribモジュールのmakeないしはRPMパッ ケージ等で導入 – pageinspectを実施したいDBでCREATE EXTENSION ● テーブル、インデックス名をインップットし、 ページヘッダやタプルヘッダのメタ情報の調査 に有用 ● 手軽に使えておすすめ
  • 11. pageinspectの出力例(テーブル) (詳細は include/storage/bufpage.h) postgres=# SELECT * FROM page_header(get_raw_page('test', 0)); -[ RECORD 1 ]-------- lsn | 0/1F88F90 checksum | 0 flags | 0 lower | 44 upper | 8032 special | 8192 pagesize | 8192 version | 4 prune_xid | 1094 Flagsはページ単位の状態を表すヒント。 PD_PAGE_FULL , PD_ALL_VISIBLEなど Versionはページレイアウトの * Page layout version number 0 is for pre-7.3 * Releases 7.3 and 7.4 use 1. * Release 8.0 uses 2 * Release 8.1 uses 3 * Release 8.3 uses 4
  • 12. pageinspectの出力例(テーブル) (詳細は include/access/htup_details.h) postgres=# SELECT * FROM heap_page_items(get_raw_page('test', 0)); -[ RECORD 1 ]--------- lp | 1 lp_off | 8160 lp_flags | 1 lp_len | 28 t_xmin | 1097 t_xmax | 0 t_field3 | 0 t_ctid | (0,1) t_infomask2 | 3 t_infomask | 2049 t_hoff | 24 t_bits | 10000000 t_oid | lp_flags はラインポインタの状態 0:未使用、1:通常、 2:REDIRECT, 3: DEAD t_infomaskがタプルの状態を 細かく管理している重要な フラグ部位。左記は10進数 t_bitsはNULL値の管理
  • 13. pageinspectの出力例(インデックス) (詳細は include/access/nbtree.h) postgres=# SELECT * FROM bt_metap('test_pkey'); -[ RECORD 1 ]----- magic | 340322 version | 2 root | 1 level | 0 fastroot | 1 fastlevel | 0
  • 14. pageinspectの出力例(インデックス) (詳細は include/access/nbtree.h) postgres=# SELECT * FROM bt_page_stats('test_pkey', 1); -[ RECORD 1 ]-+----- blkno | 1 type | l live_items | 3 dead_items | 0 avg_item_size | 16 page_size | 8192 free_size | 8088 btpo_prev | 0 btpo_next | 0 btpo | 0 btpo_flags | 3 btpo_* はspecial領域に あるBtree専用の情報
  • 15. pageinspectの出力例(インデックス) postgres=# SELECT * FROM bt_page_items('test_pkey', 1); -[ RECORD 1 ]----------------------- Itemoffset | 1 ctid | (0,1) itemlen | 16 nulls | f vars | f data | 01 00 00 00 00 00 00 00 -[ RECORD 2 ]----------------------- itemoffset | 2 ctid | (0,2) itemlen | 16 nulls | f vars | f data | 02 00 00 00 00 00 00 00 ctidはテーブルのライン ポインタ data は実際のキー値
  • 16. pageinspectの出力例(インデックス) postgres=# SELECT * FROM bt_page_items('test2_idx', 1); -[ RECORD 1 ]----------------------- Itemoffset | 1 ctid | (0,1) itemlen | 16 nulls | f vars | t data | 01 00 00 00 09 41 41 41 -[ RECORD 2 ]----------------------- itemoffset | 2 ctid | (0,2) itemlen | 16 nulls | f vars | t data | 02 00 00 00 09 42 42 42 マルチカラムインデックスは こんな感じに見える 1, 'AAA' 2, 'BBB' の16進数表記 (文字の前の09はヘッダ含むサイズ) 9 >> 1 = 4 = (1 + 3)
  • 17. pg_filedump ● Pgfoundryで公開されている外部ツール ● contribモジュール同様の手順でmake && make installして利用可能 – PostgreSQLのバージョン毎にコードがある – PostgreSQL 9.3用はHEADを使う ● テーブル、インデックスのファイルをインッ プットし、ページヘッダやタプルヘッダのメタ 情報の調査に有用
  • 18. pg_filedumpの出力例(テーブル) pg_filedump -i /Users/postgres/base/pgsql934/base/12297/16486 Block 0 ******************************************************** <Header> ----- Block Offset: 0x00000000 Offsets: Lower 40 (0x0028) Block: Size 8192 Version 4 Upper 8064 (0x1f80) LSN: logid 0 recoff 0x01f88dc8 Special 8192 (0x2000) Items: 4 Free Space: 8024 Checksum: 0x0000 Prune XID: 0x00000446 Flags: 0x0000 () Length (including item array): 40 <Data> ------ Item 1 -- Length: 32 Offset: 8160 (0x1fe0) Flags: NORMAL XMIN: 1091 XMAX: 0 CID|XVAC: 0 Block Id: 0 linp Index: 1 Attributes: 2 Size: 24 infomask: 0x0802 (HASVARWIDTH|XMAX_INVALID)
  • 19. pg_filedumpの出力例(インデックス) Block 1 ******************************************************** <Header> ----- Block Offset: 0x00002000 Offsets: Lower 40 (0x0028) Block: Size 8192 Version 4 Upper 8112 (0x1fb0) LSN: logid 0 recoff 0x01f89058 Special 8176 (0x1ff0) Items: 4 Free Space: 8072 Checksum: 0x0000 Prune XID: 0x00000000 Flags: 0x0000 () Length (including item array): 40 <Data> ------ Item 1 -- Length: 16 Offset: 8160 (0x1fe0) Flags: NORMAL Block Id: 0 linp Index: 1 Size: 16 Has Nulls: 0 Has Varwidths: 0 <Special Section> ----- BTree Index Section: Flags: 0x0043 (LEAF|ROOT|HASGARBAGE) Blocks: Previous (0) Next (0) Level (0) CycleId (0)
  • 20. pageinspect vs pg_filedump ● どちらも大体同じ情報が取れるが、pageinspect に分がある感じ ● pageinspectの良さ – SQLで集計や検索が容易 – テーブルやインデックス名で情報をひける ● pg_filedumpの良さ – PostgreSQLが停止してても使える – infomask等を分かりやすく表示する – インデックスのFlagの状態が分かる ● ただ、pg_filedumpはメンテが止まる可能性 が・・ – 9.3も正式版?が出ていない・・
  • 21. pg_xlogdump ● contribに付属しているツール ● contribモジュールのmakeないしはRPMパッ ケージ等で導入 ● コマンドライン ● WALファイルをインップットし、トランザク ションレコードの調査が可能 ● おそらくWALの内部情報を分かりやすくダンプ する唯一のツール
  • 22. pg_xlogdumpの出力例 pg_xlogdump base/pgsql934/pg_xlog/000000010000000000000001 rmgr: Heap len (rec/tot): 35/ 67, tx: 1000, lsn: 0/01B25020, prev 0/01B24FE0, bkp: 0000, desc: insert(init): rel 1663/12297/16384; tid 0/1 rmgr: Transaction len (rec/tot): 12/ 44, tx: 1000, lsn: 0/01B25068, prev 0/01B25020, bkp: 0000, desc: commit: 2014-04-26 19:51:36.311101 JST rmgr(resource manager)は処理カテゴリのようなもの。 len は rec:rmgrに関連するもののみのレコード長 totはトランザクションレコード全体の長さ。 txはトランザクションID bkp はフルページのバックアップをしたかのフラグ。 descはトランザクションの処理内容
  • 23. pg_xlogdump 活用方法? ● 運用でお世話になることは少ない・・ ● フルページの割合の調査には有用か – Bkpフラグ等で確認できる ● rmgrで絞れば、例えばテーブルの CREATE/DROPなどを抽出できる – 大事なデータやテーブルの削除処理が分かるので、 オペミスからの復旧に使える – 大事な作業はログを取っておくものなので、出番は ないかも・・
  • 24. pg_xlogdump 活用方法? pg_xlogdump -r Storage … rmgr: Storage len (rec/tot): 16/ 48, tx: 0, lsn: 0/0227AA20, prev 0/0227A9F0, bkp: 0000, desc: file create: base/12297/16505
  • 25. 挙動を見てみよう その1 ● Btreeのリーフスプリット ● Btreeインデックスのスプリットは ● 一番右端のリーフは左をFILLFACTORぶん詰める ● それ以外は1:1の比率で分ける リーフ分割 右はなるべく空ける
  • 26. 見てみる create table test (c1 int); CREATE INDEX test_idx ON test(c1); INSERT into test SELECT generate_series(1,1000); SELECT (bt_page_stats('test_idx', i)).blkno,(bt_page_stats('test_idx', i)).type, (bt_page_stats('test_idx', i)).live_items, (bt_page_stats('test_idx', i)).btpo_prev, (bt_page_stats('test_idx', i)).btpo_next FROM (SELECT generate_series(1, relpages-1) from pg_class WHERE relname = 'test_idx')s(i); blkno | type | live_items | btpo_prev | btpo_next -------+------+------------+-----------+----------- 1 | l | 367 | 0 | 2 2 | l | 367 | 1 | 4 3 | r | 3 | 0 | 0 4 | l | 268 | 2 | 0
  • 27. 見てみる INSERT INTO test SELECT 1 FROM generate_series(1,100); blkno | type | live_items | btpo_prev | btpo_next -------+------+------------+-----------+----------- 1 | l | 251 | 0 | 5 2 | l | 367 | 5 | 4 3 | r | 4 | 0 | 0 4 | l | 268 | 2 | 0 5 | l | 217 | 1 | 2 左のリーフがスプリットされ 251:217のキーを保持
  • 28. 見てみる INSERT INTO test SELECT 1000 FROM generate_series(1,200); blkno | type | live_items | btpo_prev | btpo_next -------+------+------------+-----------+----------- 1 | l | 251 | 0 | 5 2 | l | 367 | 5 | 4 3 | r | 5 | 0 | 0 4 | l | 407 | 2 | 6 5 | l | 217 | 1 | 2 6 | l | 62 | 4 | 0 右端のリーフがスプリットされ 407:62のキーを保持
  • 29. 挙動を見てみよう その2 ● Commit Hint Bit ● INSERTやUPDATEで新規のデータが投入される ● そのトランザクションがコミットされる ● 別のトランザクションがその新規のデータを見る ● その際、本当にコミットされたかをコミットログから判断する ● コミットされていたらフラグを立て、以降はフラグで判断する ● これがCommit Hint Bit タプルヘッダ 実データTx A Tx B INSERT & COMMIT clog 見に行く Hintない Clog見る Commitされてた。 フラグ付ける
  • 30. 見てみる ● 簡単なデモで
  • 31. 終わりに ● PostgreSQLのデータ構成とツールの一部を紹 介しました ● データの作りや変更を追っていく と、PostgreSQLの中が見えてきます ● バイナリエディタやgdbを駆使するのもアリで すが、便利なツールもあります ● 是非使ってみてください!
  • 32. ご清聴ありがとうございました! QA?