2018年4月1日日曜日

PostgreSQL11のJITコンパイリングを試す

llvm-postgres
開発中のPostgreSQL11でJIT(Just In Time=実行時)コンパイリングを行い、クエリ性能の高速化を期待する新機能が登場した。

本記事では

構築方法を確認したので紹介。JITコンパイリングを使いこなす話はまだ。

構築時のポイント

JITコンパイリングを有効にするためのPostgreSQL11導入方法や前提ライブラリを把握した。
  • 開発版PostgreSQLの最新のソースコードからコンパイルする
    • 前提ライブラリはllvmおよびclangの3.9.0以上
    • ./configure時に必要なオプションは--with-llvmLLVM_CONFIG=<path>CLANG=<path>の3つ
  • 構築時に遭遇するかもしれないエラーメッセージたち

出来上がった環境を見てみる

最低限のテストを行い、JITコンパイリング機能が発動するところまでを確認。
  • JIT無しで構築した環境との比較
  • JITに関連すうる初期化パラメーター(postgresql.conf)を見てみる
  • クエリの見積もりコストが一定以上でJITコンパイリングが発動

構築

手順1: llvmおよびclangのインストール

何度か構築作業のトライ&エラーしたところ、現在の最新dev版PostgreSQLは、configure時にLLVM-3.9.0以上を要求してくることが判明。まずはLLVMをインストールするところから。
普通にepel-releaseからではllvm-3.4系がインストールされてしまうので追加のyumリポジトリを設定。
/* epel-releaseリポジトリを追加 */
# yum install epel-release
# yum update

/* 3.4系がlistされるが、PostgreSQL 11devでは3.9系以上が求められる */
# yum list | grep llvm
llvm.x86_64                             3.4.2-8.el7                    epel
llvm-devel.x86_64                       3.4.2-8.el7                    epel
 :
epel-repoに以下を追加。
(本手順は stack overflow - How to install Clang and LLVM 3.9 on CentOS 7 を参考)
# vi /etc/yum.repos.d/epel.repo
[alonid-llvm-3.9.0]
name=Copr repo for llvm-3.9.0 owned by alonid
baseurl=https://copr-be.cloud.fedoraproject.org/results/alonid/llvm-3.9.0/epel-7-x86_64/
type=rpm-md
skip_if_unavailable=True
gpgcheck=1
gpgkey=https://copr-be.cloud.fedoraproject.org/results/alonid/llvm-3.9.0/pubkey.gpg
repo_gpgcheck=0
enabled=1
enabled_metadata=1
llvm-3.9.0をインストール
# yum install llvm-3.9.0-devel
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * epel: www.ftp.ne.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ llvm-3.9.0-devel.x86_64 0:3.9.0-7.el7.centos.alonid を インストール
--> 依存性の処理をしています: llvm-3.9.0(x86-64) = 3.9.0-7.el7.centos.alonid のパッケージ: llvm-3.9.0-devel-3.9.0-7.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libLLVM-3.9.so()(64bit) のパッケージ: llvm-3.9.0-devel-3.9.0-7.el7.centos.alonid.x86_64
--> トランザクションの確認を実行しています。
---> パッケージ llvm-3.9.0.x86_64 0:3.9.0-7.el7.centos.alonid を インストール
---> パッケージ llvm-3.9.0-libs.x86_64 0:3.9.0-7.el7.centos.alonid を インストール
--> 依存性解決を終了しました。

依存性を解決しました

===============================================================================================================================================================================================================================================================================
 Package                                                           アーキテクチャー                                        バージョン                                                                 リポジトリー                                                        容量
===============================================================================================================================================================================================================================================================================
インストール中:
 llvm-3.9.0-devel                                                  x86_64                                                  3.9.0-7.el7.centos.alonid                                                  alonid-llvm-3.9.0                                                  2.0 M
依存性関連でのインストールをします:
 llvm-3.9.0                                                        x86_64                                                  3.9.0-7.el7.centos.alonid                                                  alonid-llvm-3.9.0                                                  2.0 M
 llvm-3.9.0-libs                                                   x86_64                                                  3.9.0-7.el7.centos.alonid                                                  alonid-llvm-3.9.0                                                   11 M

トランザクションの要約
===============================================================================================================================================================================================================================================================================
インストール  1 パッケージ (+2 個の依存関係のパッケージ)

総ダウンロード容量: 15 M
インストール容量: 58 M
Is this ok [y/d/N]: y
Downloading packages:
警告: /var/cache/yum/x86_64/7/alonid-llvm-3.9.0/packages/llvm-3.9.0-devel-3.9.0-7.el7.centos.alonid.x86_64.rpm: ヘッダー V3 RSA/SHA1 Signature、鍵 ID c7c0c111: NOKEY                                                                        ] 289 kB/s | 384 kB  00:00:52 ETA
llvm-3.9.0-devel-3.9.0-7.el7.centos.alonid.x86_64.rpm の公開鍵がインストールされていません
(1/3): llvm-3.9.0-devel-3.9.0-7.el7.centos.alonid.x86_64.rpm                                                                                                                                                                                            | 2.0 MB  00:00:01
(2/3): llvm-3.9.0-3.9.0-7.el7.centos.alonid.x86_64.rpm                                                                                                                                                                                                  | 2.0 MB  00:00:02
(3/3): llvm-3.9.0-libs-3.9.0-7.el7.centos.alonid.x86_64.rpm                                                                                                                                                                                             |  11 MB  00:00:03
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
合計                                                                                                                                                                                                                                           2.9 MB/s |  15 MB  00:00:05
https://copr-be.cloud.fedoraproject.org/results/alonid/llvm-3.9.0/pubkey.gpg から鍵を取得中です。
Importing GPG key 0xC7C0C111:
 Userid     : "alonid_llvm-3.9.0 (None) <alonid#llvm-3.9.0@copr.fedorahosted.org>"
 Fingerprint: d6a8 1fa1 8ab0 d031 5b66 93fa 9455 6bf5 c7c0 c111
 From       : https://copr-be.cloud.fedoraproject.org/results/alonid/llvm-3.9.0/pubkey.gpg
上記の処理を行います。よろしいでしょうか? [y/N]y
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : llvm-3.9.0-libs-3.9.0-7.el7.centos.alonid.x86_64                                                                                                                                                                                               1/3
  インストール中          : llvm-3.9.0-3.9.0-7.el7.centos.alonid.x86_64                                                                                                                                                                                                    2/3
  インストール中          : llvm-3.9.0-devel-3.9.0-7.el7.centos.alonid.x86_64                                                                                                                                                                                              3/3
  検証中                  : llvm-3.9.0-3.9.0-7.el7.centos.alonid.x86_64                                                                                                                                                                                                    1/3
  検証中                  : llvm-3.9.0-libs-3.9.0-7.el7.centos.alonid.x86_64                                                                                                                                                                                               2/3
  検証中                  : llvm-3.9.0-devel-3.9.0-7.el7.centos.alonid.x86_64                                                                                                                                                                                              3/3

インストール:
  llvm-3.9.0-devel.x86_64 0:3.9.0-7.el7.centos.alonid

依存性関連をインストールしました:
  llvm-3.9.0.x86_64 0:3.9.0-7.el7.centos.alonid                                                                                       llvm-3.9.0-libs.x86_64 0:3.9.0-7.el7.centos.alonid

完了しました!
もう一つ、llvmに関連するclangの導入も必要。(最初に知っていればいきなりclangでも依存性解決してくれたのかも。)
# yum install clang-3.9.0-devel
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * epel: mirror.dmmlabs.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ clang-3.9.0-devel.x86_64 0:3.9.0-3.1.el7.centos.alonid を インストール
--> 依存性の処理をしています: clang-3.9.0(x86-64) = 3.9.0-3.1.el7.centos.alonid のパッケージ: clang-3.9.0-devel-3.9.0-3.1.el7.centos.alonid.x86_64
--> トランザクションの確認を実行しています。
---> パッケージ clang-3.9.0.x86_64 0:3.9.0-3.1.el7.centos.alonid を インストール
--> 依存性の処理をしています: clang-3.9.0-libs(x86-64) = 3.9.0-3.1.el7.centos.alonid のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclang.so.3.9()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangAST.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangBasic.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangCodeGen.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangDriver.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangFormat.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangFrontend.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangFrontendTool.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangIndex.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangRewrite.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangRewriteFrontend.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangStaticAnalyzerFrontend.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangTooling.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> 依存性の処理をしています: libclangToolingCore.so()(64bit) のパッケージ: clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64
--> トランザクションの確認を実行しています。
---> パッケージ clang-3.9.0-libs.x86_64 0:3.9.0-3.1.el7.centos.alonid を インストール
--> 依存性の処理をしています: compiler-rt-3.9.0(x86-64) >= 3.9.0 のパッケージ: clang-3.9.0-libs-3.9.0-3.1.el7.centos.alonid.x86_64
--> トランザクションの確認を実行しています。
---> パッケージ compiler-rt-3.9.0.x86_64 0:3.9.0-3.el7.centos.alonid を インストール
--> 依存性解決を終了しました。

依存性を解決しました

===============================================================================================================================================================================================================================================================================
 Package                                                           アーキテクチャー                                       バージョン                                                                   リポジトリー                                                       容量
===============================================================================================================================================================================================================================================================================
インストール中:
 clang-3.9.0-devel                                                 x86_64                                                 3.9.0-3.1.el7.centos.alonid                                                  alonid-llvm-3.9.0                                                 1.5 M
依存性関連でのインストールをします:
 clang-3.9.0                                                       x86_64                                                 3.9.0-3.1.el7.centos.alonid                                                  alonid-llvm-3.9.0                                                 441 k
 clang-3.9.0-libs                                                  x86_64                                                 3.9.0-3.1.el7.centos.alonid                                                  alonid-llvm-3.9.0                                                 8.6 M
 compiler-rt-3.9.0                                                 x86_64                                                 3.9.0-3.el7.centos.alonid                                                    alonid-llvm-3.9.0                                                 1.4 M

トランザクションの要約
===============================================================================================================================================================================================================================================================================
インストール  1 パッケージ (+3 個の依存関係のパッケージ)

総ダウンロード容量: 12 M
インストール容量: 60 M
Is this ok [y/d/N]: y
Downloading packages:
(1/4): clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64.rpm                                                                                                                                                                                               | 441 kB  00:00:01
(2/4): clang-3.9.0-devel-3.9.0-3.1.el7.centos.alonid.x86_64.rpm                                                                                                                                                                                         | 1.5 MB  00:00:01
(3/4): compiler-rt-3.9.0-3.9.0-3.el7.centos.alonid.x86_64.rpm                                                                                                                                                                                           | 1.4 MB  00:00:00
(4/4): clang-3.9.0-libs-3.9.0-3.1.el7.centos.alonid.x86_64.rpm                                                                                                                                                                                          | 8.6 MB  00:00:02
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
合計                                                                                                                                                                                                                                           2.6 MB/s |  12 MB  00:00:04
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : compiler-rt-3.9.0-3.9.0-3.el7.centos.alonid.x86_64                                                                                                                                                                                             1/4
  インストール中          : clang-3.9.0-libs-3.9.0-3.1.el7.centos.alonid.x86_64                                                                                                                                                                                            2/4
  インストール中          : clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64                                                                                                                                                                                                 3/4
  インストール中          : clang-3.9.0-devel-3.9.0-3.1.el7.centos.alonid.x86_64                                                                                                                                                                                           4/4
  検証中                  : clang-3.9.0-3.9.0-3.1.el7.centos.alonid.x86_64                                                                                                                                                                                                 1/4
  検証中                  : compiler-rt-3.9.0-3.9.0-3.el7.centos.alonid.x86_64                                                                                                                                                                                             2/4
  検証中                  : clang-3.9.0-devel-3.9.0-3.1.el7.centos.alonid.x86_64                                                                                                                                                                                           3/4
  検証中                  : clang-3.9.0-libs-3.9.0-3.1.el7.centos.alonid.x86_64                                                                                                                                                                                            4/4

インストール:
  clang-3.9.0-devel.x86_64 0:3.9.0-3.1.el7.centos.alonid

依存性関連をインストールしました:
  clang-3.9.0.x86_64 0:3.9.0-3.1.el7.centos.alonid                                       clang-3.9.0-libs.x86_64 0:3.9.0-3.1.el7.centos.alonid                                       compiler-rt-3.9.0.x86_64 0:3.9.0-3.el7.centos.alonid

完了しました!
導入したllvmおよびclangは/opt/llvm-3.9.0ディレクトリ下に作成されていた。(3.9系のrpmでは各コマンドにパスが通っていなかったため、whichが使えなくていろいろ探した。)
# cd /opt/llvm-3.9.0/
# ls
bin  include  lib64
# cd /opt/llvm-3.9.0/bin/
# ls
bugpoint      clang++      clang-cl      lli      llvm-bcanalyzer  llvm-cov      llvm-dis        llvm-dwp      llvm-link  llvm-mcmarkup  llvm-pdbdump   llvm-readobj  llvm-split       llvm-tblgen  sancov               yaml2obj
c-index-test  clang-3.9    clang-format  llvm-ar  llvm-c-test      llvm-cxxdump  llvm-dsymutil   llvm-extract  llvm-lto   llvm-nm        llvm-profdata  llvm-rtdyld   llvm-stress      obj2yaml     sanstats
clang         clang-check  llc           llvm-as  llvm-config-64   llvm-diff     llvm-dwarfdump  llvm-lib      llvm-mc    llvm-objdump   llvm-ranlib    llvm-size     llvm-symbolizer  opt          verify-uselistorder
PostgreSQLのconfigure時、llvm-configコマンドおよびclangコマンドのパスが必要になるので確認しておく。
/* llvm-configコマンドでバージョンを確認(フルパスで実行できることを確認) */
# /opt/llvm-3.9.0/bin/llvm-config-64 --version
3.9.0

/* clangコマンドでバージョンを確認(フルパスで実行できることを確認) */
# /opt/llvm-3.9.0/bin/clang --version
clang version 3.9.0 (tags/RELEASE_390/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/llvm-3.9.0/bin

手順2: PostgreSQLのconfugreとインストール

PostgreSQLのソースからインストールしたことがある人は、configureオプションさえ気を付ければいつも通り。慣れていない方向けのもう少し詳しい手順は後述。

configure

# cd /media/postgres-master/
# ./configure --prefix=/home/pg11/pg11-home-withllvm --with-llvm LLVM_CONFIG=/opt/llvm-3.9.0/bin/llvm-config-64 CLANG=/opt/llvm-3.9.0/bin/clang
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking which template to use... linux
 :

make

# make
make -C src all
make[1]: ディレクトリ `/media/postgres-master/src' に入ります
make -C common all
 :
All of PostgreSQL successfully made. Ready to install.

make install

# su pg11
# make install
make -C src install
make[1]: ディレクトリ `/media/postgres-master/src' に入ります
make -C common install
 :
PostgreSQL installation complete.

インストール後の状態

pg11ユーザーにスイッチし、--prefixで指定したディレクトリにインストールされていることを確認
# su - pg11
$ ls
pg11-home-withllvm
$ ls -ltr ./pg11-home-withllvm/
合計 12
drwxrwxr-x. 3 pg11 pg11   23  3月 31 13:17 share
drwxrwxr-x. 4 pg11 pg11 4096  3月 31 13:18 include
drwxrwxr-x. 4 pg11 pg11 4096  3月 31 13:18 lib
drwxrwxr-x. 2 pg11 pg11 4096  3月 31 13:18 bin

$ ls ./pg11-home-withllvm/bin
clusterdb  createuser  dropuser  initdb             pg_basebackup  pg_controldata  pg_dump     pg_isready     pg_recvlogical  pg_restore  pg_test_fsync   pg_upgrade  pgbench   postmaster  reindexdb
createdb   dropdb      ecpg      pg_archivecleanup  pg_config      pg_ctl          pg_dumpall  pg_receivewal  pg_resetwal     pg_rewind   pg_test_timing  pg_waldump  postgres  psql        vacuumdb

$ ls ./pg11-home-withllvm/share
postgresql

$ ls ./pg11-home-withllvm/include
ecpg_config.h    ecpgerrno.h  ecpgtype.h  libpq-events.h  pg_config.h      pg_config_manual.h  pgtypes_date.h   pgtypes_interval.h  pgtypes_timestamp.h  postgresql   sqlca.h         sqlda-native.h
ecpg_informix.h  ecpglib.h    libpq       libpq-fe.h      pg_config_ext.h  pg_config_os.h      pgtypes_error.h  pgtypes_numeric.h   postgres_ext.h       sql3types.h  sqlda-compat.h  sqlda.h

$ ls ./pg11-home-withllvm/lib
libecpg.a   libecpg.so.6     libecpg_compat.a   libecpg_compat.so.3     libpgcommon.a   libpgport.a   libpgtypes.so    libpgtypes.so.3.11  libpq.so    libpq.so.5.11  postgresql
libecpg.so  libecpg.so.6.11  libecpg_compat.so  libecpg_compat.so.3.11  libpgfeutils.a  libpgtypes.a  libpgtypes.so.3  libpq.a             libpq.so.5  pkgconfig
pg_configコマンドで確認すると、CONFIGURE行やLDFLAGS行よりLLVM込みでインストールできていることを読み取ることができる。
$ pg_config
BINDIR = /home/pg11/pg11-home-withllvm/bin
DOCDIR = /home/pg11/pg11-home-withllvm/share/doc/postgresql
HTMLDIR = /home/pg11/pg11-home-withllvm/share/doc/postgresql
INCLUDEDIR = /home/pg11/pg11-home-withllvm/include
PKGINCLUDEDIR = /home/pg11/pg11-home-withllvm/include/postgresql
INCLUDEDIR-SERVER = /home/pg11/pg11-home-withllvm/include/postgresql/server
LIBDIR = /home/pg11/pg11-home-withllvm/lib
PKGLIBDIR = /home/pg11/pg11-home-withllvm/lib/postgresql
LOCALEDIR = /home/pg11/pg11-home-withllvm/share/locale
MANDIR = /home/pg11/pg11-home-withllvm/share/man
SHAREDIR = /home/pg11/pg11-home-withllvm/share/postgresql
SYSCONFDIR = /home/pg11/pg11-home-withllvm/etc/postgresql
PGXS = /home/pg11/pg11-home-withllvm/lib/postgresql/pgxs/src/makefiles/pgxs.mk
CONFIGURE = '--prefix=/home/pg11/pg11-home-withllvm' '--with-llvm' 'LLVM_CONFIG=/opt/llvm-3.9.0/bin/llvm-config-64' 'CLANG=/opt/llvm-3.9.0/bin/clang'
CC = gcc
CPPFLAGS = -DFRONTEND -D_GNU_SOURCE
CFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2
CFLAGS_SL = -fPIC
LDFLAGS = -L../../src/common -L/opt/llvm-3.9.0/lib64 -Wl,--as-needed -Wl,-rpath,'/home/pg11/pg11-home-withllvm/lib',--enable-new-dtags
LDFLAGS_EX =
LDFLAGS_SL =
LIBS = -lpgcommon -lpgport -lpthread -lz -lreadline -lrt -lcrypt -ldl -lm
VERSION = PostgreSQL 11devel

PostgerSQLインストールの補足

pg11ユーザー作成

今回はPostgreSQLをpg11ユーザーの所有でインストールする & インストール先ディレクトリをpg11ユーザーのホーム直下にしたくて事前にユーザーを作成。
# useradd pg11
# su - pg11
$ pwd
/home/pg11
$ exit
#

最新版ソースコードの取得

上述の「configure」以降の手順は、以下の通り最新版のソースコードを取得したうえで、解凍したディレクトリ(~/postgres-master/)に移動して実行している。
# cd /media
# wget https://github.com/postgres/postgres/archive/master.zip
# unzip master.zip
# cd /media/postgres-master/
# ls
COPYRIGHT  GNUmakefile  GNUmakefile.in  HISTORY  Makefile  README  README.git  aclocal.m4  config  config.log  config.status  configure  configure.in  contrib  doc  src

configure時のエラー

ありがちなエラーを整理(llvm関係ないものも含む。)
  • readline関連
  • zlib関連
      →それぞれreadline-develzlib-develを事前に導入しておく
# yum install readline-devel
# yum install zlib-devel
  • llvmのバージョン関連
      →メッセージに従い、要求されているバージョンをなんとかして追加する
/* エラーメッセージの例 */
checking for llvm-config... /usr/bin/llvm-config
configure: error: /usr/bin/llvm-config version is 3.4.2 but at least 3.9 is required
  • LLVM_CONFIG関連
  • CLANG関連
      →llvm_configコマンドやclangコマンドの正しいパスを確認して、LLVM_CONFIGオプションまたはCLANGオプションで指定。
/* エラーメッセージの例 */
checking for llvm-config... no
checking for llvm-config-6.0... no
checking for llvm-config-5.0... no
checking for llvm-config-4.0... no
checking for llvm-config-3.9... no
configure: error: llvm-config not found, but required when compiling --with-llvm, specify with LLVM_CONFIG=
/* エラーメッセージの例 */
checking for LLVM_CONFIG... /opt/llvm-3.9.0/bin/llvm-config-64
checking for clang... no
checking for clang-6.0... no
checking for clang-5.0... no
checking for clang-4.0... no
checking for clang-3.9... no
configure: error: clang not found, but required when compiling --with-llvm, specify with CLANG=
本稿のために実行時のログを整理していて、LLVMやCLANGのバージョンが3.9指定ではなく、もっと新しいもの(6.0や5.0など)であれば、PostgreSQLがちゃんと探して使ってくれるのだな・・・と気づいた。新しいほうが賢かったりするんだろうか。

出来上がった環境を見る

llvm無しで作った環境と比較

LLVMサポートのために追加されたファイル

<path-to-postgres>/lib/postgresql配下に以下のファイル・ディレクトリが追加されている。
$ cd lib/postgresql/
$ ls -ltr
drwxrwxr-x. 3 1002 1002     45  3月 31 13:18 bitcode
-rwxr-xr-x. 1 1002 1002 138560  3月 31 13:18 llvmjit.so
-rw-r--r--. 1 1002 1002   6044  3月 31 13:18 llvmjit_types.bc
 (その他は省略)
ファイルサイズ。ノーマルのPostgreSQLに対して結構でかい。
/* 追加されたファイルが15MB強 */
$ du -sh ./pg11-home-withllvm/lib/postgresql/*
15M     ./bitcode
136K    ./llvmjit.so
8.0K    ./llvmjit_types.bc
 (その他は省略)

/* PostgreSQLのインストール先全体の約25MBに対して、15MBほど追加されて計40MB程度になる。*/
$ du -sh ./pg11-home-withllvm/*
12M     ./pg11-home-withllvm/bin
6.1M    ./pg11-home-withllvm/include
20M     ./pg11-home-withllvm/lib
2.9M    ./pg11-home-withllvm/share

$ du -sh ./pg11-home-nollvm/*
12M     ./pg11-home-nollvm/bin
6.1M    ./pg11-home-nollvm/include
4.6M    ./pg11-home-nollvm/lib
2.9M    ./pg11-home-nollvm/share
ちなみにbitcodeディレクトリ配下はたくさんのLLVM Bitcodeが配置されている。
$ cd ./pg11-home-withllvm/lib/postgresql
$ ls
ascii_and_mic.so     dict_snowball.so     euc_jp_and_sjis.so  latin2_and_win1250.so  llvmjit.so        pgxs               utf8_and_big5.so      utf8_and_euc_cn.so  utf8_and_euc_tw.so   utf8_and_iso8859.so    utf8_and_sjis.so      utf8_and_win.so
bitcode              euc2004_sjis2004.so  euc_kr_and_mic.so   latin_and_mic.so       llvmjit_types.bc  plpgsql.so         utf8_and_cyrillic.so  utf8_and_euc_jp.so  utf8_and_gb18030.so  utf8_and_iso8859_1.so  utf8_and_sjis2004.so
cyrillic_and_mic.so  euc_cn_and_mic.so    euc_tw_and_big5.so  libpqwalreceiver.so    pgoutput.so       utf8_and_ascii.so  utf8_and_euc2004.so   utf8_and_euc_kr.so  utf8_and_gbk.so      utf8_and_johab.so      utf8_and_uhc.so
$ cd bitcode
$ ls
postgres  postgres.index.bc
$ cd postgres
$ ls
access  bootstrap  catalog  commands  executor  foreign  jit  lib  libpq  main  nodes  optimizer  parser  port  postmaster  regex  replication  rewrite  statistics  storage  tcop  tsearch  utils
$ cd executor
$ ls
execAmi.bc         execIndexing.bc   execProcnode.bc     execUtils.bc   nodeBitmapAnd.bc        nodeCustom.bc        nodeGroup.bc          nodeLimit.bc        nodeModifyTable.bc          nodeResult.bc      nodeSubplan.bc        nodeValuesscan.bc     tstoreReceiver.bc
execCurrent.bc     execJunk.bc       execReplication.bc  functions.bc   nodeBitmapHeapscan.bc   nodeForeignscan.bc   nodeHash.bc           nodeLockRows.bc     nodeNamedtuplestorescan.bc  nodeSamplescan.bc  nodeSubqueryscan.bc   nodeWindowAgg.bc
execExpr.bc        execMain.bc       execSRF.bc          instrument.bc  nodeBitmapIndexscan.bc  nodeFunctionscan.bc  nodeHashjoin.bc       nodeMaterial.bc     nodeNestloop.bc             nodeSeqscan.bc     nodeTableFuncscan.bc  nodeWorktablescan.bc
execExprInterp.bc  execParallel.bc   execScan.bc         nodeAgg.bc     nodeBitmapOr.bc         nodeGather.bc        nodeIndexonlyscan.bc  nodeMergeAppend.bc  nodeProjectSet.bc           nodeSetOp.bc       nodeTidscan.bc        spi.bc
execGrouping.bc    execPartition.bc  execTuples.bc       nodeAppend.bc  nodeCtescan.bc          nodeGatherMerge.bc   nodeIndexscan.bc      nodeMergejoin.bc    nodeRecursiveunion.bc       nodeSort.bc        nodeUnique.bc         tqueue.bc

使ってみる

環境変数の設定

最低限、.bash_profileにこれぐらい追加しておけば良い。今回は複数の環境で違いを見くらべたいのでこんな感じに環境変数設定ファイルを都度読むようにする。
$ cp .bash_profile .withllvm_profile
$ vi .withllvm_profile
export PGHOME=$HOME/pg11-home-withllvm
export PGDATA=$HOME/data-withllvm
export PGPORT=5435
export PGDATABASE=postgres
export PATH=$PGHOME/bin:.:$PATH
こっちのファイルを反映するときはsourceで読みこむ。
$ source .withllvm_profile

initdb

JITサポートのためのinitdbオプションも探したがそのようなものはない。普通initdbすればOK。
$ initdb -E utf8 --no-locale
The files belonging to this database system will be owned by user "pg11".
This user must also own the server process.

The database cluster will be initialized with locale "C".
The default text search configuration will be set to "english".

Data page checksums are disabled.

creating directory /home/pg11/data-withllvm ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    pg_ctl -D /home/pg11/data-withllvm -l logfile start
データディレクトリが作成された。
$ cd $PGDATA
$ pwd
/home/pg11/data-withllvm
$ ls
PG_VERSION  base  global  pg_commit_ts  pg_dynshmem  pg_hba.conf  pg_ident.conf  pg_logical  pg_multixact  pg_notify  pg_replslot  pg_serial  pg_snapshots  pg_stat  pg_stat_tmp  pg_subtrans  pg_tblspc  pg_twophase  pg_wal  pg_xact  postgresql.auto.conf  postgresql.conf

設定ファイルの編集&起動

  • postgresql.confでは以下のパラメーターを修正
    • listen_addresses = ‘*’
    • port = 5435
    • logging_collector = on
  • pg_hba.confは以下
    • 自分のノートPCのIPアドレスを許可

データベース起動

$ pg_ctl start

パラメーター一覧からjitを検索

postgres=# SELECT name,setting,context,category,short_desc,extra_desc FROM pg_settings WHERE name LIKE '%jit%' ORDER BY category DESC,name ASC;
          name           | setting |      context      |               category                |                      short_desc                      |          extra_desc
-------------------------+---------+-------------------+---------------------------------------+------------------------------------------------------+------------------------------
 jit_above_cost          | 100000  | user              | Query Tuning / Planner Cost Constants | Perform JIT compilation if query is more expensive.  | -1 disables JIT compilation.
 jit_inline_above_cost   | 500000  | user              | Query Tuning / Planner Cost Constants | Perform JIT inlining if query is more expensive.     | -1 disables inlining.
 jit_optimize_above_cost | 500000  | user              | Query Tuning / Planner Cost Constants | Optimize JITed functions if query is more expensive. | -1 disables optimization.
 jit                     | on      | user              | Query Tuning / Other Planner Options  | Allow JIT compilation.                               |
 jit_provider            | llvmjit | postmaster        | File Locations                        | JIT provider to use.                                 |
 jit_debugging_support   | off     | superuser-backend | Developer Options                     | Register JIT compiled function with debugger.        |
 jit_dump_bitcode        | off     | superuser         | Developer Options                     | Write out LLVM bitcode to facilitate JIT debugging.  |
 jit_expressions         | on      | user              | Developer Options                     | Allow JIT compilation of expressions.                |
 jit_profiling_support   | off     | superuser-backend | Developer Options                     | Register JIT compiled function with perf profiler.   |
 jit_tuple_deforming     | on      | user              | Developer Options                     | Allow JIT compilation of tuple deforming.            |
(10 rows)
注意: LLVM無しで作った環境もパラメーター自体は同じものが設定されていた。

JITが発動するとどうなるか

クエリの見積もりコストがjit_above_costを超えると発動するとのことなので、pgbenchのテーブルを使って超雑にコストの高いクエリを作ってみた。複雑にしたいがために適当of適当で作った。クエリの意味を考えてはいけない。
/* サンプルはpgbenchのテーブルで */
$ pgbench -i -s 100 -U bench bench
creating tables...
generating data...
100000 of 10000000 tuples (1%) done (elapsed 0.23 s, remaining 23.10 s)
200000 of 10000000 tuples (2%) done (elapsed 0.48 s, remaining 23.76 s)
 :
done.

/* pgbenchのベンチマークではなく、無駄に重く作ってみたクエリ。★の行数でコストが変わる。 */
EXPLAIN ANALYZE
WITH a AS (SELECT a.aid,abalance,b.bid,tbalance FROM pgbench_accounts a
  JOIN pgbench_branches b ON a.bid=b.bid
  JOIN pgbench_tellers t       ON b.bid = t.bid
  WHERE a.aid between 50000 and xxxxxx) --★
SELECT * FROM pgbench_branches
RIGHT OUTER JOIN a ON pgbench_branches.bbalance = tbalance
WHERE tbalance % 35 in (0,2,5,7,9,11,13,17);
★を調整して、見積もりコスト(1行目のHash Left Join (cost=33360.21..100000.04)が100000を超えると、JITが発動した。
bench=> explain analyze with A as (select a.aid,abalance,b.bid,tbalance from pgbench_accounts a join pgbench_branches b on a.bid=b.bid JOIN pgbench_tellers t ON  b.bid = t.bid
WHERE a.aid between 50000 and 262926) -- ★
select * from pgbench_branches right outer join A on pgbench_branches.bbalance = tbalance where tbalance % 35 in (0,2,5,7,9,11,13,17);
                                                                                QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Hash Left Join  (cost=33360.21..100000.04 rows=81144 width=380) (actual time=45.816..3774.989 rows=212927 loops=1)
   Hash Cond: (a.tbalance = pgbench_branches.bbalance)
   CTE a
     ->  Hash Join  (cost=49.72..33355.96 rows=2028610 width=16) (actual time=45.637..1518.676 rows=2129270 loops=1)
           Hash Cond: (a_1.bid = b.bid)
           ->  Index Scan using pgbench_accounts_pkey on pgbench_accounts a_1  (cost=0.43..9977.66 rows=202861 width=12) (actual time=0.076..207.748 rows=212927 loops=1)
                 Index Cond: ((aid >= 50000) AND (aid <= 262926))
           ->  Hash  (cost=36.79..36.79 rows=1000 width=12) (actual time=45.497..45.497 rows=1000 loops=1)
                 Buckets: 1024  Batches: 1  Memory Usage: 51kB
                 ->  Hash Join  (cost=4.25..36.79 rows=1000 width=12) (actual time=43.046..44.835 rows=1000 loops=1)
                       Hash Cond: (t.bid = b.bid)
                       ->  Seq Scan on pgbench_tellers t  (cost=0.00..20.00 rows=1000 width=8) (actual time=0.041..0.610 rows=1000 loops=1)
                       ->  Hash  (cost=3.00..3.00 rows=100 width=4) (actual time=42.934..42.934 rows=100 loops=1)
                             Buckets: 1024  Batches: 1  Memory Usage: 12kB
                             ->  Seq Scan on pgbench_branches b  (cost=0.00..3.00 rows=100 width=4) (actual time=42.699..42.805 rows=100 loops=1)
   ->  CTE Scan on a  (cost=0.00..65929.82 rows=81144 width=16) (actual time=45.665..3541.279 rows=212927 loops=1)
         Filter: ((tbalance % 35) = ANY ('{0,2,5,7,9,11,13,17}'::integer[]))
         Rows Removed by Filter: 1916343
   ->  Hash  (cost=3.00..3.00 rows=100 width=364) (actual time=0.122..0.122 rows=100 loops=1)
         Buckets: 1024  Batches: 1  Memory Usage: 12kB
         ->  Seq Scan on pgbench_branches  (cost=0.00..3.00 rows=100 width=364) (actual time=0.011..0.058 rows=100 loops=1)
 Planning Time: 1.694 ms
 JIT:
   Functions: 36
   Generation Time: 11.757 ms
   Inlining: false
   Inlining Time: 0.000 ms
   Optimization: false
   Optimization Time: 2.401 ms
   Emission Time: 39.496 ms
 Execution Time: 3894.130 ms
(31 rows)

Time: 3903.549 ms (00:03.904)
試しに★を1行へらして、コストが100000を下回ると、JITは発動しない。
bench=> explain analyze with A as (select a.aid,abalance,b.bid,tbalance from pgbench_accounts a join pgbench_branches b on a.bid=b.bid JOIN pgbench_tellers t ON  b.bid = t.bid
WHERE a.aid between 50000 and 262925) -- ★
select * from pgbench_branches right outer join A on pgbench_branches.bbalance = tbalance where tbalance % 35 in (0,2,5,7,9,11,13,17);
                                                                      QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Hash Left Join  (cost=33360.07..99999.58 rows=81144 width=380) (actual time=3.699..3824.800 rows=212926 loops=1)
   Hash Cond: (a.tbalance = pgbench_branches.bbalance)
   CTE a
     ->  Hash Join  (cost=49.72..33355.82 rows=2028600 width=16) (actual time=3.499..1532.521 rows=2129260 loops=1)
           Hash Cond: (a_1.bid = b.bid)
           ->  Index Scan using pgbench_accounts_pkey on pgbench_accounts a_1  (cost=0.43..9977.64 rows=202860 width=12) (actual time=0.054..201.977 rows=212926 loops=1)
                 Index Cond: ((aid >= 50000) AND (aid <= 262925))
           ->  Hash  (cost=36.79..36.79 rows=1000 width=12) (actual time=3.411..3.411 rows=1000 loops=1)
                 Buckets: 1024  Batches: 1  Memory Usage: 51kB
                 ->  Hash Join  (cost=4.25..36.79 rows=1000 width=12) (actual time=1.076..2.791 rows=1000 loops=1)
                       Hash Cond: (t.bid = b.bid)
                       ->  Seq Scan on pgbench_tellers t  (cost=0.00..20.00 rows=1000 width=8) (actual time=0.023..0.613 rows=1000 loops=1)
                       ->  Hash  (cost=3.00..3.00 rows=100 width=4) (actual time=1.024..1.024 rows=100 loops=1)
                             Buckets: 1024  Batches: 1  Memory Usage: 12kB
                             ->  Seq Scan on pgbench_branches b  (cost=0.00..3.00 rows=100 width=4) (actual time=0.005..0.085 rows=100 loops=1)
   ->  CTE Scan on a  (cost=0.00..65929.50 rows=81144 width=16) (actual time=3.520..3594.655 rows=212926 loops=1)
         Filter: ((tbalance % 35) = ANY ('{0,2,5,7,9,11,13,17}'::integer[]))
         Rows Removed by Filter: 1916334
   ->  Hash  (cost=3.00..3.00 rows=100 width=364) (actual time=0.130..0.130 rows=100 loops=1)
         Buckets: 1024  Batches: 1  Memory Usage: 12kB
         ->  Seq Scan on pgbench_branches  (cost=0.00..3.00 rows=100 width=364) (actual time=0.009..0.056 rows=100 loops=1)
 Planning Time: 1.282 ms
 Execution Time: 3931.001 ms
(23 rows)

Time: 3935.137 ms (00:03.935)
と、パラメーターの設定にしたがってJITが発動している様子がわかります。
本稿ではここまで。
今後はJITが得意な処理をちゃんと調べて、「こんなケースで効果がでる」みたいなところを明らかにしていきたい。

2018年2月12日月曜日

pgAdmin4をバージョンアップする(Windows版)

2017年12月13日水曜日

pgAdmin4を日本語化する

この記事はPostgreSQL Advent Calendar 2017の13日目です。昨日はkmoriさんの「.psqlrcの話」でした。
本記事では、私もメンバーの一員として取り組んでいるpgAdmin4の日本語化について書きます。

pgAdmin4とは?

クライアントPCからリモートのPostgreSQLサーバーに接続し、メンテナンス、状態監視、簡単な開発に利用できるGUIクライアントです。

pgAdmin4、こんな人におススメ

 ・データベースをGUIで手軽に操作したい
 ・PostgreSQLを使い始めたので、まずはアクセスみたい
 ・監視やチューニングに関しても、手元でちょろっとできて欲しいんよ

データベースを利用する上で、例えばマルチDB対応しているA5や、補完機能などが抜群で圧倒的支持とウワサのオブジェクトブラウザ-など、便利なクライアントツールは複数知られていますが、PostgreSQL向けにとにかく気軽に使いたいならpgAdminでしょう。
特にGUIクライアントの需要が高いであろうWindows版であれば、PostgreSQLのインストーラーに同梱されていますので、使い始めが簡単ですし、簡単な監視、SQLチューニングまでいろいろできます。


日本語対応しました!

知る人ぞ知る、pgAdminの開発メーリングリスト
ついに日本語対応しました。日本PostgreSQLユーザ会の有志で数ヶ月にわたる翻訳を行い、この度日本語対応することができました。


日本語化する方法

PostgreSQL10に同梱されているpgAmind4 v2以降、簡単に日本語化することができます。既に稼働しているpgAdmin4を日本語化する手順を説明します。

・翻訳ファイルの配置
まずは以下のファイルを手元にダウンロードしておいてください。
 poファイルのダウンロード
こちらのリンク先で、「messages.po」「messages.mo」をそれぞれ入手しておいてください。(注:右クリックで「リンク先を保存」では正しく保存できませんでした。私の場合、pgadmin4のトップでソースコード全体をDOWNLOADしました)

Windowsの場合、デフォルトで「C:\Program Files\PostgreSQL\10\pgAdmin 4\web\pgadmin\translations」に各国語の翻訳ファイルが配置されていますので、「ja\LC_MESSAGES」フォルダを作成し、両ファイルを配置します。

・設定変更
「C:\Program Files\PostgreSQL\10\pgAdmin 4\web」にpgAdmin起動時に読み込まれる「config.py」がありますので、これをテキストエディタで開き、一か所編集します。

'ja','Japanese'の行を追加します。'Polish'の後のカンマも忘れずに。
---
# Languages we support in the UI
LANGUAGES = {
    'en': 'English',
    'zh': 'Chinese (Simplified)',
    'de': 'German',
    'pl': 'Polish',
    'ja': 'Japanese'
}
---

・pgAdminの起動と設定変更
追加したフォルダのパスや設定が間違っていたりするとpgAdminが上手く起動しません。私は↑の設定ファイルでカンマを付け忘れて数時間悩みましたw

pgAdmin4を起動し、上部メニューの「File」-「Preferences」より設定変更を行います。
「Miscellaneous」-「User Language」で使用する言語を選択します。 ここでは config.pyファイルに記述した言語が候補になります。

変更はすぐには反映されませんので、「File」-「Reset Layout」します。

なにやら警告が。pgAdminから実行中の処理がある場合は気をつけましょう。

日本語になりました!


ところで、最初から日本語に対応した版が出るのはもう少し先になりそうです。そして今は日本語化しても英語交じりで「ん?!」って感じです。パッと見は確かに日本語なのですが、実用的なメニューではどこが変わったのよ?!という方に日本語版おススメポイントを1つ挙げておきます。



ちょっとマニアックな部分ですが、SQL実行する「Query Tool」では(そもそも「Query Tool」を日本語にしてよ、という意見が・・・(∩゚д゚)アーアーきこえなーい
雷アイコンでユーザーが書いたSQLを実行します。が、ん?実行どこ?!って思ってました。昔のpgAdmin3は雷アイコンが黄色かったのでなんとなく目についたんですよね。

「どれだよ実行~」と思って探していくと、雷アイコンのマウスオーバーでちゃんと日本語ヘルプが出ますし、複数の実行オプションがあるのですが、こういうマニアックなメニューが日本語になっているのは嬉しい気がします。
(「EXPLAIN ANALYZE」はSQLコマンドなのでこのまま英語表記かな・・・)


以上です。

明日はやっさん(yassan168)さんがデータ分析でPostgreSQLな話をしてくれるそうです!

2017年12月1日金曜日

コピペで試す PG10 の 3ステップレプリケーション!

本記事は PostgreSQL Advent Calendar 2017 の1日目です。
のっけから23時台の更新とひやひやさせてすみません。

■何を書くか
11/3に開催されたPostgreSQL Conforence 2017 JapanでPostgreSQLのレプリケーションに関するチュートリアルを受け持ったのですが、その準備中、PG10でレプリケーション作成の簡単さにびっくりしたのです。当然チュートリアル内でもその簡単さを熱く語ったわけですが、それを書こうと思います。

PostgreSQLレプリケーション(pgcon17j_t4) from Kosuke Kida


■PG10のレプリケーションはこうなった!
 ・パラメータのデフォルト値が変わって、簡単にレプリケーションできるようになった
 ・ロジカルレプリケーションができるようになった

 その他にも細かい話題はあるにせよ、このうち、ロジレプの陰で感動するほど簡単になったレプリケーション作成を取り上げたいと思います。

 ■ステップ0:インストール
AWSでEC2インスタンス(CentOS)にPostgreSQLをインストールします。

$ sudo yum install wget
$ wget https://download.postgresql.org/pub/repos/yum/testing/10/redhat/rhel-7-x86_64/pgdg-centos10-10-2.noarch.rpm
$ sudo rpm -ivh pgdg-centos10-10-2.noarch.rpm
$ sudo yum install postgresql10 postgresql10-server postgresql10-contrib postgresql10-devel
$ sudo vi /usr/lib/systemd/system/postgresql-10.service
---起動スクリプトのパスを変更---
# Location of database directory
# Environment=PGDATA=/var/lib/pgsql/10/data/
Environment=PGDATA=/home/postgres/data/
--
$ su - postgres
$ vi .bash_profile
---ユーザーの環境変数を変更---
### edit for PostgreSQL10
export PGDATA=/home/postgres/data
export PATH=/usr/pgsql-10/bin:.:$PATH
---

プライマリのデータベースを作成しておきます。

$ sudo systemctl start postgresql-10.service
$ sudo systemctl status postgresql-10.service
$ supostgres
$ createuser -d -r -l -P demo
$ createdb -O demo demodb
 
サンプルデータも入れておきましょう。

$ psql -U demo demodb
demodb=> create table sample (a int,b text);
demodb=> insert into sample values (1,'test1');
 
■ステップ1:プライマリ側の設定
レプリケーション用のユーザーを作成し、ユーザーのアクセス制御をpg_hba.confに書きます。
$ createuser --replication rep_user
$ vi $PGDATA/pg_hba.conf
 ----pg_hba.confを編集---
TYPE
DB
USER
CIDR-ADDRESS
METHOD
host
replication
rep_user
192.168.10.0/24
trust
host
all
rep_user
0.0.0.0/0
reject
 ---
このように、アクセス許可設定はもちろのこと、拒否設定もすると良いと思ってます。
 
レプリケーション用のパラメータを修正します。ここがポイント。デフォルト値が変更になり、(最小ではパラメータ変更なしでも)レプリケーションできます。
$ vi $PGDATA/postgresql.conf
 

パラメータ

設定

説明

listen_addresses

*

(通常はDB作成後にほぼ必須で実施)

wal_level

replica

レプリケーションに必要なWAL情報を生成

max_wal_senders

10

起動可能なwal senderプロセスの上限

max_replication_slots

10

作成可能なレプリケーションスロットの上限

synchronous_standby_names

任意

同期スタンバイの名前を指定

synchronous_commit

on

同期レベルを指定

hot_standby

on

自身がスタンバイの時に参照可能とする

hot_standby_feedback

on

自身の情報をプライマリに送信
 
自分がスタンバイになったときのために、サンプルのrecovery.confを作成しておきます。
$ vi $PGDATA/recovery.conf.node1
 
パラメータ
設定
説明
standby_mode
on
起動時にスタンバイモードになる
primary_conninfo
プライマリへの接続情報
primary_slot_name
slot2
プライマリのレプリケーションスロット名
recovery_target_timeline
latest
最新のマスターに追従する設定
 
■ステップ2:スタンバイの作成

スタンバイ側でpg_basebackupを使ってプライマリのバックアップを取得します。取得したデータはそのまま展開され、スタンバイのデータディレクトリになります。
$ pg_basebackup -U rep_user -h <node1_ip> -p 5432 -D /home/postgres/data
$ ls -ltr $PGDATA
drwx------. 3 postgres postgres    60 Oct 28 15:44 pg_wal
drwx------. 6 postgres postgres    54 Oct 28 15:44 base
drwx------. 2 postgres postgres  4096 Oct 28 15:44 global
drwx------. 2 postgres postgres    32 Oct 28 15:44 log
-rw-------. 1 postgres postgres 22844 Oct 28 15:44 postgresql.conf
-rw-------. 1 postgres postgres    88 Oct 28 15:44 postgresql.auto.conf
-rw-rw-r--. 1 postgres postgres   169 Oct 28 15:44 recovery.conf.node1
-rw-------. 1 postgres postgres  4760 Oct 28 15:44 pg_hba.conf
  :
 
スタンバイサーバーの設定もプライマリから取得したバックアップに含まれているのでほぼそのまま流用できます。変更すべき点は、recovery.confです。これはレプリケーション時にスタンバイがプライマリに接続しにいくための設定ですので、常にレプリケーションの相手ノードの情報が書いておくものだからです。
 
$ cp $PGDATA/recovery.conf.node1 $PGDATA/recovery.conf.node2
$ vi $PGDATA/recovery.conf.node2 

primary_conninfo
プライマリへの接続情報
primary_slot_name
slot1
プライマリのレプリケーションスロット名
 
この2行をプライマリへの接続情報に変更します。
 
■ステップ3:スタンバイを起動
レプリケーションスロットを使う場合、スタンバイ起動時に、必ずレプリケーションスロットを作成、または状態を確認するようにします。(レプリケーションスロットで運用する場合。)
 recovery.confに書いた primary_slot_name がまさにそのための設定で、ここで指定したスロットがマスター側に存在しないとレプリケーションできません。
 
プライマリでレプリケーションスロットを作成します。
$ su - postgres
$ psql -h <node1_ip> -U postgres postgres
postgres=# select pg_create_physical_replication_slot('slot1');
 
スタンバイでデータベースを起動します。
$ sudo systemctl start postgresql-10.service
$ su - postgres
$ ps x
11089 ?  Ss  0:00 /usr/pgsql-10/bin/postmaster -D /home/postgres/data/
11093 ?  Ss  0:00 postgres: startup process   recovering 000000010000000000000005
11097 ?  Ss  0:00 postgres: wal receiver process   streaming 0/5000140
  :
 
ほら、レプリケーションできました
 
今回は、AWSでたぶん一番簡単にPostgreSQLをインストールするところから、レプリケーションができるまでをコピペして使えるそのままのコマンドで紹介しました。
(書式がぐっちゃぐちゃで申し訳なさすぎます。見栄えはあとでコソッと変更します。)

明日は、Morihayaさんが担当してくださいます。

PostgreSQL11のJITコンパイリングを試す

llvm-postgres 開発中のPostgreSQL11でJIT(Just In Time=実行時)コンパイリングを行い、クエリ性能の高速化を期待する新機能が登場した。 本記事では 構築方法を確認したので紹介。JITコンパイ...