複数バージョンのPostgreSQLを入れる2

拙作なツールですが、複数バージョンのPostgreSQLをローカルマシンに入れて、テストや動作確認でバージョンを切り替えたりするツールを以前に作成したことがありましたが、色々と使い勝手も含めて改良したいなあと思っていたこともあり、今回新たに作り直してみました。

動作確認は自分のMac環境でしかできていませんが、それなりに動いて重宝しているので、以下に概要をまとめてみました。

pgenv2

https://github.com/moritoru81/pgenv2

動作環境

  • Bash 4.2 or later(4.4以上を推奨)

インストール

リポジトリをクローンして、install.shでパスを通すだけです。設置場所は、任意です。

$ git clone https://github.com/moritoru81/pgenv2.git
$ cd pgenv2
$ source install.sh

機能

今のところ以下ができます。ざっくりと言うと、xxenvと言われるソフトウェアと類似の機能があります。

  • PostgreSQLのインストール(ソースアーカイブをダウンロードしてビルド)
  • インストールした複数バージョンのPostgreSQLの切り替え
  • ローカルマシン上でのレプリケーション環境の構築

利用可能なバージョン一覧の表示

公式サイトのWebページからリリースされているバージョン一覧を取得して表示します。

$ pgenv versions
1.08
1.09
...

インストール時に、ここで表示されるバージョンを指定します。

指定のバージョンのPostgreSQLをインストールする

pgenv versionsで利用可能なバージョン一覧を確認できたら、次はインストールします。以下では、10.1をインストールしています。

$ pgenv install 10.1

コマンドを実行すると、10.1のソースアーカイブをダウンロードして、展開、configuremakeと実行していきます。ビルドのログは、pgenv/logsにバージョンの名前で出力されます。

configureのオプションは、pgenv/configure_optionsにデフォルトの条件が書いてあります。pgenvのconfigureコマンドで編集ができます。$EDITORで指定されるエディタでファイルを編集します。

pgenv configure --edit --global 10.1

無事にインストールできたら、以下でバージョン確認ができます。

$ pgenv list
  10.1       
* 10.3       
  10.4       
  9.6.9      
  9.5 

上記では、現在10.3が有効ですが、10.1に切り替えてみます。

$ pgenv global 10.1
Current version -> versions/10.1

[Next step]

  Create an instance and start postmaster:
    $ initdb pgdata
    $ pg_ctl -D pgdata -l postgresql.log start

  Connect to the postgres database:
    $ psql postgres

切り替わったか確認します。

$ pgenv list
* 10.1       
  10.3       
  10.4       
  9.6.9      
  9.5
$ psql -V
psql (PostgreSQL) 10.1
$ pgenv prefix --bin ./psql -V
psql (PostgreSQL) 10.1

インストール場所を確認してみます。

$ pgenv prefix 
/Users/guest/workspace/pgenv2/versions/10.1

レプリケーション環境の構築

PostgreSQLには、レプリケーション機能がありますが、サクッと手元で環境を構築し、動作確認したいことがあります。pgenv2には、そういった機能があります。

1対1の同期レプリケーションを組みたい場合、以下のようにできます。

$ pgenv cluster -D foo setup --sync-standby standby primary

上記例では、fooというディレクトリに、各種インスタンスディレクトリが作成されます。

$ ls foo
archivedir        cluster_config.sh primary           primary.conf      standby           standby.conf

プライマリは「primary」、同期スタンバイは「standby」としています。各ノードの設定は、基本的に外出しで、includeパラメータで読み込ませています。port番号は、デフォルトでは24312から順にインクリメントして使用しています。

以下で構築した環境の状態を確認してみます。primary -> standbyはレプリケーション関係を示しています。pg_stat_replicationビューの情報をもとにしています。

$ pgenv cluster -D foo status
[Cluster Servers]
# Primary server
primary:24312       pg_ctl: server is running (PID: 17941)

# Synchronous standby servers
standby:24313       pg_ctl: server is running (PID: 18042)

# Asynchronous standby servers

[Replication Graph]
primary -> standby 
  standby -> 

別ターミナルで、各種インスタンスのログを表示しておきます。

$ pgenv cluster -D foo tail -f -a

==> primary/log/postgresql-2018-06-23.log <==
2018-06-23 09:01:16.905 JST [17944] LOG:  database system was shut down at 2018-06-23 09:01:16 JST
2018-06-23 09:01:16.914 JST [17941] LOG:  database system is ready to accept connections
2018-06-23 09:01:17.372 JST [17978] LOG:  standby "standby" is now a synchronous standby with priority 1
2018-06-23 09:01:18.170 JST [18049] LOG:  standby "standby" is now a synchronous standby with priority 1

==> standby/log/postgresql-2018-06-23.log <==
2018-06-23 09:01:16.905 JST [17944] LOG:  database system was shut down at 2018-06-23 09:01:16 JST
2018-06-23 09:01:16.914 JST [17941] LOG:  database system is ready to accept connections
2018-06-23 09:01:17.372 JST [17978] LOG:  standby "standby" is now a synchronous standby with priority 1
2018-06-23 09:01:18.012 JST [18044] LOG:  database system was interrupted; last known up at 2018-06-23 09:01:17 JST
2018-06-23 09:01:18.050 JST [18044] LOG:  entering standby mode
2018-06-23 09:01:18.052 JST [18044] LOG:  redo starts at 0/2000028
2018-06-23 09:01:18.052 JST [18044] LOG:  consistent recovery state reached at 0/20000F8
2018-06-23 09:01:18.054 JST [18042] LOG:  database system is ready to accept read only connections
2018-06-23 09:01:18.069 JST [18048] LOG:  started streaming WAL from primary at 0/3000000 on timeline 1

続いて、スタンバイを昇格させてみます。

$ pg_ctl -D foo/standby promote
waiting for server to promote.... done
server promoted

ログも出力されていることを確認します。

==> standby/log/postgresql-2018-06-23.log <==
2018-06-23 09:01:16.905 JST [17944] LOG:  database system was shut down at 2018-06-23 09:01:16 JST
2018-06-23 09:01:16.914 JST [17941] LOG:  database system is ready to accept connections
2018-06-23 09:01:17.372 JST [17978] LOG:  standby "standby" is now a synchronous standby with priority 1
2018-06-23 09:01:18.012 JST [18044] LOG:  database system was interrupted; last known up at 2018-06-23 09:01:17 JST
2018-06-23 09:01:18.050 JST [18044] LOG:  entering standby mode
2018-06-23 09:01:18.052 JST [18044] LOG:  redo starts at 0/2000028
2018-06-23 09:01:18.052 JST [18044] LOG:  consistent recovery state reached at 0/20000F8
2018-06-23 09:01:18.054 JST [18042] LOG:  database system is ready to accept read only connections
2018-06-23 09:01:18.069 JST [18048] LOG:  started streaming WAL from primary at 0/3000000 on timeline 1
2018-06-23 09:09:32.542 JST [18044] LOG:  received promote request
2018-06-23 09:09:32.542 JST [18048] FATAL:  terminating walreceiver process due to administrator command
2018-06-23 09:09:32.543 JST [18044] LOG:  invalid record length at 0/3000140: wanted 24, got 0
2018-06-23 09:09:32.543 JST [18044] LOG:  redo done at 0/3000108
2018-06-23 09:09:32.544 JST [18044] LOG:  selected new timeline ID: 2
2018-06-23 09:09:32.609 JST [18044] LOG:  archive recovery complete
2018-06-23 09:09:32.611 JST [18042] LOG:  database system is ready to accept connections

レプリケーション状態を見てみます。

$ pgenv cluster -D foo status
[Cluster Servers]
# Primary server
primary:24312       pg_ctl: server is running (PID: 17941)

# Synchronous standby servers
standby:24313       pg_ctl: server is running (PID: 18042)

# Asynchronous standby servers

[Replication Graph]
primary -> 
standby ->

続けて、standbyに新しく非同期スタンバイを追加してみます。

$ pgenv cluster -D foo ctrl --attach --fork-off standby standby2

非同期スタンバイを起動します。非同期スタンバイ追加時にも-Sオプションで同時に起動できます。

$ pgenv cluster -D foo start standby2

レプリケーション状態を確認してみます。

$ pgenv cluster -D foo status
[Cluster Servers]
# Primary server
primary:24312       pg_ctl: server is running (PID: 17941)

# Synchronous standby servers
standby:24313       pg_ctl: server is running (PID: 18042)

# Asynchronous standby servers
standby2:24314      pg_ctl: server is running (PID: 19632)

[Replication Graph]
standby2 -> 
primary -> 
standby -> standby2  

別の方法でも確認してみます。

 $ psql -x -p 24313 -d postgres -c "select * from pg_stat_replication;"
-[ RECORD 1 ]----+------------------------------
pid              | 20524
usesysid         | 10
usename          | guest
application_name | standby2
client_addr      | ::1
client_hostname  | 
client_port      | 52690
backend_start    | 2018-06-23 10:50:31.537352+09
backend_xmin     | 
state            | streaming
sent_lsn         | 0/5000140
write_lsn        | 0/5000140
flush_lsn        | 0/5000140
replay_lsn       | 0/5000140
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 0
sync_state       | async

インスタンスを停止します。

$ pgenv cluster -D foo stop -a

昇格させたstandbyと非同期レプリケーションstandby2のみを起動します。

$ pgenv cluster -D foo start standby standby2

状態を確認してみます。

$ pgenv cluster -D foo status
[Cluster Servers]
# Primary server
primary:24312       pg_ctl: no server running

# Synchronous standby servers
standby:24313       pg_ctl: server is running (PID: 22434)

# Asynchronous standby servers
standby2:24314      pg_ctl: server is running (PID: 22453)

[Replication Graph]
standby2 -> 
primary -> 
standby -> standby2 

と、こんな感じでレプリケーションの動作確認を手元ですぐに確認できます。

ちょっとした拡張機能の確認

$ pgenv extension init myext
$ cd myext
$ pgenv extension install -v @all
$ pgenv extension run -v @all 'initdb  ${ver}data'
$ pgenv extension run -v @all 'pg_ctl start -l $ver.log -D ${ver}data -o "-p $((9000+i))"'
$ pgenv extension run -v @all 'psql -p $((9000+i)) postgres -c "create extension myext"'
$ pgenv extension run -v @all 'psql -p $((9000+i)) postgres -c "select myext()"'

byebyehaikikyou

日記やIT系関連のネタ、WordPressに関することなど様々な事柄を書き付けた雑記です。ITエンジニア経験があるのでプログラミングに関することなどが多いです。

シェアする

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

コメントする

Translate »