1. はじめに
リリースノートを見ている方はご存知かと思いますが、ついにPluggable Storage IFが実装されますね。
おもしろそうだし、今後知っておく必要があるとは思っていたので、PG12正式版のリリースが近づく中、そろそろ見始めようと思います。
- 本資料でわかること
- Pluggable Storage Interfaceの概要
- 現時点版のzheapのセットアップ及び利用手順
- pgbenchによるheap vs zheapの比較結果
本資料はせいぜいチュートリアルレベルで、機能の詳細には踏み込んでいません。試しに触ってみようと思う方向けの情報となっていますのでご注意ください。
1.1. Pluggable Table Storage Interfaceってなんだっけ?
DBのユースケースは様々あるため、PostgreSQLが現在実装しているストレージの設計では必ずしも最適ではないケースが存在します。
そこで、ストレージとの間を抽象化(これがPluggable Table Storage Interface)して、ユースケースに応じたものを選択できるようにしようという仕組み。(だと理解しています。)
MySQLでストレージエンジンを選択できる仕組みがPostgreSQLにも用意されたと言ったほうがイメージしやすいかもしれません。
詳しくは PostgreSQL Wiki を御覧ください。
例としてMySQL/MariaDBが提供しているものだと、どれがPostgreSQLに必要かというのが書かれていたりするので参考になるかもしれません。
(余談ですが)PostgreSQL12から、psqlのメタコマンドでそのテーブルがどのIFを利用しているか確認することができます。デフォルトはもちろん「heap」となります。
postgres=# CREATE TABLE foo (id int,v text);
CREATE TABLE
postgres-# \d+ foo
Table "public.foo"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
id | integer | | | | plain | |
v | text | | | | extended | |
Access method: heap
1.2. zheapってなんだ?
いきなりzheapって書きましたが、今回は新たなストレージエンジンとして期待されているこの製品を試してみようと思います。PostgreSQL12では、コア機能として選択できるストレージエンジンは既存の1種類しかないですが、新たなストレージエンジンとしてEnterpriseDB社が絶賛開発しているものになります。
zheapについて詳しく知りたい方は、Amit Kapilaさんの発表資料があるのでコチラをご確認ください。
zheapとは、PostgreSQLでUNDOログを利用したストレージフォーマットを実現するものです。EDB社が主導で開発を進めており、従来のheapと比べて、テーブルサイズの肥大化を抑えることができ、領域の即時再利用できるようにすることでVACUUM処理が不要になるというものらしい。
ちなみにソースはGithubで公開されているので、合わせてご参照いただくのが良いかと思います。
2. zheapの動作確認
2.1. インストール~PG起動
現在、zheapはPostgreSQLから切り出された形にはなっていないので、zheap込みのPostgreSQLを新しくにインストールする必要があります。(現時点で12beta1がベースっぽいです)
cd ~
git clone https://github.com/EnterpriseDB/zheap
cd ~/zheap
PGHOME=~/pg_zheap/pgsql
./configure --prefix=${PGHOME} \
--bindir=${PGHOME}/bin \
--libdir=${PGHOME}/lib \
--sysconfdir=${PGHOME}/etc \
--includedir=${PGHOME}/include \
--datadir=${PGHOME}/share \
--with-pgport=5432 \
--with-python \
--with-openssl \
--with-pam \
--with-ldap \
--with-libxml \
--with-libxslt
cd src
make
make install
PGDATA=~/pg_zheap/data
~/pg_zheap/pgsql/bin/initdb -D ${PGDATA} --no-locale --encoding=utf8
~/pg_zheap/pgsql/bin/pg_ctl -D ${PGDATA} start
起動すると見たことないプロセスが動いていることに気づきます。
$ ps -ef | grep postgres
ikki 8823 1 0 21:00 ? 00:00:00 /home/ikki/pg_zheap/pgsql/bin/postgres -D /home/ikki/pg_zheap/data
ikki 8825 8823 0 21:00 ? 00:00:00 postgres: checkpointer
ikki 8826 8823 0 21:00 ? 00:00:00 postgres: background writer
ikki 8827 8823 0 21:00 ? 00:00:00 postgres: walwriter
ikki 8828 8823 0 21:00 ? 00:00:00 postgres: autovacuum launcher
ikki 8829 8823 0 21:00 ? 00:00:00 postgres: stats collector
ikki 8830 8823 0 21:00 ? 00:00:00 postgres: discard worker★
ikki 8831 8823 0 21:00 ? 00:00:00 postgres: undo worker launcher★
ikki 8832 8823 0 21:00 ? 00:00:00 postgres: logical replication launcher
追加されたプロセスの概要:
- discard worker
- UNDOを非同期に管理として不要になったUNDOログの破棄を行うためのプロセス
- undo worker launcher
- 必要に応じてUNDOアクションを実行するための undo worker を起動するランチャー
2.2. zheapを使用したテーブルの作成
GithubのREADME.mdのとおりに実行してみる。
postgres=# CREATE TABLE foo (id int, v text);
CREATE TABLE
postgres=# CREATE TABLE bar (id int, v text) USING zheap;
CREATE TABLE
postgres=# \d+ foo
Table "public.foo"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
id | integer | | | | plain | |
v | text | | | | extended | |
Access method: heap
postgres=# \d+ bar
Table "public.bar"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+----------+--------------+-------------
id | integer | | | | plain | |
v | text | | | | extended | |
Access method: zheap
GUCパラメータのdefault_table_access_method
を変更することでデフォルトを変更することもできます。あとはSET文でも指定可能なので、都合の良いやり方を選んべばOKです。(デフォルト値は'heap'になっています。)
postgres=# show default_table_access_method;
default_table_access_method
-----------------------------
heap
(1 row)
ちなみにUNDOログはこんな感じで出力されています。
$ ll -h pg_zheap/data/base/undo/
total 2.0M
-rw------- 1 ikki ikki 1.0M Jul 7 08:54 000000.0000300000
-rw------- 1 ikki ikki 1.0M Jul 7 08:52 000000.0000400000
作成されているときはログに出力されておりこういう出力内容でした。
2019-07-07 08:53:32.542 UTC [11946] LOG: created undo segment "base/undo/000000.0000100000"
2019-07-07 08:53:41.280 UTC [11946] LOG: created undo segment "base/undo/000000.0000200000"
2019-07-07 08:53:48.824 UTC [11946] LOG: created undo segment "base/undo/000000.0000300000"
2019-07-07 08:53:56.952 UTC [11896] LOG: recycled undo segment "base/undo/000000.0000000000" -> "base/undo/000000.0000400000"
2019-07-07 08:53:56.952 UTC [11896] LOG: unlinked undo segment "base/undo/000000.0000100000"
2019-07-07 08:53:56.952 UTC [11896] LOG: unlinked undo segment "base/undo/000000.0000200000"
3. 性能比較
本当は有効に効くケース(テーブルが肥大化するようなケース?)とかを考えた上でやるべきですが、一旦は何も考えずにやってみる。
3.1. pgbench
heapで作ったテーブルとzheapで作ったテーブルで試してみる。
default_table_access_method
はセッション単位であればSET文で変更してもよいし、ALTER SYSTEM
でやってもOKです。
postgres=# show default_table_access_method ;
default_table_access_method
-----------------------------
zheap
(1 row)
# 初期テーブル作成
~/pg_zheap/pgsql/bin/pgbench -i -s 50 postgres
# 負荷掛け
~/pg_zheap/pgsql/bin/pgbench -c 10 -T 180 postgres
3.2. 結果
TPS(大きな差分はない)
結果は以下のとおり。デフォルトのpgbenchの負荷では、ストレージエンジンの変更による性能差は見られなかったです。(3回実施した平均値として取得)
method | latency avg | tps |
---|---|---|
heap | 6.912 ms | 1446.818450 |
zheap | 6.723 ms | 1487.459050 |
テーブルサイズの変化(若干の差分あり)
上記のベンチマークを3回実行したあとのテーブルサイズを確認した結果は以下のとおりでした。
なぜか初期値が違うし、ばらつきもありますが増加量でいうと、heapだと10MB増加していたものが、zheapだと数KBに収まっており、たしかにテーブルの肥大化に対して効果がありそうだなという感じですね。
heapで作成したテーブルの場合
table | before | after |
---|---|---|
pgbench_accounts | 641 MB | 651 MB |
pgbench_branches | 40 kB | 296 kB |
pgbench_history | 0 bytes | 13 MB |
pgbench_tellers | 56 kB | 368 kB |
zheapで作成したテーブルの場合
table | before | after |
---|---|---|
pgbench_accounts | 514 MB | 514 MB |
pgbench_branches | 48 kB | 656 kB |
pgbench_history | 8192 bytes | 9152 kB |
pgbench_tellers | 56 kB | 784 kB |
4. まとめ
今回導入された table_access_method
を変更することで、PostgreSQLユーザはそのワークロードに合わせたストレージエンジンのテーブルを作成できるようになりました。
この機能によって、将来的には、ワークロードの特性に合わせたストレージエンジンを選択することができ、ますますPostgreSQLの活躍の場を増やせそうで楽しみです。
今後ですが、これでチュートリアルは終わった認識なので、もう少しzheapの理解を深め、より顕著な差が出るケースを検討して、測定をしてみようかと思います。