Copyright 2013 Metro Systems. 1
9.3で進化した外部テーブル
第26回 しくみ+アプリケーション勉強会2013年6月8日
株式会社メトロシステムズ花田 茂
Copyright 2013 Metro Systems. 2
自己紹介
● 氏名– 花田 茂(はなだ しげる)
● 所属– 株式会社メトロシステムズ
● メールアドレス– [email protected]
● Twitter– @s87
● ブログ– http://d.hatena.ne.jp/s87/
Copyright 2013 Metro Systems. 3
アジェンダ
● 外部テーブルとは?● 外部テーブルの進化● 外部データラッパの紹介● 外部データラッパの作り方
Copyright 2013 Metro Systems. 4
外部テーブルとは?
● PostgreSQLの外部にあるデータに通常のテーブルと同様にSQL文でアクセスできる特殊なテーブルです。(ビューに近い?)– SQLでは「FOREIGN TABLE」
● 外部テーブルを作成するには、外部データの種類に応じた「外部データラッパ」(FDW:Foreign Data Wrapper)が必要です。
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.
Copyright 2013 Metro Systems. 6
外部テーブルの進化(1)
● 8.4– SQL/MED基盤
● 外部データの検索は未実装● dblinkやplproxyなどの外部モジュール用に管理情報
のコンテナを提供– postgresql_fdw_validatorがdblink用に存在
● これの後方互換性維持のために「postgresql_fdw」という名前が使えないという事態になるとは…
Copyright 2013 Metro Systems. 7
外部テーブルの進化(2)
● 9.0– ***動きなし***
Copyright 2013 Metro Systems. 8
外部テーブルの進化(3)
● 9.1– 外部テーブルサポート(検索のみ)– file_fdwの追加– SERVER、USER MAPPING、FOREIGN
TABLE構文の追加
Copyright 2013 Metro Systems. 9
外部テーブルの進化(4)
● 9.2– 外部テーブルへのANALYZE– 複数候補パス(よりよいアクセスパスを選択)– 列単位のFDWオプション
Copyright 2013 Metro Systems. 10
外部テーブルの進化(5)
● 9.3– 書き込み可能な外部テーブル
● トランザクションコマンドもハンドリング可能– postgres_fdwの追加
Copyright 2013 Metro Systems. 11
さっそくデモ
● postgres_fdw– 他のPostgreSQLサーバにアクセスできるFDW– 9.1で外部テーブルと一緒に提案→却下– 9.2でANALYZE対応などと一緒に提案→却下– 9.3でようやくcontribに追加
● 長引いた原因はネーミング?● pgsql_fdw → postgresql_fdw → postgres_fdw
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
Copyright 2013 Metro Systems. 13
postgres_fdw(2)
● SERVERで定義したデータベースにUSER MAPPINGで定義したユーザで接続– ローカルユーザとリモートユーザをマッピング– サーバ×ローカルユーザでリモートユーザを切り替え
● table_nameオプションで指定したテーブルに対するSELECT文を生成してクエリを実行– リモートと別の名前で外部テーブルを定義可能
● 取得した結果をローカルのPostgreSQL内で処理し、クライアントに返却– EXPLAIN VERBOSEでリモートクエリを表示
Copyright 2013 Metro Systems. 14
postgres_fdw(3)
● WHERE句をリモートで評価して転送量削減– MUTABLE/STABLEの演算子/関数– ユーザ定義の演算子/関数
● 他のテーブルやビューとの結合が可能– 同じサーバの外部テーブル同士でも、結合はローカルに持って
きてから→大量データの場合は要注意● ORDER BYやLIMIT/OFFSETはローカル評価
– 頑張ればORDER BYはリモート評価できそうです
Copyright 2013 Metro Systems. 15
postgres_fdw(4)
● EXPLAIN結果でおかしい点があったんですが、気づきましたか?
Copyright 2013 Metro Systems. 16
postgres_fdw(5)
● 見積もりを正確にするには…– クエリ実行時にリモートの見積もりを取得
● FOREIGN TABLEかSERVERのオプションでuse_remote_estimateをtrueに設定
● クエリ実行時にEXPLAINをリモートで実行し、その見積もりでローカルの実行計画を作成
– ANALYZEしてローカルに統計情報を保持● テーブル名を明示する必要がある(対象を指定しない場合は外部テーブルをスキップ)
Copyright 2013 Metro Systems. 17
postgres_fdw(6)
● リモート接続に関する注意点– ローカル接続が続いている限り、リモート接続は保持される→リモート側をシャットダウンするとき注意
– 同じサーバ上の外部テーブルへのクエリは同じ接続で実行
● REPEATABLE READまたはSERIALIZABLEの分離レベルを使用
Copyright 2013 Metro Systems. 18
postgres_fdw(7)
● 検索だけでなく、更新も可能– INSERT/UPDATE/DELETE
● トランザクションも一部サポート– リモートトランザクションをロールバック可能– 二相コミットは未サポート
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/
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
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
Copyright 2013 Metro Systems. 22
外部データラッパの作り方
● C言語関数– FDW API(コールバック関数)を実装し、それらの関数ポインタを持っ
た構造体を返すハンドラ関数を実装– 検索のみならば7個の関数でOK
● SQL関数– ハンドラ関数のSQLラッパ関数を実装– オプションを検査するバリデータ関数を実装(必要に応じて)
● EXTENSION– 全体をEXTENSIONとしてパッケージ
● 詳細は– http://www.postgresql.org/docs/9.3/static/fdwhandler.html
Copyright 2013 Metro Systems. 23
FDW API(1)
● 検索系– プランナ
● GetForeignRelSize– テーブルサイズを見積もる
● GetForeignPaths– アクセスパスを(最低一つ)生成する– ソートキーの異なるパスなどを複数生成できる– プランナが自動的に最適なパスを選択してくれる
● GetForeignPlan– プランナが決定したアクセスパスに沿ったForeignScanプランノードを生成する
– FDW独自の情報をGetForeignPathsから受け取れる
Copyright 2013 Metro Systems. 24
FDW API(2)● 検索系
– エグゼキュータ● BeginForeignScan
– スキャン開始時に一度だけ呼ばれる● IterateForeignScan
– 上位ノードが1行必要としたときに呼ばれる– HeapTuple(行データの内部表現)を生成して返す
● ReScanForeignScan– スキャン位置を先頭に戻してほしいときに呼ばれる– NestedLoopのインナー側の場合など– スキャン結果を捨ててしまった場合は、リモートから再取得する
● EndForeignScan(検索終了)– スキャン終了時に呼ばれる– クリーンアップなど– クエリがエラー終了すると呼ばれないので要注意
Copyright 2013 Metro Systems. 25
FDW API(3)
● 検索用EXPLAIN– ExplainForeignScan
● 検索クエリのEXPLAINで呼ばれる● ForeignScanノードに表示する情報を追加する● VERBOSEモードのon/of判定も可能
● ANALYZE– AnalyzeForeignTable
ANALYZE可否を判断し、可能ならばサンプル収集関数を返す– AcquireSampleRows
● リモートデータからサンプル行を取得する
Copyright 2013 Metro Systems. 26
FDW API(4)
● 更新系– リライタ/プランナ
● AddForeignUpdateTargets– 更新時に使用するキー情報をタプル定義に追加する– postgres_fdwではCTID(タプルID)を使用
● PlanForeignModify– 更新処理に必要な情報をプライベート領域に保存する– postgres_fdwでは更新用SQL分を生成
Copyright 2013 Metro Systems. 27
FDW API(5)
● 更新系– エグゼキュータ
● BeginForeignModify– 更新処理開始時に呼ばれる
● ExecForeignInsert● ExecForeignUpdate(リモート更新実行)● ExecForeignDelete(リモート削除実行)
– 挿入/更新/削除一件ごとに一回呼ばれる– リモート側にデータを挿入/更新/削除する
● EndForeignModify(更新終了)– 更新処理終了時に呼ばれる
Copyright 2013 Metro Systems. 28
FDW API(6)
● 更新用EXPLAIN– ExplainForeignModify
● 更新クエリのEXPLAINで呼ばれる● 更新ノードに表示する情報を追加する● VERBOSEモードのon/of判定も可能
Copyright 2013 Metro Systems. 29
トランザクション管理
● リモートトランザクションサポート– トランザクション終了時に呼ばれるコールバック関数を登録しておき、そこでトランザクションコマンドを実行する
● RegisterXactCallback● RegisterSubXactCallback
– ローカルのCOMMIT/ROLLBACKの直前に呼ばれるので、このコールバックで例外が発生するとローカルトランザクションもABORTする
Copyright 2013 Metro Systems. 30
大変だな〜という人向けに
● blackhole_fdw– Andrew Dunstan氏が公開
● https://bitbucket.org/adunstan/blackhole_fdw– APIに対応する関数を持つが、何もしない→検索
しても0件、更新は空振り– FDWのひな形として利用可能
Copyright 2013 Metro Systems. 31
FDW関連の情報源
● PostgreSQL wiki– http://wiki.postgresql.org/wiki/SQL/MED
● PGXN– http://pgxn.org
Copyright 2013 Metro Systems. 32
おわりに
● ご清聴ありがとうございました。