拙作なツールですが、複数バージョンのPostgreSQLをローカルマシンに入れて、テストや動作確認でバージョンを切り替えたりするツールを以前に作成したことがありましたが、色々と使い勝手も含めて改良したいなあと思っていたこともあり、今回新たに作り直してみました。
動作確認は自分のMac環境でしかできていませんが、それなりに動いて重宝しているので、以下に概要をまとめてみました。
pgenv2
動作環境
- Bash 4.2 or later(4.4以上を推奨)
インストール
リポジトリをクローンして、install.sh
でパスを通すだけです。設置場所は、任意です。
1 2 3 |
$ git clone https://github.com/moritoru81/pgenv2.git $ cd pgenv2 $ source install.sh |
機能
今のところ以下ができます。ざっくりと言うと、xxenvと言われるソフトウェアと類似の機能があります。
- PostgreSQLのインストール(ソースアーカイブをダウンロードしてビルド)
- インストールした複数バージョンのPostgreSQLの切り替え
- ローカルマシン上でのレプリケーション環境の構築
利用可能なバージョン一覧の表示
公式サイトのWebページからリリースされているバージョン一覧を取得して表示します。
1 2 3 4 |
$ pgenv versions 1.08 1.09 ... |
インストール時に、ここで表示されるバージョンを指定します。
指定のバージョンのPostgreSQLをインストールする
pgenv versionsで利用可能なバージョン一覧を確認できたら、次はインストールします。以下では、10.1をインストールしています。
1 |
$ pgenv install 10.1 |
コマンドを実行すると、10.1のソースアーカイブをダウンロードして、展開、configure
、make
と実行していきます。ビルドのログは、pgenv/logs
にバージョンの名前で出力されます。
configureのオプションは、pgenv/configure_options
にデフォルトの条件が書いてあります。pgenvのconfigureコマンドで編集ができます。$EDITORで指定されるエディタでファイルを編集します。
1 |
pgenv configure --edit --global 10.1 |
無事にインストールできたら、以下でバージョン確認ができます。
1 2 3 4 5 6 |
$ pgenv list 10.1 * 10.3 10.4 9.6.9 9.5 |
上記では、現在10.3が有効ですが、10.1に切り替えてみます。
1 2 3 4 5 6 7 8 9 10 11 |
$ 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 |
切り替わったか確認します。
1 2 3 4 5 6 7 8 9 10 |
$ 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 |
インストール場所を確認してみます。
1 2 |
$ pgenv prefix /Users/guest/workspace/pgenv2/versions/10.1 |
レプリケーション環境の構築
PostgreSQLには、レプリケーション機能がありますが、サクッと手元で環境を構築し、動作確認したいことがあります。pgenv2には、そういった機能があります。
1対1の同期レプリケーションを組みたい場合、以下のようにできます。
1 |
$ pgenv cluster -D foo setup --sync-standby standby primary |
上記例では、fooというディレクトリに、各種インスタンスディレクトリが作成されます。
1 2 |
$ ls foo archivedir cluster_config.sh primary primary.conf standby standby.conf |
プライマリは「primary」、同期スタンバイは「standby」としています。各ノードの設定は、基本的に外出しで、include
パラメータで読み込ませています。port番号は、デフォルトでは24312から順にインクリメントして使用しています。
以下で構築した環境の状態を確認してみます。primary -> standby
はレプリケーション関係を示しています。pg_stat_replicationビューの情報をもとにしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ 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 -> |
別ターミナルで、各種インスタンスのログを表示しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ 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 |
続いて、スタンバイを昇格させてみます。
1 2 3 |
$ pg_ctl -D foo/standby promote waiting for server to promote.... done server promoted |
ログも出力されていることを確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
==> 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 |
レプリケーション状態を見てみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ 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に新しく非同期スタンバイを追加してみます。
1 |
$ pgenv cluster -D foo ctrl --attach --fork-off standby standby2 |
非同期スタンバイを起動します。非同期スタンバイ追加時にも-S
オプションで同時に起動できます。
1 |
$ pgenv cluster -D foo start standby2 |
レプリケーション状態を確認してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ 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 |
別の方法でも確認してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$ 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 |
インスタンスを停止します。
1 |
$ pgenv cluster -D foo stop -a |
昇格させたstandbyと非同期レプリケーションstandby2のみを起動します。
1 |
$ pgenv cluster -D foo start standby standby2 |
状態を確認してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ 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 |
と、こんな感じでレプリケーションの動作確認を手元ですぐに確認できます。
ちょっとした拡張機能の確認
1 2 3 4 5 6 7 |
$ 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()"' |
コメント