© 2013 Metro Systems.
データハブとしてのPostgreSQL~9.3で進化した外部テーブル~
db tech showcase Tokyo 20132013-11-01
株式会社メトロシステムズ花田 茂
2© 2013 Metro Systems.
自己紹介(1)
氏名
花田 茂(はなだ しげる)
所属
株式会社メトロシステムズ
メール
ブログ
http://d.hatena.ne.jp/s87/
@s87
3© 2013 Metro Systems.
自己紹介(2)
経歴
1999年 メトロシステムズに入社、Oracleでシステム開発
2003年 PostgreSQLの運用ツール開発やコンサルティング
2010年 PostgreSQL本体開発に参加
2012年 カナダで開催されたPostgreSQL開発者会議に参加
2013年 OSS-DB Silver/Gold取得
現在 ドキュメント翻訳や日本語MLなどでも活動中
4© 2013 Metro Systems.
アジェンダ
外部テーブルとは?
外部テーブルの進化
外部テーブルを使ったデータ統合
外部データラッパの紹介
外部データラッパの作り方
5© 2013 Metro Systems.
PostgreSQLサーバ
外部テーブルとは?
PostgreSQLの外部にあるデータに通常のテーブルと同様にSQL文でアクセスできる特殊なテーブルです。(ビューに近い?)
SQL規格での名前は「FOREIGN TABLE」
外部テーブルを作成するには、外部データの種類に応じた「外部データラッパ」(FDW:Foreign Data Wrapper)が必要です。
PostgreSQLクライアント
テーブルデータファイル
SQL
検索結果
外部データ
外部テーブル
外部データラッパ
6© 2013 Metro Systems.
そもそも外部データって?
PostgreSQLからアクセスできるもの全て
OSファイル
CSVファイル、JSONファイル、ログファイル、Etc.
リレーショナルデータベース
PostgreSQL、Oracle、MySQL、SQLite3、Etc.
NoSQLデータベース
Hadoop、Redis、Mongo、Neo4J、Etc.
Webサービス
twitter、RESTアプリケーション、Etc.
その他
Amazon S3、コマンド実行結果、Etc.
7© 2013 Metro Systems.
外部テーブルの進化(1)
8.4(2009年)
SQL/MED基盤
外部データラッパ関連オブジェクトサポート外部データラッパ、サーバ、ユーザマッピング
外部データの検索は未実装
dblinkやplproxyなどの外部モジュール用に管理情報のコンテナを提供
postgres=> SELECT dblink_connect('con', 'host=foo,dbname=bar');...postgres=> SELECT * FROM dblink('con', 'SELECT id, name FROM remote_table WHERE col = ''value'' ORDER BY key') AS t (id int, name text);
クエリを文字列で渡す→シンタックスチェックなし
結果の列型定義を明示する必要がある
8© 2013 Metro Systems.
外部テーブルの進化(2)
9.0(2010年)
***動きなし***
9© 2013 Metro Systems.
外部テーブルの進化(3)
9.1(2011年)
外部テーブルサポート(検索のみ)
file_fdwの追加
COPYコマンドがサポートするフォーマット(CSV、タブ区切り、独自バイナリ)のファイルをロード不要で参照可能に!
外部データの更新は未実装
外部PostgreSQLは(標準では)未対応
MySQLでいうCSVストレージエンジン
のようなもの
10© 2013 Metro Systems.
外部テーブルの進化(4)
9.2(2012年)
外部テーブルの統計情報取得
外部データの内容に応じた実行計画を生成
【注意】ANALYZEコマンドにテーブル名を明示すること!
複数候補パス(よりよいアクセスパスを選択)
外部データへのアクセス方法が複数ある場合に、最適な方法をPostgreSQLのプランナが選択
列単位のFDWオプション
外部データの統計情報の取得や複数候補パスサポートにより、よりよい実行計画を選択可能に
外部データの更新は未実装
11© 2013 Metro Systems.
外部テーブルの進化(5)
9.3(2013年)
書き込み可能な外部テーブル
トランザクションコマンドもハンドリング可能
postgres_fdwの追加
外部データが更新可能に!
外部のPostgreSQLのテーブルをローカルテーブルと同様に参照/更新可能
二相コミットは未実装
12© 2013 Metro Systems.
外部テーブルの進化(6)
9.4(現在開発中)
テーブル継承サポート
外部テーブルを子テーブルとして定義
パーティションキーによるシャーディングが可能に
リモートでの結合や集約
分析系クエリなどで負荷分散や転送量削減
外部データ
外部テーブル
外部データ
外部テーブル
外部データ
外部テーブル
親テーブル
結果自動的に
結果をマージ
検索
13© 2013 Metro Systems.
外部テーブルのデモ
postgres_fdw
他のPostgreSQLサーバにアクセスできるFDW
9.1で外部テーブルと一緒に提案→却下
9.2でANALYZE対応などと一緒に提案→却下
9.3でようやくcontribに追加
長引いた原因はネーミング?pgsql_fdw → postgresql_fdw → postgres_fdw
14© 2013 Metro Systems.
postgres_fdw(1)
まずはEXTENSIONを作成
自動的にFOREIGN DATA WRAPPERも作成
接続先サーバをSERVERで定義
オプション:host、port、dbnameなどのlibpqオプション
リモートユーザをUSER MAPPINGで定義
オプション:user、password
外部データ構造をFOREIGN TABLEで定義
オプション:table_name
15© 2013 Metro Systems.
postgres_fdw(2)
SERVERで定義したデータベースにUSER MAPPINGで定義したユーザで接続
ローカルユーザとリモートユーザをマッピング
サーバ×ローカルユーザでリモートユーザを切り替え
table_nameオプションで指定したテーブルに対するSELECT文を生成してクエリを実行
リモートと別の名前で外部テーブルを定義可能
取得した結果をローカルのPostgreSQL内で処理し、クライアントに返却
EXPLAIN VERBOSEでリモートクエリを表示
16© 2013 Metro Systems.
postgres_fdw(3)
WHERE句をリモートで評価して転送量削減
MUTABLE/STABLEの演算子/関数
ユーザ定義の演算子/関数
他のテーブルやビューとの結合が可能
同じサーバの外部テーブル同士でも、結合はローカルに持ってきてから→大量データの場合は要注意
ORDER BYやLIMIT/OFFSETはローカル評価
頑張ればORDER BYはリモート評価できそうです
17© 2013 Metro Systems.
postgres_fdw(4)
見積もりを正確にするには…
クエリ実行時にリモートの見積もりを取得
FOREIGN TABLEかSERVERのオプションでuse_remote_estimateをtrueに設定
クエリ実行時にEXPLAINをリモートで実行し、その見積もりでローカルの実行計画を作成
ANALYZEしてローカルに統計情報を保持
テーブル名を明示する必要がある(対象を指定しない場合は外部テーブルをスキップ)
18© 2013 Metro Systems.
postgres_fdw(5)
リモート接続に関する注意点
ローカル接続が続いている限り、リモート接続は保持される→リモート側をシャットダウンするとき注意
同じサーバ上の外部テーブルへのクエリは同じ接続で実行
REPEATABLE READまたはSERIALIZABLEの分離レベルを使用
19© 2013 Metro Systems.
postgres_fdw(6)
検索だけでなく、更新も可能
INSERT/UPDATE/DELETE
トランザクションも一部サポート
リモートトランザクションをロールバック可能
二相コミットは未サポート
20© 2013 Metro Systems.
外部テーブルによるデータ統合(1)
ログデータ
ログをCSV形式で出力し、file_fdwで参照
ログをSQLで検索可能
ウィンドウ関数や集約関数などで統計処理も可能
21© 2013 Metro Systems.
外部テーブルによるデータ統合(2)
別システムのマスタデータ流通
別システムのマスタテーブルを外部テーブルで参照
エクスポート/インポート不要でリアルタイムに変更に追従
9.3の新機能のマテリアライズド・ビューと組み合わせると、スナップショット取得も可能
22© 2013 Metro Systems.
外部テーブルによるデータ統合(3)
旧システムデータの活用
旧システムのデータを外部テーブル経由で参照することで、データ流通基盤を構築せずにデータ連携が可能
新旧システム間のデータ移行にも利用可能
23© 2013 Metro Systems.
外部テーブルによるデータ統合(4)
簡易EAIサーバとしての利用
複数種類のデータソースをPostgreSQLを経由して一本化
異種データソース間の結合や中間表の作成なども使い慣れたSQL文だけで可能
最終結果はCOPYコマンドで簡単にCSV化可能
24© 2013 Metro Systems.
サードパーティの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/
25© 2013 Metro Systems.
サードパーティの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/
ldap_fdw
http://pgxn.org/dist/ldap_fdw/
neo4j_fdw
https://github.com/nuko-yokohama/neo4j_fdw
hadoop_fdw
http://www.bigsql.org/se/hadoopfdw/
26© 2013 Metro Systems.
サードパーティの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
27© 2013 Metro Systems.
外部データラッパの作り方
C言語関数
FDW API(コールバック関数)を実装し、それらの関数ポインタを持った構造体を返すハンドラ関数を実装
検索のみのサポートならば、7個の関数を実装すればOK!
SQL関数
ハンドラ関数のSQLラッパ関数を実装
オプションを検査するバリデータ関数を実装(必要に応じて)
EXTENSION
全体をEXTENSIONとしてパッケージ
詳細は
http://www.postgresql.org/docs/9.3/static/fdwhandler.html
28© 2013 Metro Systems.
FDW API(1)
検索系
プランナGetForeignRelSize
テーブルサイズを見積もるGetForeignPaths
アクセスパスを(最低一つ)生成するソートキーの異なるパスなどを複数生成できるプランナが自動的に最適なパスを選択してくれる
GetForeignPlan
プランナが決定したアクセスパスに沿ったForeignScanプランノードを生成するFDW独自の情報をGetForeignPathsから受け取れる
29© 2013 Metro Systems.
FDW API(2)
検索系
エグゼキュータBeginForeignScan
スキャン開始時に一度だけ呼ばれるIterateForeignScan
上位ノードが1行必要としたときに呼ばれるHeapTuple(行データの内部表現)を生成して返す
ReScanForeignScan
スキャン位置を先頭に戻してほしいときに呼ばれるNestedLoopのインナー側の場合などスキャン結果を捨ててしまった場合は、リモートから再取得する
EndForeignScan(検索終了)スキャン終了時に呼ばれるクリーンアップなどクエリがエラー終了すると呼ばれないので要注意
30© 2013 Metro Systems.
FDW API(3)
検索用EXPLAIN
ExplainForeignScan
検索クエリのEXPLAINで呼ばれる
ForeignScanノードに表示する情報を追加する
VERBOSEモードのon/off判定も可能ANALYZE
AnalyzeForeignTable
ANALYZE可否を判断し、可能ならばサンプル収集関数を返す
AcquireSampleRows
リモートデータからサンプル行を取得する
31© 2013 Metro Systems.
FDW API(4)
更新系
リライタ/プランナAddForeignUpdateTargets
更新時に使用するキー情報をタプル定義に追加するpostgres_fdwではCTID(タプルID)を使用
PlanForeignModify
更新処理に必要な情報をプライベート領域に保存するpostgres_fdwでは更新用SQL分を生成
32© 2013 Metro Systems.
FDW API(5)
更新系
エグゼキュータBeginForeignModify
更新処理開始時に呼ばれるExecForeignInsert
ExecForeignUpdate(リモート更新実行)
ExecForeignDelete(リモート削除実行)挿入/更新/削除一件ごとに一回呼ばれる
リモート側にデータを挿入/更新/削除する
EndForeignModify(更新終了)更新処理終了時に呼ばれる
33© 2013 Metro Systems.
FDW API(6)
更新用EXPLAIN
ExplainForeignModify
更新クエリのEXPLAINで呼ばれる
更新ノードに表示する情報を追加する
VERBOSEモードのon/off判定も可能
34© 2013 Metro Systems.
トランザクション管理
リモートトランザクションサポート
トランザクション終了時に呼ばれるコールバック関数を登録しておき、そこでトランザクションコマンドを実行する
RegisterXactCallback
RegisterSubXactCallback
ローカルのCOMMIT/ROLLBACKの直前に呼ばれるので、このコールバックで例外が発生するとローカルトランザクションもABORTする
35© 2013 Metro Systems.
大変だな〜という人向けに
blackhole_fdw
Andrew Dunstan氏が公開
https://bitbucket.org/adunstan/blackhole_fdw
APIに対応する関数を持つが、何もしない→検索しても0件、更新は空振り
FDWのひな形として利用可能
36© 2013 Metro Systems.
FDW関連の情報源
PostgreSQL wiki
http://wiki.postgresql.org/wiki/SQL/MED
PGXN
http://pgxn.org
37© 2013 Metro Systems.
おわりに
ご清聴ありがとうございました。
38© 2013 Metro Systems.
お知らせ
PostgreSQL入門トレーニング
2013年からOSS-DB Silverに対応したトレーニングコースを提供しています。
http://www.metrosystems.co.jp/education/
商用データベースの構築・運用で培ったノウハウを盛り込んだ独自テキストを使用し、商用製品とPostgreSQLを対比しながらハンズオン環境で基本的な使い方を習得できます!
11/21・22の二日間は、初回につき特別に無料で開催いたします。お問い合わせは[email protected]まで!