postgresql 10 新機能 @オープンセミナー香川 2017
TRANSCRIPT
PostgreSQL 10 新機能オープンセミナー香川 2017
2017.09.09
日本PostgreSQLユーザ会 花田茂
自己紹介
•花田 茂(Shigeru HANADA)•クラウドな会社でサポートエンジニア
•PostgreSQLの開発に参加�主に外部データラッパ機能
• SNS� Twitter: @s87� https://www.slideshare.net/babystarmonja/
そもそも「PostgreSQL」とは?
•読み方は「ポストグレスキューエル」�または「ポストグレス」「ポスグレ」
•オープンソースのRDBMS� https://www.postgresql.org
•開発主体が企業ではなくコミュニティ� PGDG: PostgreSQL Global Development Group
•PostgreSQLライセンス(BSD系)�改変可能、ソース提供不要
そもそも「PostgreSQL」とは?
•開発系の機能� SQL標準に準拠した構文のサポート
� 集計用途のウィンドウ関数なども
�効率的な実行計画� 各種スキャン、結合(Nested Loop、Merge Join、Hash Join)
�豊富なインデックス種別� B-Tree、Hash、GiST、SP-GiST、GIN、BRIN
�豊富なデータ型と演算子� JSON、幾何(図形)データ、IPアドレス、配列、範囲型
�豊富なストアドプロシージャ・ファンクション言語� PL/pgSQL、SQL、JavaScript(v8)、Python、etc.
そもそも「PostgreSQL」とは?
•運用管理系の機能�レプリケーション(同期・非同期)
� MySQLの用語でいう「準同期」レプリケーション
� 物理レプリケーション
� カスケードも可能
�リモートバックアップ� pg_basebackupでネットワーク越しに物理バックアップを取得
� PITR(Point in Time Recovery)� 任意のタイミングを指定してリカバリ可能
� GUIツール� pgAdmin3/pgAdmin4
そもそも「PostgreSQL」とは?
•アーキテクチャ的な特徴�プロセスモデル
� スレッドモデルと比較して接続確立が比較的重い
� pgpool-IIやアプリケーションサーバーでの接続プーリングをおすすめ
�追記型MVCC� 更新・削除時に古いバージョンに削除フラグを立てて残す
� VACUUMが必要、ただし現在はデフォルトで自動化
� OracleやMySQLは上書き型で、UNDO領域を持つ
� WALベースのストリーミングレプリケーション� 物理レプリケーションのためレプリケーションエラーは発生しづらい
� メジャーバージョンを跨げないのでローリングアップグレードできない
そもそも「PostgreSQL」とは?
•プラガブル(Pluggable)�関数
� SQL、PL/pgSQL、Tcl、Perl、Python、JavaScript(V8)、R、Etc.�外部データラッパ
� PostgreSQL、File、MySQL、Oracle、Redis、MongoDB、Twitter、Etc.�カスタムスキャン
� Pg-Strom (GPGPUを使ってデータを超並列処理)� http://strom.kaigai.gr.jp
� 手続き言語� 好きな言語で関数を書ける!
�インデックス
そもそも「PostgreSQL」とは?
•他のDBMSとの比較� PostgreSQLとMySQL、使うならどっち? データベース専門家が8つの視点で徹底比較!(エンジニアHub)� https://employment.en-japan.com/engineerhub/entry/2017/09/05/110000
�そーだいなるらくがき帳今こそ知りたい、2大OSSデータベースのMySQLとPostgreSQLの違いについて話をしてきた(そーだいなるらくがき帳)� http://soudai.hatenablog.com/entry/2017/05/27/173055
バージョンについて
•バージョン表記�従来は 「 9.6.5」のように三つの数字で表記
� 最初の二つがメジャーバージョン、新機能追加
� 最後の一つがマイナーバージョン、バグフィックスなど
�次バージョンから「10.1」のように二つの数字で表記� 最初がメジャーバージョン、新機能追加
� 最後がマイナーバージョン、バグフィックスなど
•概ね一年に一度メジャーバージョンリリース�現在のSTABLEは9.6.5�次バージョンの10は現在Beta4、もうすぐRC?
最近のバージョンの推移
• 9.5� UPSERTサポート
� INSERT ~ ON CONFLICT DO UPDATE ~� BRIN(Block Range Index)
� ブロック範囲でインデックスをはる、大規模テーブル向け機能
� Row-level Security� 列値とクエリ実行ユーザーなどにもとづいてアクセス権を設定
�同時実行性能の改善� ロック改善などで多CPUコア環境でよりスケール可能に
最近のバージョンの推移
• 9.6�パラレルクエリ
� スキャン、結合、集約を並列に実行
�マルチ同期レプリケーション� 複数のレプリカに同期レプリケーションが可能に
� FDW(Foreign Data Wrapper)機能強化� DATABASE LINKやリンクサーバーのような機能
� ソートや結合を外部データソースで実行可能に
最近のバージョンの推移• 10 (9/9現在Beta 4)�パラレルクエリの改良
� B-Treeインデックススキャン、ビットマップスキャン、マージ結合、一部のサブクエリ
�ロジカルレプリケーション� 論理レプリケーションが可能に
�ネイティブパーティショニング� テーブル継承による擬似パーティショニングから構文サポートに
�マルチ同期レプリケーションでのQuorum Commit� N台に同期すればOK
�その他� ハッシュインデックスのWALサポート(クラッシュセーフ)� 複合列での統計情報のサポート
最近のバージョンの推移• 10 (9/9現在Beta 4)�パラレルクエリの改良
� B-Treeインデックススキャン、ビットマップスキャン、マージ結合、一部のサブクエリ
�ロジカルレプリケーション� 論理レプリケーションが可能に
�ネイティブパーティショニング� テーブル継承による擬似パーティショニングから構文サポートに
�マルチ同期レプリケーションでのQuorum Commit� N台に同期すればOK
�その他� ハッシュインデックスのWALサポート(クラッシュセーフ)� 複合列での統計情報のサポート
詳しくはリリースノートで!https://www.postgresql.org/docs/10/static/release-10.html
パラレルクエリ
パラレルクエリの概要
•WorkerとGather�パラレル度数に合わせてWorkerを起動して処理
�各Workerの出力をGatherしてまとめる
Gather
Worker Worker Worker
パラレルクエリ関連のGUC(1)•パラレル処理の制御� max_parallel_workers_per_gather
� Gatherごとの最大Worker数� max_parallel_workers
� インスタンス全体での最大Worker数� min_parallel_table_scan_size
� パラレルクエリを検討する最小テーブルデータ量
� min_parallel_index_scan_size� パラレルクエリを検討する最小インデックスデータ量
� force_parallel_mode� デバッグ用途などでパラレルクエリを強制
パラレルクエリ関連のGUC(2)•実行計画作成時のコスト計算など� parallel_setup_cost
� パラレルクエリでのWorker起動コスト
� parallel_tuple_cost� パラレルクエリでのタプル転送コスト
パラレルクエリの例
•標準ベンチマークツールのpgbenchを使用
•「支店ごとの預金残高の平均」を集計
postgres=# EXPLAIN SELECT bid, avg(abalance) FROM pgbench_accounts WHERE aid % 10 = 0 GROP BY bid ORDER BY bid;
QUERY PLAN------------------------------------------------------------------------------------------------------------Finalize GroupAggregate (cost=2286598.72..2288424.56 rows=1000 width=36)Group Key: bid-> Gather Merge (cost=2286598.72..2288402.06 rows=2000 width=36)
Workers Planned: 2-> Partial GroupAggregate (cost=2285598.69..2287171.19 rows=1000 width=36)
Group Key: bid-> Sort (cost=2285598.69..2286119.52 rows=208333 width=8)
Sort Key: bid-> Parallel Seq Scan on pgbench_accounts (cost=0.00..2264345.00 rows=208333 width=8)
Filter: ((aid % 10) = 0)(10 rows)
パラレルクエリの例 Finalize GroupAggregate
Group Key: bid-> Gather Merge
Workers Planned: 2-> Partial GroupAggregate
Group Key: bid-> Sort
Sort Key: bid-> Parallel Seq Scan on pgbench_accounts
Filter: ((aid % 10) = 0)
パラレルクエリの例 Finalize GroupAggregate
Group Key: bid-> Gather Merge
Workers Planned: 2-> Partial GroupAggregate
Group Key: bid-> Sort
Sort Key: bid-> Parallel Seq Scan on pgbench_accounts
Filter: ((aid % 10) = 0)
パラレルクエリの例 Finalize GroupAggregate
Group Key: bid-> Gather Merge
Workers Planned: 2-> Partial GroupAggregate
Group Key: bid-> Sort
Sort Key: bid-> Parallel Seq Scan on pgbench_accounts
Filter: ((aid % 10) = 0)
パラレルクエリの例 Finalize GroupAggregate
Group Key: bid-> Gather Merge
Workers Planned: 2-> Partial GroupAggregate
Group Key: bid-> Sort
Sort Key: bid-> Parallel Seq Scan on pgbench_accounts
Filter: ((aid % 10) = 0)
パラレルクエリの例 Finalize GroupAggregate
Group Key: bid-> Gather Merge
Workers Planned: 2-> Partial GroupAggregate
Group Key: bid-> Sort
Sort Key: bid-> Parallel Seq Scan on pgbench_accounts
Filter: ((aid % 10) = 0)
パラレルクエリの例 Finalize GroupAggregate
Group Key: bid-> Gather Merge
Workers Planned: 2-> Partial GroupAggregate
Group Key: bid-> Sort
Sort Key: bid-> Parallel Seq Scan on pgbench_accounts
Filter: ((aid % 10) = 0)
パラレルクエリの例 Finalize GroupAggregate
Group Key: bid-> Gather Merge
Workers Planned: 2-> Partial GroupAggregate
Group Key: bid-> Sort
Sort Key: bid-> Parallel Seq Scan on pgbench_accounts
Filter: ((aid % 10) = 0)
パラレルクエリの例
•大規模テーブル同士をPK(またはインデックスのある列)で結合
postgres=# EXPLAIN SELECT count(*) FROM pgbench_accounts a1 JOIN pgbench_accounts a2 ON a1.aid = a2.aid;QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------Finalize Aggregate (cost=5486220.02..5486220.03 rows=1 width=8)-> Gather (cost=5486219.81..5486220.02 rows=2 width=8)
Workers Planned: 2-> Partial Aggregate (cost=5485219.81..5485219.82 rows=1 width=8)
-> Merge Join (cost=1.14..5381053.14 rows=41666667 width=0)Merge Cond: (a1.aid = a2.aid
) -> Parallel Index Only Scan using pgbench_accounts_pkey on pgbench_accounts a1 (cost=0.57..2013443.23 rows=41666667 width=4)
-> Index Only Scan using pgbench_accounts_pkey on pgbench_accounts a2 (cost=0.57..2596776.57 rows=100000000 width=4)(8 rows)
パラレルクエリの今後
•APPEND(UNION)•COPY FROM•インデックス作成
•VACUUM• SERIALIZABLE分離レベル
宣言的パーティショニング
パーティショニングの概要
•パーティショニングとは�論理的には一つの大きなテーブルを物理的に分割すること
�分割基準は値リスト・範囲などが一般的
•効果�検索条件に応じて特定パーティションのみ処理することでパフォーマンス向上が望める
�パーティション単位で削除することでを軽減(DELETEは遅い)
�あまり参照されないパーティションを遅いが安価なストレージに配置してコストを削減
これまで
•テーブル継承とチェック制約で擬似的にパーティショニングを実装
•「Constraint Exclusion(制約による排除)」により検索条件に合致するパーティション(子表)のみスキャン
•パーティション追加などの管理が煩雑
宣言的パーティショニング•レンジとリストをサポート�レンジ: 年月、名称など�リスト: コード値など�パーティションキーには関数呼び出しなどの式も指定可能
� 「パーティションキーのための列」が不要になる
•親テーブルと子テーブル�パーティション基準を指定して親テーブルを作成したのちに、各パーティションの子テーブルを作成する
�インデックスは各子テーブルに作成→一つのサイズが小さくなり、頻繁にアクセスされるパーティションのインデックスがメモリに配置されやすくなる
手順•親表を作成� CREATE TABLE parent(…) PARTITION BY
[{RANGE|LIST} ({column|expression})];
•子表を作成� CREATE TABLE child_1 PARTITION OF parent FOR
VALUES FROM ({minimum value|MINVALUE}) TO ({maximum value|MAXVALUE});� 下限は「以上」、上限は「未満」→上限=次の下限
� 制限なしの意味で「MINVALUE」や「MAXVALUE」も指定可能
� CREATE TABLE child_1 PARTITION OF parent FOR VALUES IN (value[ , …]);
手順postgres=# ¥d+ sales_item
Table "public.sales_item"Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
------------+---------+-----------+----------+---------+----------+--------------+-------------id | integer | | | | plain | |shop_id | integer | | | | plain | |sales_date | date | | | | plain | |amount | bigint | | | | plain | |note | text | | | | extended | |
Partition key: RANGE (sales_date)Partitions: sales_item_201701 FOR VALUES FROM ('2017-01-01') TO ('2017-02-01'),
sales_item_201702 FOR VALUES FROM ('2017-02-01') TO ('2017-03-01'),sales_item_201703 FOR VALUES FROM ('2017-03-01') TO ('2017-04-01')
手順ー9.6まで/* まず親テーブルを作成 */CREATE TABLE sales_item (id int, shop_id int, sales_date date, amount bigint, note text);
/* 年月ごとに子テーブルを作成し、CHECK 制約でデータ範囲を定義 */CREATE TABLE sales_item_201701 (LIKE sales_item) INHERITS (sales_item);ALTER TABLE sales_item_201701 ADD CONSTRAINT ck_sales_date CHECK (sales_date >= '2017-01-01'::date AND sales_date < '2017-02-01');
/* 新しい値範囲のデータを子テーブルに追加するようにトリガーを変更 */…
手順ー10から/* まず親テーブルを作成 */CREATE TABLE sales_item (id int, shop_id int, sales_date date, amount bigint, note text) PARTITIONED BY RANGE (sales_date);
/* 年月ごとに子テーブルを作成 */CREATE TABLE sales_item_201701 PARTITION OF sales_item FOR VALUES FROM ('2017-01-01') TO ('2017-02-01');
/* パーティション追加時はテーブルを追加するだけ */CREATE TABLE sales_item_201702 PARTITION OF sales_item FOR VALUES FROM ('2017-02-01') TO ('2017-03-01');CREATE TABLE sales_item_201703 PARTITION OF sales_item FOR VALUES FROM ('2017-03-01') TO ('2017-04-01');
論理レプリケーション
従来のレプリケーションは?
•従来のストリーミングレプリケーションは物理レプリケーション
•データブロックに対する操作などを記録したWALを伝搬するため、レプリカでもブロックイメージが同一となる
•レプリケーション先は読み取り専用のため競合はなくレプリケーションエラーは起きにくい
物理レプリケーションの制限
•メジャーバージョンを統一する必要がある�バイナリフォーマットに依存するため
�ローリングアップグレードができない
•常に全体をレプリケーション�集計用途などで特定部分のみレプリケーション、といったユースケースでも、全体を保持できるH/Wが必要
� 1 to Nの関係のみで、特定のインスタンスに情報を集約できない
これまでは、サードパーティのレプリケーションツールで対応する必要があった
論理レプリケーションの概要
•PublishとSubscribe�レプリケーション元でPublish(変更の配布)
�レプリケーション先でSubscribe(変更の購読)
•レプリケーションスロット�各レプリケーション先ごとにレプリケーション元に作成
�レプリケーション状況を把握し、不要なWALのみ削除
論理レプリケーションの注意点
•レプリケーション先と更新が競合しうる
• INSERT ON CONFLICT では実際に発生した変更のみが伝搬する
•COPY FROMはINSERTとして伝搬する
•TRUNCATEとDDLは伝搬しない
PostgreSQL関連情報
情報源
• JPUG (https://www.postgresql.jp)•Let’s Postgres (https://lets.postgresql.jp)•ML (https://www.postgresql.jp/npo/mailinglist)• Slack (https://postgresql-hackers-jp.herokuapp.com/)
•Twitter @jpug_study
参考文献• PostgreSQL Documents
� https://www.postgresql.org/docs/10/static/runtime-config-query.html
• PostgreSQL 10がやってくる!(その5) ロジカルレプリケーション基本編� http://qiita.com/nuko_yokohama/items/af3bbd9acbd9723b6b95
• PostgreSQL 10 Beta1 新機能検証結果� http://h50146.www5.hpe.com/products/software/oe/linux/mainstream/s
upport/lcc/pdf/PostgreSQL_10_New_Features_ja_20170522-1.pdf
• PostgreSQL10徹底解説� https://www.slideshare.net/masahikosawada98/postgresql10
• 次期バージョンPostgreSQL 10 の 新機能とその後の方向性� https://www.sraoss.co.jp/event_seminar/2017/db_tech_show_case_oss_2
017.pdf
Any Questions?