はじめに
業務でPostgreSQLの設計構築を行う際に、ローカル上に検証環境を作りたいと思いました。
PostgreSQLをインストールする方法はいくつかあります。(Let's Postgres インストール編)
インストーラからインストールすると簡単に環境を構築できて便利なのですが、私はPostgreSQLのソースコードに興味があったため、ソースコードからビルドする手順を本記事に整理しました。
対象読者
- 学習や検証用途で、PostgreSQLをローカルに構築したい方
- ソースコードからビルドしたい or 流れに興味がある方
- PostgreSQLのOSS貢献に興味がある方
全体の流れ
本記事は、仮想化環境上に立てた Ubuntu 22.04 におけるビルド手順です。
なお、本記事の最後に付録として、ビルド手順を網羅したDockerfileを用意しました。コンテナ環境で気軽にソースコードからPostgreSQLをビルドしたい場合はご活用ください。
全体の流れは以下となります。
- 前提モジュールのインストール
- PostgreSQL管理ユーザ作成 (OSユーザ)
- PostgreSQLソースコード取得
- ビルド用ディレクトリ作成
- configureコマンド実行
- ビルド (make)
- インストール (make)
- postgresユーザ向けにパスを通す
- データベースクラスタ作成
- PostgreSQLディレクトリ構成 全体像
- PostgreSQLサーバ起動・停止 (pg_ctl)
1. 前提モジュールのインストール
# rootにsu
sudo su -
# ローカルのパッケージリスト更新
apt update
# 前提モジュールのインストール
apt install -y build-essential git wget ca-certificates curl pkg-config \
flex bison autoconf automake libtool gettext \
libreadline-dev zlib1g-dev libssl-dev locales \
libxml2-dev libxml2-utils libxslt1-dev libbz2-dev liblzma-dev libncursesw5-dev \
libicu-dev sgml-base docbook-xml docbook-xsl xsltproc sgml-data \
python3 python3-dev python3-venv python3-distutils python3-pip libpython3-dev postgresql-contrib
2. PostgreSQL管理ユーザ(postgres)作成
# root確認
whoami
# postgres ユーザ作成
adduser postgres
# 以下のように進める
Adding user `postgres' ...
Adding new group `postgres' (1002) ...
Adding new user `postgres' (1002) with group `postgres' ...
Creating home directory `/home/postgres' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: # パスワード入力
Retype new UNIX password: # パスワード入力(確認)
passwd: password updated successfully
Changing the user information for postgres
Enter the new value, or press ENTER for the default
Full Name []: # Enter
Room Number []: # Enter
Work Phone []: # Enter
Home Phone []: # Enter
Other []: # Enter
Is the information correct? [Y/n] Y
# sudoグループに追加
gpasswd -a postgres sudo
Adding user postgres to group sudo
3. ソースコード取得 (git clone)
# root確認
whoami
# ソースコード取得 (どこでもOKだが、本手順では /usr/local/src に取得)
cd /usr/local/src
git clone https://git.postgresql.org/git/postgresql.git
ls -l
# postgres ディレクトリが存在すること
4. ビルド用ディレクトリ作成
ビルド用のディレクトリを作成します。
これにより、ソースコードとビルド成果物を分離でき、ソースコード領域をクリーンに保てます。
# root確認
whoami
# ビルド用ディレクトリを作成
cd /usr/local/src/postgres
mkdir build_dir
5. configureコマンド実施
configureコマンドは、ソースコードに含まれるテンプレートファイル (GNUmakefile.in) を、実際のビルド環境に適した設定ファイルに変換します。
configureコマンドで利用するオプションを先に説明します。個人的にPL/Pythonを利用したかったため、そのオプションも記載しております。
なお、以下に記載したものは全て任意のオプションとなりますので、不要なものは消してOKです。configureのみでも問題ないです。
他にも多くのオプションがあるので、気になる方はこちらをご参照ください。
-
--prefix=PREFIX
- デフォルトの/usr/local/pgsqlではなく、PREFIXディレクトリ配下に全てのファイルをインストールさせる。本記事では
/opt/pgsqlとする。
- デフォルトの/usr/local/pgsqlではなく、PREFIXディレクトリ配下に全てのファイルをインストールさせる。本記事では
-
--with-python
- PL/Pythonを利用可能にする。
-
--with-ssl=openssl
- クライアントとサーバ間で送受信されるデータをSSL/TLSによる暗号化を実現する。
-
--with-libxml
- PostgreSQLでxml型を利用する。
-
--with-libxslt
- XMLデータを他の形式(XML、HTML、テキストなど)に変換するためのXSLT(eXtensible Style Language Transformations)を有効にする。ドキュメントなどをビルドする際に必要。
ちなみに、新しい標準APIのために今後のバージョンではxml2モジュールは削除される可能性があるようです。
xml2 — XPath問い合わせとXSLT機能
# root確認
whoami
# ビルド用ディレクトリに移動
cd /usr/local/src/postgresql/build_dir
# configureコマンド実行
/usr/local/src/postgresql/configure \
--prefix=/opt/pgsql \
--with-python \
--with-ssl=openssl \
--with-libxml \
--with-libxslt
正常終了すると、build_dir配下は以下のディレクトリ構成となります。
total 416
drwxr-xr-x 6 root root 4096 Sep 23 04:55 ./
drwxr-xr-x 9 root root 4096 Sep 23 04:14 ../
drwxr-xr-x 2 root root 4096 Sep 23 04:55 config/
-rw-r--r-- 1 root root 348919 Sep 23 04:55 config.log
-rwxr-xr-x 1 root root 40217 Sep 23 04:55 config.status*
drwxr-xr-x 61 root root 4096 Sep 23 04:55 contrib/
drwxr-xr-x 3 root root 4096 Sep 23 04:55 doc/
-rw-r--r-- 1 root root 4176 Sep 23 04:55 GNUmakefile
lrwxrwxrwx 1 root root 34 Sep 23 04:55 Makefile -> /usr/local/src/postgresql/Makefile
drwxr-xr-x 16 root root 4096 Sep 23 04:55 src/
6. ビルド (make)
makeコマンドでビルドを実施します。
なお、makeやmake allでもOKなのですが、ドキュメント(HTMLやman)や追加モジュール(contrib)を含め、構築可能なもの全てをビルドするために、make worldとしています。
# ビルド実施
make world
# 確認
echo $?
# 0であること
もしmake worldが失敗した場合、build_dir配下をすべて削除し、再度configureから実施します。
rm -rf /usr/local/src/postgresql/build_dir/*
7. インストール (make)
make worldにより、build_dir配下にはビルド済みの成果物が作成されます。
これをmake install-worldで全てインストールします。
# インストール実施
make install-world
# 確認
echo $?
# 0であること
configureコマンド実行時、--prefixで指定した場所(/opt/pgsql)に以下のようなディレクトリが作成されていることを確認します。
total 24
drwxr-xr-x 6 root root 4096 Sep 23 05:25 ./
drwxr-xr-x 4 root root 4096 Sep 23 05:25 ../
drwxr-xr-x 2 root root 4096 Sep 23 05:25 bin/
drwxr-xr-x 6 root root 4096 Sep 23 05:25 include/
drwxr-xr-x 4 root root 4096 Sep 23 05:25 lib/
drwxr-xr-x 8 root root 4096 Sep 23 05:25 share/
8. postgresユーザにパスを通す
データベースクラスタの初期化を行うinitdbコマンドや、起動・停止等に利用するpg_ctlコマンドなど、各postgresqlコマンドへのパスを通します。
# postgresユーザにsu
su - postgres
# .profileの存在を確認
ls -la
# .profileにパスを追記
echo -e "# Postgresql path\nexport PATH=/opt/pgsql/bin:\$PATH" >> .profile
# 設定反映
. .profile
# initdbコマンドへのパスが通っていることを確認
which initdb
# /opt/pgsql/bin/initdb
9. データベースクラスタ初期化
いよいよ本手順でPostgreSQLサーバを利用する準備が整います。
その前に、今回はWAL(Write Ahead Logging)領域 (pg_wal) とデータベースクラスタ領域を分けて構築します。
PostgreSQLの物理設計において、WAL領域とテーブルやインデックスが格納されたデータベースクラスタ領域を物理的に隔離することは、耐障害性を考慮した設計として推奨されます。参考
ただし、今回は検証環境の構築なので、ディレクトリを分離するのみとなります。
initdbのオプションは、こちらをご覧ください。
# postgresユーザ確認
whoami
# データベースクラスタ領域 作成
sudo mkdir /pgsql
sudo chown postgres:postgres /pgsql
ls -ld /pgsql
# WAL領域 作成
sudo mkdir /wal
sudo chown postgres:postgres /wal
ls -ld /wal
# データベースクラスタ 初期化
initdb --no-locale --encoding=utf8 -U postgres -D /pgsql -X /wal
10. PostgreSQLディレクトリ構成 全体像
ここまでの手順を実施すると、以下のようなディレクトリ構成になっています。
├── /usr/
│ └── local/
│ └── src/
│ └── postgresql/ # PostgreSQL ソースコードディレクトリ
│ ├── src/ # コア部分。データベースサーバー本体、トランザクション機構、ストレージエンジン、SQL プランナー、クエリ実行系など。
│ ├── contrib/ # 追加機能群。公式拡張モジュールやツール。Core に含まれていないけど公式で提供されるもの。
│ ├── doc/ # ドキュメント。ユーザー用マニュアル、管理マニュアル、API ドキュメントなど。
│ ├── config/ # 設定スクリプトやビルド時の設定補助、 Makefile 生成系など。
│ ├── build_dir/ # ビルド用 一時ディレクトリ
│ └── Makefile, etc.
├── /opt/
│ └── pgsql/ # prefixで指定した、PostgreSQLがインストールされるディレクトリ
│ ├── bin/
│ │ ├── initdb
│ │ ├── pg_ctl
│ │ ├── psql
│ │ └── etc.
│ ├── lib/
│ │ ├── libpq.so 等のクライアントライブラリ
│ │ └── 拡張モジュール .so 等
│ ├── include/
│ │ └── ヘッダーファイル
│ └── share/
│ ├── extension
│ ├── man/man1 などのマニュアル
│ └── SQL/ドキュメントあるいは設定テンプレートファイル
├── /pgsql/ # データベースクラスタ(PGDATA)
│ ├── PG_VERSION
│ ├── base/
│ │ └── #(各データベースごとの OID ディレクトリ)
│ ├── global/ # クラスタ全体で共有されるデータを格納する領域 (ロール、システムカタログ、etc.)
│ ├── pg_wal/ -> /wal/ # WAL ファイル(Write-Ahead Log)
│ ├── postgresql.conf # 設定ファイル
│ ├── pg_hba.conf # クライアント接続・認証に関する設定ファイル
│ ├── pg_ident.conf # ident認証、外部認証死してむを利用する場合に利用するファイル
│ └── etc.
└── /wal # WAL領域
├── 000000010000000000000001 # WALファイル
├── archive_status/ # WALアーカイブ可否を示すreadyファイル配置場所
└── summaries/ # WAL要約ファイル配置場所
11. PostgreSQLサーバ起動・停止 (pg_ctl)
# 起動
PGDATA=/pgsql/ pg_ctl start -D /pgsql -l /tmp/postgres.log
# 停止
PGDATA=/pgsql/ pg_ctl stop -D /pgsql -l /tmp/postgres.log
最後に
これでPostgreSQL検証環境を用意できたので、今後PostgreSQL関連の発信を行っていきたいと思います。
また、PostgreSQLのOSSにも関わっていきたいと思いメーリングリストにいくつか登録してみました。ご興味のある方はこちらをご参照ください。
付録
- PostgreSQLのソースコードビルドをコンテナ環境で行う Dockerfile (ビルド後のイメージサイズは、1.6GB)