PostgreSQL9.2新機能 新潟オープンソースセミナー2012 2012-11-03 日本PostgreSQLユーザ会 花田 茂
May 26, 2015
PostgreSQL9.2新機能
新潟オープンソースセミナー2012
2012-11-03
日本PostgreSQLユーザ会花田 茂
日本PostgreSQLユーザ会 2
謝辞 この資料は SRA OSS, Inc. の以前の講演資料をベー
スにしております。ご提供承諾いただきありがとうございます。
日本PostgreSQLユーザ会 3
自己紹介 花田 茂(はなだ しげる)
所属: 株式会社メトロシステムズ(東京・池袋) Twitter: @s87 blog: http://d.hatena.jp/s87/ Mail: [email protected]
PostgreSQLとの関わり 2003年頃から周辺ツール開発、性能検証など 2009年頃からPostgreSQL本体開発(SQL/MED他) 2011年から日本語ドキュメント翻訳
日本PostgreSQLユーザ会 4
PostgreSQL のこれまでと現在
日本PostgreSQLユーザ会 5
改めて・・・ PostgreSQL とは 代表的なオープンソースRDBMSのひとつ Ingres(1970~ UCB) を先祖に持つ
PostgreSQL 6.0 (1996 ~) から 15年以上の歴史 BSDタイプのライセンスで配布
PostgreSQL Global Development Group と University of California が著作権を持つ
ひとつのオーナー企業、オーナー個人を持たない PostgreSQL開発に時間を割く技術者を提供している
企業がいくつかある/その企業群も少しずつ変遷している
日本PostgreSQLユーザ会 6
Contributors
PostgreSQL開発体制
Major Contributors
Core Team
Josh BerkusTom LanePeter EisentrautMagnus HaganderBruce MomjianDave Page
藤井雅雄板垣貴裕原田均石井達夫 :30~40名
支援企業
開発コミュニティ
日本PostgreSQLユーザ会 7
PostgreSQLの歩み
PG 7.0 PG 7.1 PG 7.2 PG 7.3 PG 7.4 PG 8.0 PG 8.1 PG 8.2 PG 8.3 PG 8.4 PG 9.0 PG 9.10
20000
40000
60000
80000
100000
120000
PostgreSQLのコードサイズとリリース
コードサイズ
(byt
e)
更新の高速化ビットマップ
スキャンプリペアドステートメント
並列実行VACUUM外部キー、
JOIN構文
トランザクションログ
スキーマPITR、
Windows
CPUスケール
|2001年
4月
|2005年
1月
|2009年
7月
|2006年12月
|2002年
11月
ウィンドウ関数再帰SQL
レプリケーションWindows 64bit
|2011年
9月
同期レプリケーション外部テーブル
日本PostgreSQLユーザ会 8
9.1 のおさらい
日本PostgreSQLユーザ会 9
9.1 のおさらい(1) (準)同期レプリケーションに対応
9.0 でサポートした物理レプリケーションを拡張 pg_basebackup など利便性向上
マスターサーバ スタンバイサーバPostgresWAL
データPostgres
WALデータ
マスターサーバ スタンバイサーバPostgresWAL
データPostgres
WALデータ
WAL情報転送
適用
リクエスト
クライアント
日本PostgreSQLユーザ会 10
9.1 のおさらい(2) 外部テーブル(SQL/MED)の枠組み
CSVファイルのラッパーが付属 拡張モジュール枠組み(CREATE EXTENSION) UNLOGGEDテーブル(高速/低信頼) 空間近傍検索(k-NN GiST インデックス対応) SE-Postgres(SE-Linux準拠のセキュリティ) N-gram全文検索 述語ロックSERIALIZABLE、更新WITH句、
ビュートリガ、カラムロケール指定、etc
日本PostgreSQLユーザ会 11
PostgreSQL 9.2 の拡張
日本PostgreSQLユーザ会 12
CPUスケール対応 Readは コア数64までスケール
⇒ PostgreSQL 8.2 で改良 コア数 8~12 まで
PgCon 2012Robert Haas 発表資料 (2012/5/18) より
・Fast Pathロック・直列化部分を短時間に・WALディスク同期を改善
日本PostgreSQLユーザ会 13
書き込みトランザクション改善 グループコミットの改善で、書き込みが大量に発生するようなケースの性能が向上 SRA OSS Inc.様のセミナー資料で測定結果が参照可
能 注意:commit_delayがコミット以外のWALフ
ラッシュにも適用されるようになった
日本PostgreSQLユーザ会 14
Index Only Scan(1)
インデックスだけを読んで処理できる テーブルデータにアクセスが省略できるので、通常の
検索より高速! ただし、クエリに必要な全ての列(SELECT
句、WHERE句、Etc.)がインデックス定義に含まれていることが条件
類似機能は他のDBMSにも MySQLでの「Covering Index」 Oracleでの「INDEX (FAST) FULL SCAN」
日本PostgreSQLユーザ会 15
Index Only Scan(2)
postgres=# EXPLAIN (ANALYZE, BUFFERS)postgres-# SELECT count(*) FROM pgbench_accounts; QUERY PLAN----------------------------------------------------------- Aggregate (cost=288935.08..288935.09 rows=1 width=4) (actual time=13486.255..13486.255 rows=1 loops=1) Buffers: shared hit=32 read=163903 -> Seq Scan on pgbench_accounts (cost=0.00..263935.06 rows=10000006 width=4) (actual time=23.478..12261.668 rows=10000000 loops=1) Buffers: shared hit=32 read=163903 Total runtime: 13486.385 ms(5 rows)
実行例(enable_indexonlyscan=off)
日本PostgreSQLユーザ会 16
Index Only Scan(3)
postgres=# EXPLAIN (ANALYZE, BUFFERS)postgres-# SELECT count(*) FROM pgbench_accounts; QUERY PLAN -------------------------------------------------------------- Aggregate (cost=284699.32..284699.33 rows=1 width=0) (actual time=2466.584..2466.585 rows=1 loops=1) Buffers: shared read=27328 -> Index Only Scan using pgbench_accounts_pkey on pgbench_accounts (cost=0.00..259699.31 rows=10000006 width=0) (actual time=0.093..1516.373 rows=10000000 loops=1) Heap Fetches: 0 Buffers: shared read=27328 Total runtime: 2466.709 ms(6 rows)
実行例(enable_indexonlyscan=on)
Seq Scanよりも約5.5倍高速!
日本PostgreSQLユーザ会 17
Index Only Scan(4)
なんで今までなかったの? PostgreSQLでは、同時実行性と読み取り一貫性を保
証するために、追記型アーキテクチャを採用している 更新や削除が発生すると、行の新しいバージョンを
INSERTと同じようにページ内の空き領域に追加する 検索時には、見つかったタプルが自トランザクション
が参照すべきバージョンかを判断する 9.2から可視性マップ(Visibility Map)がクラッシュ
セーフになり、(条件付ではあるが)テーブルデータを見なくてもタプルの可視性判定ができるようになった
日本PostgreSQLユーザ会 18
Index Only Scan(5)
可視性マップって何? PostgreSQLが「ページ内のすべてのタプルが全ての
現存トランザクションから可視であるか?」を保存しているビットマップのこと
「<relfilenode>_vm」というファイルに保存されている
VACUUM中に内容を更新する
日本PostgreSQLユーザ会 19
Index Only Scan(6)
Index Only Scanの流れ 通常のインデックススキャンと同様にインデックスを
たどってインデックスタプルを取得 テーブルタプルのブロック番号とページ内オフセットが判明
テーブルタプルに対応するVisibility Mapページを取得 Visibility Mapページからテーブル参照要否が判明
テーブルページからテーブルタプル取得 テーブルを見る必要がなければスキップ
(インデックス|テーブル)タプルから結果生成
日本PostgreSQLユーザ会 20
Index Only Scan(7)
要VACUUM! もちろんautovacuumでOK ANALYZEでは可視性マップは更新されません! ロングトランザクションに注意!
postgresexecutor
visibilitymap
更新されないデータは同じページに! 可視性マップはページ単位の管理なの
で、更新されないレコードが同じページに集まると効果的 不要!
日本PostgreSQLユーザ会 21
レプリケーション拡張(1)
カスケード構成に対応
スタンバイサーバPostgres
マスターサーバPostgres
スタンバイサーバPostgres
スタンバイサーバ
Postgres
レプリケーション
レプリケーション
レプリケーション
日本PostgreSQLユーザ会 22
レプリケーション拡張(2)
カスケード構成に対応
スタンバイサーバPostgres
マスターサーバPostgres
スタンバイサーバPostgres
スタンバイサーバ
Postgres レプリケーション
レプリケーション
レプリケーション
pg_basebackup
pg_receivexlog
オンライン物理バックアップをスタンバイから取れる
マスタサーバの負荷軽減
日本PostgreSQLユーザ会 23
レプリケーション拡張(3)
同期レプリケーションにremote_writeが追加 GUCパラメータ「synchronous_commit」で設定 従来の「on」設定より軽量・低信頼な同期レプリケー
ション設定値 意味on 自機のディスク同期を待つ
レプリケーション先のディスク同期を待つremote_write 自機のディスク同期を待つ
レプリケーション先の書き込み完了を待つlocal 自機のディスク同期を待つ
レプリケーション先の処理は待たないoff 自機のディスク同期を待たない
レプリケーション先の処理は待たない
安全
高速
日本PostgreSQLユーザ会 24
レプリケーション拡張(4)
remote_writeの場合は 自機でのWAL書き込み+ディスク同期 レプリケーション先でのWAL書き込み
マスターサーバ スタンバイサーバPostgresPostgres
WAL
クライアント
WAL①
COMMIT発行
②WAL書き込み&ディスク同期
③WAL転送
④WAL書き込み
⑤WAL受領通知
⑥COMMIT完了
日本PostgreSQLユーザ会 25
レプリケーション拡張(5)
pg_receivexlogコマンドの追加 スタンバイサーバとして上流からストリーミングWAL
を受け取ってファイルに保存するコマンド WALの多重化を実現できる WALが保存されたディレクトリはリカバリ時にアーカ
イブWAL保存場所として使用可能 【注意】バックアップラベルファイルやヒストリファ
イルは保存されない pg_xlog_location_diff()関数の追加
レプリケーションがどの程度遅れているかを知るのに便利
日本PostgreSQLユーザ会 26
範囲データ型(1)
下限値・上限値で範囲を表現するデータ型 境界値を含む/含まないを指定可能
'[1,3)'は「1以上、3未満」を表す 境界値にNULLを使うと無限区間に
基本的なデータ用の範囲型と演算子は組み込みで提供 CREATE TYPE AS RANGE文で新しい範囲型も定義可能
データ型 要素データ型int4range int
int8range bigint
numrange numeric
tsrange timestamp
tstzrange timestamptz
daterange date
演算子 型 意味A && B bool AとBが重なっているA @> B bool AがBを含むA -|- B bool AとBが隣接しているA * B 範囲 AとBの共通範囲A + B 範囲 AとBの合併範囲A - B 範囲 AからBを除いた範囲
日本PostgreSQLユーザ会 27
範囲データ型(2)
8.4で導入された排他制約と組み合わせることで、「重なり」がないかを検査する制約を定義可能
postgres=# \d reservation Table "public.reservation" Column | Type | Modifiers-------------+-----------+----------- id | integer | not null room_id | integer | not null during | tstzrange | not null reserver_id | integer | memo | text |Indexes: "reservation_pkey" PRIMARY KEY, btree (id) "reservation_during_excl" EXCLUDE USING gist (room_id WITH =, during WITH &&)
同じ部屋番号で時間帯が重なる
予約は不可という制約*Note*
GiSTでint型を使うにはcontrib/btree_gist
が必要
日本PostgreSQLユーザ会 28
範囲データ型(3)
8.4で導入された排他制約と組み合わせることで、「重なり」がないかを検査する制約を定義可能
postgres=# INSERT INTO reservation (room_id, during, reserver)postgres-# VALUESpostgres-# (2, '[2012-06-16 14:00,2012-06-16 14:45)'::tstzrange, 1);INSERT 0 1postgres=# INSERT INTO reservation (room_id, during, reserver)postgres-# VALUESpostgres-# (2, '[2012-06-16 14:30,2012-06-16 14:45)'::tstzrange, 1);ERROR: conflicting key value violates exclusion constraint "reservation_during_excl"DETAIL: Key (room, during)=(2, ["2012-06-16 14:30:00+09", "2012-06-16 17:00:00+09")) conflicts with existing key (room, during)=(2, ["2012-06-16 14:00:00+09","2012-06-16 14:45:00+09")).
日本PostgreSQLユーザ会 29
JSONデータ型(1)
格納時の構文チェックのついたtext型 PostgreSQLの行や配列から変換可能
array_to_json() row_to_json()
日本語の使用は次リリース(Beta3?)から pl/v8*1ではJavaScriptで関数が書けるので親和
性が高い?
*1 http://code.google.com/p/plv8js/wiki/PLV8
日本PostgreSQLユーザ会 30
JSONデータ型(2)
使用例(テーブル定義)postgres=# \d users Table "public.users" Column | Type | Modifiers--------+---------+----------- id | integer | not null name | text | not null data | json |Indexes: "users_pkey" PRIMARY KEY, btree (id)
postgres=# SELECT * FROM users ORDER BY id; id | name | data----+------+------------------------------------------------------------ 1 | foo | {"last_access":"2012-01-01 12:34:56","features":"[1,3,5]"} 2 | bar | {"last_access":"2011-11-25 23:42:41","features":"[2,3,6]"}(2 rows)
日本PostgreSQLユーザ会 31
JSONデータ型(3)
使用例(array_to_json()関数)
postgres=# SELECT array_to_json('{1,2,3}'::int[]); array_to_json--------------- [1,2,3](1 row)
postgres=#
日本PostgreSQLユーザ会 32
JSONデータ型(4)
使用例(row_to_json()関数)postgres=# SELECT row_to_json(row(id, name))postgres-# FROM foo WHERE id = 1; row_to_json-------------------------- {"f1":1,"f2":"name_1"}(1 row)
postgres=# SELECT row_to_json(t) FROMpostgres-# (SELECT id, name FROM t WHERE id = 1) t; row_to_json-------------------------- {"id":1,"name":"name_1"}(1 row)
日本PostgreSQLユーザ会 33
JSONデータ型(5)
PGXNに外部モジュールとしてjson_accessorsが出ました! http://pgxn.org/dist/json_accessors/
どんな機能が? json_array_to_<type>_array()
JSON配列からPostgreSQL型配列に変換 json_get_<type>()
JSONから属性名指定でスカラ値を取得 json_get_<type>_array()
JSONから属性名指定で配列値を取得
日本PostgreSQLユーザ会 34
JSONデータ型(6)
使用例(json_get_text()関数)postgres=# select * from users order by id;-[ RECORD 1 ]----------------------------------------------------------id | 1name | Saitoattributes | {"carrior":"softbank", "model":"iPhone-5","maker":"Apple"}-[ RECORD 2 ]----------------------------------------------------------id | 2name | Takahashiattributes | {"carrior":"au", "model":"A01","maker":"iida"}postgres=# SELECT name FROM users WHEREpostgres-# json_get_text(attributes::text, 'maker') = 'Apple'; name ------- Saito(1 row) 引数がtext型なので、
キャストが必要です
日本PostgreSQLユーザ会 35
カスタムプラン EXECUTEのパラメータを考慮したプランを生成postgres=# PREPARE s(int) AS SELECT * FROM t WHERE id < $1;PREPAREpostgres=# EXPLAIN (COSTS off) EXECUTE s(1); QUERY PLAN------------------------------ Index Scan using t_pkey on t Index Cond: (id < 1)(2 rows)
postgres=# EXPLAIN (COSTS off) EXECUTE s(1000000); QUERY PLAN-------------------------- Seq Scan on t Filter: (id < 1000000)(2 rows)
日本PostgreSQLユーザ会 36
Parameterized Paths(1)
Nested LoopのInner側で、直接結合しないテーブルの値を使ったインデックススキャンが可能になった
これまでは、直接結合する相手テーブルの値または固定値のみが使用できた
インデックススキャンの適用可能性が広がり、複雑な結合のあるクエリに性能向上のチャンスが生まれた
日本PostgreSQLユーザ会 37
Parameterized Paths(2)
9.1ではbはSeqScanだが…
postgres=# EXPLAIN (COSTS false) SELECT 1 FROM c WHERE EXISTS (postgres(# SELECT * FROM a JOIN b USING (b_id)postgres(# WHERE b.c_id = c.c_id) AND c.value = 1; QUERY PLAN------------------------------------------- Nested Loop Semi Join Join Filter: (c.c_id = b.c_id) -> Index Scan using c_value_key on c Index Cond: (value = 1) -> Nested Loop -> Seq Scan on b -> Index Scan using a__b_id on a Index Cond: (b_id = b.b_id)(8 rows)
日本PostgreSQLユーザ会 38
Parameterized Paths(3)
9.2ではcテーブルの値を使うIndexScanに!
postgres=# EXPLAIN (COSTS false) SELECT 1 FROM c WHERE EXISTS (postgres(# SELECT * FROM a JOIN b USING (b_id)postgres(# WHERE b.c_id = c.c_id) AND c.value = 1; QUERY PLAN ------------------------------------------------ Nested Loop Semi Join -> Index Scan using c_value_key on c Index Cond: (value = 1) -> Nested Loop -> Index Scan using b__c_id on b Index Cond: (c_id = c.c_id) -> Index Only Scan using a__b_id on a Index Cond: (b_id = b.b_id)(8 rows)
日本PostgreSQLユーザ会 39
その他の拡張(1)
NOT VALID CHECK制約 CHECK制約作成時に既存のデータを検査しない 制約作成以降のデータ追加・更新は検査される ALTER TABLE VALIDATE CONSTRAINT <制約名>
で現在のデータを検査可能 NOT INHERIT CHECK制約
継承関係を辿って子テーブルに制約が伝搬しない 親テーブルにデータを入れたくない、といったケース
で有効
日本PostgreSQLユーザ会 40
その他の拡張(2)
インデックス Unbalanced treeをサポートするSP-GiST(Space-
Partitioned GiST)アクセスメソッドの追加 セキュリティ
セキュリティバリアビュー VIEWのsecurity_barrier属性と関数のLEAKPROOF属性を組
み合わせることで、関数を通じてアクセス不可のカラム内容が漏れることを防ぐ
CREATE や DROP もSE-Postgresで管理可能 ALTER TABLEでの .. ALTER TYPE の改善
全レコード書き替えは必要なときだけ
日本PostgreSQLユーザ会 41
その他の拡張(3)
管理機能 contrib/pg_stat_statement
類似(定数値だけが異なるなど)SQLを集約してくれる I/O情報も収集
実行時統計情報の拡充 pg_stat_bgwriter チェックポイント動作の情報 pg_stat_database デッドロックカウンタ
libpq 単一行モード(プロトコルレベルカーソル)のサポー
ト
日本PostgreSQLユーザ会 42
その他の拡張(4)
省電力 定期的にスリープから復帰する補助プロセスを減らす
ことで、処理が無い時間帯においてサーバ省電力機能が効果的に働く 11個/秒→0.4個/秒
各種プランナ、executor改善 高速ソート 定数式のキャッシュ利用 配列内の各要素まで考慮したコスト見積もり
日本PostgreSQLユーザ会 43
その他の拡張(5)
psqlメタコマンド ¥x auto
横幅の広い結果を自動的に縦表示に ¥setenv
psqlコマンドの環境変数をセッション中に変更可能 ¥timing
エラーになった処理も時間表示
日本PostgreSQLユーザ会 44
ご清聴ありがとうございました
日本PostgreSQLユーザ会 45
日本PostgreSQLユーザ会のご紹介 NPO法人として活動中
http://www.postgresql.jp/ 活動目的
PostgreSQLの研究開発および普及促進 勉強会開催 日本語ドキュメント翻訳 メーリングリスト運営
PostgreSQLに関する情報の公開 Let's Postgres(http://lets.postgresql.jp/)
会員相互および外部との技術的・人間的交流