1サーバでPostgreSQLインスタンスを複数起動する方法


はじめに

同じサーバのPostreSQLで複数インスタンスを同時に立ち上げて、アプリケーションの動作を簡単に確認する必要がありまして、備忘録としてまとめました。
今回は、簡単に環境を構築するために、PostgreSQL用アカウントを作成せず、自分のアカウントを使用して、PostgreSQLをソースコードからインストールします。

環境

OS は、Ubuntu 20.04 を使用しています。PostgreSQLのバージョンは現時点での最新である PostgreSQL 13.3 を使用します。

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"

事前準備

PostgreSQLに必要なパッケージをインストールします。
bash
$ sudo apt install libreadline-dev zlib1g-dev bison flex

PostgreSQLのインストールと実行に必要なディレクトリを作成します。src はソースコードの格納先、pgsql は PosthreSQLのインストール先、data はデータベースクラスタの格納先としています。

$ cd $HOME
$ mkdir src
$ mkdir pgsql
$ mkdir data

PostgreSQLのインストール

PostgreSQLのソースコードのアーカイブファイルを入手して、アーカイブファイルを展開します。

$ cd src
$ wget https://ftp.postgresql.org/pub/source/v13.3/postgresql-13.3.tar.gz
$ tar xvzf postgresql-13.3.tar.gz

PostgreSQLをビルドします。configure の実行時に prefix オプションで PostgreSQL のインストール先を指定します。今回は、$HOME/pgsql/postgresql-13.3 です。

$ cd postgresql-13.3
$ ./configure --prefix=$HOME/pgsql/postgresql-13.3
$ make
$ make install

データベースクラスタの作成

データベースクラスタを作成します。今回は 3つのクラスタ cluster1, cluster2, cluster3 を作成します。

$ cd $HOME/pgsql/postgresql-13.3/bin
$ ./initdb $HOME/data/cluster1
$ ./initdb $HOME/data/cluster2
$ ./initdb $HOME/data/cluster3

インスタンスを同時に立ち上げるために、それぞれ違うポート番号を設定します。cluster1 は PostgreSQL デフォルトのポート番号 5432 を使用して、cluster2 は 5433 に、cluster3 は 5434 にポート番号を変更します。

$ cd $HOME/data/cluster2
$ vi postgresql.conf
port = 5433
$ cd $HOME/data/cluster3
$ vi postgresql.conf
port = 5434

PostgreSQLインスタンスの起動

pg_ctl コマンドで、それそれの PostgreSQL インスタンスを起動します。起動時にデータベースクラスタと、ログファイルを指定します。

$ cd $HOME/pgsql/postgresql-13.3/bin
$ ./pg_ctl -D $HOME/data/cluster1 -l $HOME/data/cluster1/postgres1.log start
$ ./pg_ctl -D $HOME/data/cluster2 -l $HOME/data/cluster2/postgres2.log start
$ ./pg_ctl -D $HOME/data/cluster3 -l $HOME/data/cluster3/postgres3.log start

データベースとテーブルの作成

createdb コマンドで、それぞれのデータベースを作成します。

$ ./createdb -p 5432 postgresdb1
$ ./createdb -p 5433 postgresdb2
$ ./createdb -p 5434 postgresdb3

psqlコマンドで、それぞれのインスタンスに接続して、テーブル dbnmae を作成して、レコードを1行追加します。

$ ./psql -p 5432 postgresdb1
postgresdb1=# CREATE TABLE dbname(name text);
postgresdb1=# INSERT INTO dbname VALUES('postgres database1');
$ ./psql -p 5433 postgresdb2
postgresdb2=# CREATE TABLE dbname(name text);
postgresdb2=# INSERT INTO dbname VALUES('postgres database2');
$ ./psql -p 5434 postgresdb3
postgresdb3=# CREATE TABLE dbname(name text);
postgresdb3=# INSERT INTO dbname VALUES('postgres database3');

PostgreSQLインスタンス起動確認

上記のpsqlでインスタンス起動は確認できていますが、同時に各インスタンスへアクセスできるか確認してみます。

print_dbname.py
import psycopg2
# PostgreSQLインスタンス接続情報、実行SQL 
dsn1 = "dbname=postgresdb1 host=localhost"
dsn2 = "dbname=postgresdb2 host=localhost port=5433"
dsn3 = "dbname=postgresdb3 host=localhost port=5434"
sql = "SELECT * FROM dbname"
# PostgreSQLインスタンスと接続 
conn1 = psycopg2.connect(dsn1)
conn2 = psycopg2.connect(dsn2)
conn3 = psycopg2.connect(dsn3)
# カーソルの取得
cur1 = conn1.cursor()
cur2 = conn2.cursor()
cur3 = conn3.cursor()
# SQL実行
cur1.execute(sql)
cur2.execute(sql)
cur3.execute(sql)
# 取得結果を出力
print(cur1.fetchone())
print(cur2.fetchone())
print(cur3.fetchone())
# カーソルを閉じる
cur1.close()
cur2.close()
cur3.close()
# PostgreSQLインスタンスとの接続を切断
conn1.close()
conn2.close()
conn3.close()

上記 pythonプログラムを実行すると、以下のように各インスタンスのテーブルに格納されているレコードを表示されます。

$ python3 print_dbname.py 
('postgres database1',)
('postgres database2',)
('postgres database3',)

下図のようなイメージになります。

python3、psycopg2がインストールされていなく、上記プログラムが実行できない場合、以下のコマンドでインストールをお願いします。

$ sudo apt install python3
$ sudo apt install python3-pip
$ pip install psycopg2-binary

PostgreSQLインスタンスの終了

pg_ctl コマンドで、それそれの PostgreSQL インスタンスを終了させます。

$ cd $HOME/pgsql/postgresql-13.3/bin
$ ./pg_ctl -D $HOME/data/cluster1 stop
$ ./pg_ctl -D $HOME/data/cluster2 stop
$ ./pg_ctl -D $HOME/data/cluster3 stop

まとめ

ポート番号を変更することで、同じサーバのPostreSQLで複数インスタンスを同時に立ち上げました。自分のアカウントで簡単にPostgreSQLの複数インスタンスを確認することができました。

もし、記述について誤りがあったり、気になることがあれば、編集リクエストやコメントでフィードバックしていただけると助かります。

参照

以下の情報を参考にさせて頂きました。