Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

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

  1. 1. PostgreSQLのデータ構造と内容を知る - 便利な外部ツールの一部紹介 - JPUGしくみ + アプリーケーション分科会 勉強会 2014.5.31 笠原辰仁 @kasa_zip
  2. 2. アジェンダ ● はじめに ● PostgreSQLを構成するデータ ● 構造、状況を把握するツール群 ● 各種ツールの使い方と代表的な利用例
  3. 3. はじめに ● 本日は、PostgreSQLのデータ構造やその内容を 知るために有用なツールとその簡単な使い方を紹 介します ● 最近はプレ勉強会や永安氏の公開している PostgreSQL internals など、PostgreSQLの内 部を深く知るための手段や機会が増えてきました – http://www.postgresqlinternals.org/index.php/ ● 内部構造を知る上で、理解の手助けになれば・・ ● また、最近はPostgreSQLの利用シーンも増えて おり、データ破損などの調査も必要になるケース が増えているので・・・
  4. 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. 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. 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. 7. 便利なツール群(主に開発) ● データ構造や属性の確認に便利 名称 説明 解析対象 PostgreSQL起 動 pg_filedump (外部ツール) テーブルやインデックスデータの物理 イメージをダンプして可視化するツー ル。 pagseinspectがあればほぼ不要・・ テーブル インデックス 不要 pg_xlogdump (9.3からcontrib) トランザクションログの内容を可視化 するツール。 トランザク ションログ 不要 pageinspect (8.3からcontrib) テーブルやインデックス、FSMのメタ 情報(主にヘッダ情報)を可視化する ツール テーブル インデックス FSM 必要
  8. 8. 便利なツール群(主に検証・運用) ● データの統計的な俯瞰、確認に便利 名称 説明 解析対象 PostgreSQL起 動 pgstattuplet (contrib) テーブルやインデックスの不 要領域や断片化状況を数値化 するツール。 テーブル インデックス 必要 pg_buffercache (contrib) テーブルやインデックスが PostgreSQLの共有バッファ にどれだけ格納されているか を数値化するツール。 テーブル インデックス 必要 pg_fincore (外部ツール) テーブルやインデックスがOS のファイルキャッシュにどれ だけ格納されているかを数値 化するツール。 テーブル インデックス 必要 pg_freespacemap (contirb) FSMにマッピングされている 空き領域状況を数値化する ツール。 FSM 必要
  9. 9. テーブル/インデックスの ページ構造を調べる * +-----------------------+---------------------------------+ * | PageHeaderData | linp1 linp2 linp3 ... | * +---------------+------+---------------------------------+ * | ... linpN | | * +---------------+-----------------------------------------+ * | ^ pd_lower | * | | * | v pd_upper | * +-------------+-------------------------------------------+ * | | tupleN ... | * +-------------+-----------------------+-------------------+ * | ... tuple3 tuple2 tuple1 | "special space"| * +--------------------------------------+-------------------+ * ^ pd_special ●
  10. 10. pageinspect ● contribに付属しているツール ● contribモジュールのmakeないしはRPMパッ ケージ等で導入 – pageinspectを実施したいDBでCREATE EXTENSION ● テーブル、インデックス名をインップットし、 ページヘッダやタプルヘッダのメタ情報の調査 に有用 ● 手軽に使えておすすめ
  11. 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. 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. 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. 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. 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. 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. 17. pg_filedump ● Pgfoundryで公開されている外部ツール ● contribモジュール同様の手順でmake && make installして利用可能 – PostgreSQLのバージョン毎にコードがある – PostgreSQL 9.3用はHEADを使う ● テーブル、インデックスのファイルをインッ プットし、ページヘッダやタプルヘッダのメタ 情報の調査に有用
  18. 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. 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. 20. pageinspect vs pg_filedump ● どちらも大体同じ情報が取れるが、pageinspect に分がある感じ ● pageinspectの良さ – SQLで集計や検索が容易 – テーブルやインデックス名で情報をひける ● pg_filedumpの良さ – PostgreSQLが停止してても使える – infomask等を分かりやすく表示する – インデックスのFlagの状態が分かる ● ただ、pg_filedumpはメンテが止まる可能性 が・・ – 9.3も正式版?が出ていない・・
  21. 21. pg_xlogdump ● contribに付属しているツール ● contribモジュールのmakeないしはRPMパッ ケージ等で導入 ● コマンドライン ● WALファイルをインップットし、トランザク ションレコードの調査が可能 ● おそらくWALの内部情報を分かりやすくダンプ する唯一のツール
  22. 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. 23. pg_xlogdump 活用方法? ● 運用でお世話になることは少ない・・ ● フルページの割合の調査には有用か – Bkpフラグ等で確認できる ● rmgrで絞れば、例えばテーブルの CREATE/DROPなどを抽出できる – 大事なデータやテーブルの削除処理が分かるので、 オペミスからの復旧に使える – 大事な作業はログを取っておくものなので、出番は ないかも・・
  24. 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. 25. 挙動を見てみよう その1 ● Btreeのリーフスプリット ● Btreeインデックスのスプリットは ● 一番右端のリーフは左をFILLFACTORぶん詰める ● それ以外は1:1の比率で分ける リーフ分割 右はなるべく空ける
  26. 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. 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. 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. 29. 挙動を見てみよう その2 ● Commit Hint Bit ● INSERTやUPDATEで新規のデータが投入される ● そのトランザクションがコミットされる ● 別のトランザクションがその新規のデータを見る ● その際、本当にコミットされたかをコミットログから判断する ● コミットされていたらフラグを立て、以降はフラグで判断する ● これがCommit Hint Bit タプルヘッダ 実データTx A Tx B INSERT & COMMIT clog 見に行く Hintない Clog見る Commitされてた。 フラグ付ける
  30. 30. 見てみる ● 簡単なデモで
  31. 31. 終わりに ● PostgreSQLのデータ構成とツールの一部を紹 介しました ● データの作りや変更を追っていく と、PostgreSQLの中が見えてきます ● バイナリエディタやgdbを駆使するのもアリで すが、便利なツールもあります ● 是非使ってみてください!
  32. 32. ご清聴ありがとうございました! QA?

×