32
Copyright 2013 Metro Systems. 1 9.3で進化した外部テーブル 第26回 しくみ+アプリケーション勉強会 2013年6月8日 株式会社メトロシステムズ 花田 茂

9.3で進化した外部テーブル

Embed Size (px)

DESCRIPTION

2013-06-08 第26回 しくみ+アプリケーション勉強会で使用したスライドです。 Ustreamで動画も観られます。 http://www.ustream.tv/recorded/34007681

Citation preview

Page 1: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 1

9.3で進化した外部テーブル

第26回 しくみ+アプリケーション勉強会2013年6月8日

株式会社メトロシステムズ花田 茂

Page 2: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 2

自己紹介

● 氏名– 花田 茂(はなだ しげる)

● 所属– 株式会社メトロシステムズ

● メールアドレス– [email protected]

● Twitter– @s87

● ブログ– http://d.hatena.ne.jp/s87/

Page 3: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 3

アジェンダ

● 外部テーブルとは?● 外部テーブルの進化● 外部データラッパの紹介● 外部データラッパの作り方

Page 4: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 4

外部テーブルとは?

● PostgreSQLの外部にあるデータに通常のテーブルと同様にSQL文でアクセスできる特殊なテーブルです。(ビューに近い?)– SQLでは「FOREIGN TABLE」

● 外部テーブルを作成するには、外部データの種類に応じた「外部データラッパ」(FDW:Foreign Data Wrapper)が必要です。

Page 5: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 5

そもそも外部データって?

● PostgreSQLからアクセスできるもの全て– OSファイル

● CSVファイル、JSONファイル、ログファイル、Etc.– リレーショナルデータベース

● PostgreSQL、Oracle、MySQL、SQLite3、Etc.– NoSQLデータベース

● Hadoop、Redis、Mongo、Neo4J、Etc.– Webサービス

● twitter、RESTアプリケーション、Etc.– その他

● Amazon S3、コマンド実行結果、Etc.

Page 6: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 6

外部テーブルの進化(1)

● 8.4– SQL/MED基盤

● 外部データの検索は未実装● dblinkやplproxyなどの外部モジュール用に管理情報

のコンテナを提供– postgresql_fdw_validatorがdblink用に存在

● これの後方互換性維持のために「postgresql_fdw」という名前が使えないという事態になるとは…

Page 7: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 7

外部テーブルの進化(2)

● 9.0– ***動きなし***

Page 8: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 8

外部テーブルの進化(3)

● 9.1– 外部テーブルサポート(検索のみ)– file_fdwの追加– SERVER、USER MAPPING、FOREIGN

TABLE構文の追加

Page 9: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 9

外部テーブルの進化(4)

● 9.2– 外部テーブルへのANALYZE– 複数候補パス(よりよいアクセスパスを選択)– 列単位のFDWオプション

Page 10: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 10

外部テーブルの進化(5)

● 9.3– 書き込み可能な外部テーブル

● トランザクションコマンドもハンドリング可能– postgres_fdwの追加

Page 11: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 11

さっそくデモ

● postgres_fdw– 他のPostgreSQLサーバにアクセスできるFDW– 9.1で外部テーブルと一緒に提案→却下– 9.2でANALYZE対応などと一緒に提案→却下– 9.3でようやくcontribに追加

● 長引いた原因はネーミング?● pgsql_fdw → postgresql_fdw → postgres_fdw

Page 12: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 12

postgres_fdw(1)

● まずはEXTENSIONを作成– 自動的にFOREIGN DATA WRAPPERも作成

● 接続先サーバをSERVERで定義– オプション:host、port、dbnameなどのlibpqオプ

ション● リモートユーザをUSER MAPPINGで定義

– オプション:user、password● 外部データ構造をFOREIGN TABLEで定義

– オプション:table_name

Page 13: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 13

postgres_fdw(2)

● SERVERで定義したデータベースにUSER MAPPINGで定義したユーザで接続– ローカルユーザとリモートユーザをマッピング– サーバ×ローカルユーザでリモートユーザを切り替え

● table_nameオプションで指定したテーブルに対するSELECT文を生成してクエリを実行– リモートと別の名前で外部テーブルを定義可能

● 取得した結果をローカルのPostgreSQL内で処理し、クライアントに返却– EXPLAIN VERBOSEでリモートクエリを表示

Page 14: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 14

postgres_fdw(3)

● WHERE句をリモートで評価して転送量削減– MUTABLE/STABLEの演算子/関数– ユーザ定義の演算子/関数

● 他のテーブルやビューとの結合が可能– 同じサーバの外部テーブル同士でも、結合はローカルに持って

きてから→大量データの場合は要注意● ORDER BYやLIMIT/OFFSETはローカル評価

– 頑張ればORDER BYはリモート評価できそうです

Page 15: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 15

postgres_fdw(4)

● EXPLAIN結果でおかしい点があったんですが、気づきましたか?

Page 16: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 16

postgres_fdw(5)

● 見積もりを正確にするには…– クエリ実行時にリモートの見積もりを取得

● FOREIGN TABLEかSERVERのオプションでuse_remote_estimateをtrueに設定

● クエリ実行時にEXPLAINをリモートで実行し、その見積もりでローカルの実行計画を作成

– ANALYZEしてローカルに統計情報を保持● テーブル名を明示する必要がある(対象を指定しない場合は外部テーブルをスキップ)

Page 17: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 17

postgres_fdw(6)

● リモート接続に関する注意点– ローカル接続が続いている限り、リモート接続は保持される→リモート側をシャットダウンするとき注意

– 同じサーバ上の外部テーブルへのクエリは同じ接続で実行

● REPEATABLE READまたはSERIALIZABLEの分離レベルを使用

Page 18: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 18

postgres_fdw(7)

● 検索だけでなく、更新も可能– INSERT/UPDATE/DELETE

● トランザクションも一部サポート– リモートトランザクションをロールバック可能– 二相コミットは未サポート

Page 19: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 19

サードパーティのFDW(1)

● RDBMS– oracle_fdw(Zheng Yang版)

● http://pgxn.org/dist/odbc_fdw/– oracle_fdw(NTT版)

● http://interdbconnect.sourceforge.net– mysql_fdw

● http://pgxn.org/dist/mysql_fdw/– odbc_fdw

● http://pgxn.org/dist/odbc_fdw/– jdbc_fdw

● http://pgxn.org/dist/jdbc_fdw/

Page 20: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 20

サードパーティのFDW(2)● その他のデーターベース

– couchdb_fdw● http://pgxn.org/dist/couchdb_fdw/

– mongo_fdw● http://pgxn.org/dist/mongo_fdw/

– redis_fdw● http://pgxn.org/dist/redis_fdw/● https://github.com/pg-redis-fdw/redis_fdw

– ldap_fdw● http://pgxn.org/dist/ldap_fdw/

– neo4j_fdw● https://github.com/nuko-yokohama/neo4j_fdw

Page 21: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 21

サードパーティのFDW(3)

● その他– multicorn_fdw(PythonでFDWを実装)

● http://pgxn.org/dist/couchdb_fdw/– s3_fdw(Amazon S3)

● http://pgxn.org/dist/s3_fdw/– twitter_fdw(Twitter)

● http://pgxn.org/dist/twitter_fdw/– www_fdw(REST)

● https://github.com/cyga/www_fdw

Page 22: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 22

外部データラッパの作り方

● C言語関数– FDW API(コールバック関数)を実装し、それらの関数ポインタを持っ

た構造体を返すハンドラ関数を実装– 検索のみならば7個の関数でOK

● SQL関数– ハンドラ関数のSQLラッパ関数を実装– オプションを検査するバリデータ関数を実装(必要に応じて)

● EXTENSION– 全体をEXTENSIONとしてパッケージ

● 詳細は– http://www.postgresql.org/docs/9.3/static/fdwhandler.html

Page 23: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 23

FDW API(1)

● 検索系– プランナ

● GetForeignRelSize– テーブルサイズを見積もる

● GetForeignPaths– アクセスパスを(最低一つ)生成する– ソートキーの異なるパスなどを複数生成できる– プランナが自動的に最適なパスを選択してくれる

● GetForeignPlan– プランナが決定したアクセスパスに沿ったForeignScanプランノードを生成する

– FDW独自の情報をGetForeignPathsから受け取れる

Page 24: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 24

FDW API(2)● 検索系

– エグゼキュータ● BeginForeignScan

– スキャン開始時に一度だけ呼ばれる● IterateForeignScan

– 上位ノードが1行必要としたときに呼ばれる– HeapTuple(行データの内部表現)を生成して返す

● ReScanForeignScan– スキャン位置を先頭に戻してほしいときに呼ばれる– NestedLoopのインナー側の場合など– スキャン結果を捨ててしまった場合は、リモートから再取得する

● EndForeignScan(検索終了)– スキャン終了時に呼ばれる– クリーンアップなど– クエリがエラー終了すると呼ばれないので要注意

Page 25: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 25

FDW API(3)

● 検索用EXPLAIN– ExplainForeignScan

● 検索クエリのEXPLAINで呼ばれる● ForeignScanノードに表示する情報を追加する● VERBOSEモードのon/of判定も可能

● ANALYZE– AnalyzeForeignTable

ANALYZE可否を判断し、可能ならばサンプル収集関数を返す– AcquireSampleRows

● リモートデータからサンプル行を取得する

Page 26: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 26

FDW API(4)

● 更新系– リライタ/プランナ

● AddForeignUpdateTargets– 更新時に使用するキー情報をタプル定義に追加する– postgres_fdwではCTID(タプルID)を使用

● PlanForeignModify– 更新処理に必要な情報をプライベート領域に保存する– postgres_fdwでは更新用SQL分を生成

Page 27: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 27

FDW API(5)

● 更新系– エグゼキュータ

● BeginForeignModify– 更新処理開始時に呼ばれる

● ExecForeignInsert● ExecForeignUpdate(リモート更新実行)● ExecForeignDelete(リモート削除実行)

– 挿入/更新/削除一件ごとに一回呼ばれる– リモート側にデータを挿入/更新/削除する

● EndForeignModify(更新終了)– 更新処理終了時に呼ばれる

Page 28: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 28

FDW API(6)

● 更新用EXPLAIN– ExplainForeignModify

● 更新クエリのEXPLAINで呼ばれる● 更新ノードに表示する情報を追加する● VERBOSEモードのon/of判定も可能

Page 29: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 29

トランザクション管理

● リモートトランザクションサポート– トランザクション終了時に呼ばれるコールバック関数を登録しておき、そこでトランザクションコマンドを実行する

● RegisterXactCallback● RegisterSubXactCallback

– ローカルのCOMMIT/ROLLBACKの直前に呼ばれるので、このコールバックで例外が発生するとローカルトランザクションもABORTする

Page 30: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 30

大変だな〜という人向けに

● blackhole_fdw– Andrew Dunstan氏が公開

● https://bitbucket.org/adunstan/blackhole_fdw– APIに対応する関数を持つが、何もしない→検索

しても0件、更新は空振り– FDWのひな形として利用可能

Page 31: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 31

FDW関連の情報源

● PostgreSQL wiki– http://wiki.postgresql.org/wiki/SQL/MED

● PGXN– http://pgxn.org

Page 32: 9.3で進化した外部テーブル

Copyright 2013 Metro Systems. 32

おわりに

● ご清聴ありがとうございました。