雑文発散

«前の日記(2012-12-31) 最新 次の日記(2013-01-02)» 編集
過去の日記

2013-01-01 [長年日記]

あけましておめでとうございます

無職での正月は初めてなので、なんか新鮮です(適当)。

ところで、2002年5月に tDiary で日記を書き始めたころは毎日日記を書いていました(日記だし)が、最近は年に数える程度の日記しか書いていない(日記じゃない)状態になっていたのですが、毎年1月1日だけは日記を書いていたのが長年日記で確認できて大変うれしく感じていたところであります。

昨日の日記のとおり、今年はいろいろ変わっていくつもりですので、みなさまよろしくお願いします。

[PostgreSQL] 複数バージョンの PostgreSQL をひとつのサーバで同時に利用する

PostgreSQL 9.0 と 9.1 と 9.2 を動かしながら比較したくなる事案が発生したので、ひとつのサーバに3つのバージョンを入れてみることにしたので、その時のメモ。

OS は慣れているので、CentOS 6 を選択。PostgreSQL は、CentOS のパッケージではなく、本家が用意している RPM パッケージを利用する。この方がマルチバージョンを実現しやすい。

手順としてはこんな感じ。

  1. CentOS 6 へ PostgreSQL 本家の yum リポジトリを登録。
  2. 各バージョンの PostgreSQL をインストール。
  3. 同時起動のための設定。
  4. 利用時のちょっとした工夫。

ということで、実施していく。

1. CentOS 6 へ PostgreSQL 本家の yum リポジトリを登録。

これはもうお馴染みの手順。PostgreSQL 本家に yum リポジトリを設定するための RPM パッケージが用意されているので、それを使う。

PostgreSQL RPM Building Project - Repository Packages のページから、インストールしたいバージョンと OS 用のパッケージを選択して取得する。リンクをクリックするといきなりダウンロードになるので、それだけ注意。

今回は、次のパッケージを利用した。

Version RPM パッケージ名
PostgreSQL 9.0 pgdg-centos90-9.0-5.noarch.rpm
PostgreSQL 9.1 pgdg-centos91-9.1-4.noarch.rpm
PostgreSQL 9.2 pgdg-centos92-9.2-6.noarch.rpm

これらをダウンロードして、インストールする。rpm コマンドで直接 URL を指定可能なのは知っているけど、なんとなく手元に残しておきたい派。

 # wget http://yum.postgresql.org/9.0/redhat/rhel-6-x86_64/pgdg-centos90-9.0-5.noarch.rpm
 # wget http://yum.postgresql.org/9.1/redhat/rhel-6-x86_64/pgdg-centos91-9.1-4.noarch.rpm
 # wget http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/pgdg-centos92-9.2-6.noarch.rpm
 # rpm -ivh pgdg-centos90-9.0-5.noarch.rpm
 # rpm -ivh pgdg-centos91-9.1-4.noarch.rpm
 # rpm -ivh pgdg-centos92-9.2-6.noarch.rpm

これで yum リポジトリが登録された。気になる人は /etc/yum.repos.d/ を見れば、ちゃんとインストールされているのが分かるはず。

 # ls -l /etc/yum.repos.d/
【中略】
-rw-r--r--. 1 root root  436  9月 24 05:52 2011 pgdg-90-centos.repo
-rw-r--r--. 1 root root  436  8月 22 20:30 2011 pgdg-91-centos.repo
-rw-r--r--. 1 root root  442  9月 24 07:47 2012 pgdg-92-centos.repo

2. 各バージョンの PostgreSQL をインストール。

リポジトリが登録されれば、後は各バージョンの PostgreSQL を yum コマンドでインストールするだけ。

 # yum install postgresql90-server postgresql91-server postgresql92-server

だいたいこんな感じで yum コマンドによって、依存関係が解決されるはず。自分での作業中には、この他にも細々とインストールしていたので、たぶん、この他にも libevent などの追加パッケージが表示されると思われる。

 Dependencies Resolved
 
 ==================================================================================================
  Package                      Arch            Version                       Repository       Size
 ==================================================================================================
 Installing:
  postgresql90-server          x86_64          9.0.11-1PGDG.rhel6            pgdg90          3.4 M
  postgresql91-server          x86_64          9.1.7-1PGDG.rhel6             pgdg91          3.6 M
  postgresql92-server          x86_64          9.2.2-1PGDG.rhel6             pgdg92          3.8 M
 Installing for dependencies:
  postgresql90                 x86_64          9.0.11-1PGDG.rhel6            pgdg90          946 k
  postgresql90-libs            x86_64          9.0.11-1PGDG.rhel6            pgdg90          191 k
  postgresql91                 x86_64          9.1.7-1PGDG.rhel6             pgdg91          990 k
  postgresql91-libs            x86_64          9.1.7-1PGDG.rhel6             pgdg91          189 k
  postgresql92                 x86_64          9.2.2-1PGDG.rhel6             pgdg92          959 k
  postgresql92-libs            x86_64          9.2.2-1PGDG.rhel6             pgdg92          181 k
 
 Transaction Summary
 ==================================================================================================
 Install       9 Package(s)

これで、各バージョンの PostgreSQL サーバとクライアント(psqlコマンド等)がインストールされた。

複数バージョンの PostgreSQL が、こんなに簡単にインストールできるのは、各バージョンのディレクトリ構成が工夫されているから。

例えば、データを格納する領域はこのように各バージョンで分けられている。

 # ls -l /var/lib/pgsql/
 合計 12
 drwx------. 4 postgres postgres 4096 12月 31 19:52 2012 9.0
 drwx------. 4 postgres postgres 4096 12月 31 19:53 2012 9.1
 drwx------. 5 postgres postgres 4096 12月 31 19:54 2012 9.2
クライアントも同様にバージョンごとのディレクトリが切られている。
 # ls -l /usr/
【中略】
drwxr-xr-x.  5 root root  4096 12月 31 19:51 2012 pgsql-9.0
drwxr-xr-x.  5 root root  4096 12月 31 19:51 2012 pgsql-9.1
drwxr-xr-x.  5 root root  4096 12月 31 19:51 2012 pgsql-9.2
【後略】

このディレクトリ構成を取っているのが PostgreSQL 本家が提供している RPM パッケージの特徴だと勝手に思っている。

というか、他にも工夫が見え隠れしているので、本家の開発者たちは、ナチュラルに複数バージョンの共存をしているんじゃないかなぁ。

3. 同時起動のための設定。

さて、インストールしただけでは使えないので、初期設定を少しする。

まずは PostgreSQL では定番の initdb という作業。データ領域の初期化を行なう。これは、各バージョンともに実施する必要がある。

 # service postgresql-9.0 initdb
 # service postgresql-9.1 initdb
 # service postgresql-9.2 initdb

initdb さえ行なえば、普通は起動準備が完了するのだけど、複数バージョンを同時起動するために少し工夫をする。

CentOS 6 用の PostgreSQL の起動スクリプトは、/etc/sysconfig/pgsql/ 以下に追加設定ファイルが存在すれば読みに行くように記述されている。

この小技を利用して、各バージョンの PostgreSQL の稼働ポート番号が重ならないように変更してやれば同時起動が可能になる。

起動スクリプトと追加設定ファイルの関係と、設定する稼働ポート番号の関係を次に示す。なお、稼働ポート番号は、特に決まりは無いので使える範囲で好きに設定して構わない。デフォルトが 5432 なので、9.2 をデフォルトとして、9.1、9.2 はひとつずつ減らした形で設計した。

起動スクリプト名 追加設定ファイル名 稼働ポート番号
/etc/init.d/postgresql-9.0 /etc/sysconfig/pgsql/postgresql-9.0 5430
/etc/init.d/postgresql-9.1 /etc/sysconfig/pgsql/postgresql-9.1 5431
/etc/init.d/postgresql-9.1 /etc/sysconfig/pgsql/postgresql-9.2 5432

各追加設定ファイルの中身はこれだけ。

 # cat /etc/sysconfig/pgsql/postgresql-9.0 
 PGPORT=5430
 # cat /etc/sysconfig/pgsql/postgresql-9.1 
 PGPORT=5431
 # cat /etc/sysconfig/pgsql/postgresql-9.2 
 PGPORT=5432

各起動スクリプト内の PGPORT=5432 という記述を直接修正する方法もあるのだけど、このように追加設定ファイルを利用した方がスマートじゃないかなーなどと勝手に思っている。

これで同時起動の設定も終えたので、サーバを起動する。

 # service postgresql-9.0 start
 # service postgresql-9.1 start
 # service postgresql-9.2 start

特に問題なく起動できているようなら、9.0、9.1、9.2 の同時起動が完成。

各サーバプロセスはこんな感じで見えると思う。

 # ps axf
16247 ?        S      0:01 /usr/pgsql-9.0/bin/postmaster -p 5430 -D /var/lib/pgsql/9.0/data
16249 ?        Ss     0:03  \_ postgres: logger process                                        
16251 ?        Ss     0:11  \_ postgres: writer process                                        
16252 ?        Ss     0:11  \_ postgres: wal writer process                                    
16253 ?        Ss     0:08  \_ postgres: autovacuum launcher process                           
16254 ?        Ss     0:04  \_ postgres: stats collector process                               
16293 ?        S      0:01 /usr/pgsql-9.1/bin/postmaster -p 5431 -D /var/lib/pgsql/9.1/data
16295 ?        Ss     0:03  \_ postgres: logger process                                        
16297 ?        Ss     0:11  \_ postgres: writer process                                        
16298 ?        Ss     0:11  \_ postgres: wal writer process                                    
16299 ?        Ss     0:05  \_ postgres: autovacuum launcher process                           
16300 ?        Ss     0:06  \_ postgres: stats collector process                               
27165 ?        S      0:00 /usr/pgsql-9.2/bin/postmaster -p 5432 -D /var/lib/pgsql/9.2/data
27167 ?        Ss     0:00  \_ postgres: logger process                                        
27169 ?        Ss     0:00  \_ postgres: checkpointer process                                  
27170 ?        Ss     0:00  \_ postgres: writer process                                        
27171 ?        Ss     0:00  \_ postgres: wal writer process                                    
27172 ?        Ss     0:00  \_ postgres: autovacuum launcher process                           
27173 ?        Ss     0:00  \_ postgres: stats collector process

4. 利用時のちょっとした工夫。

さて、サーバ側の設定はここまでで終わったので、今度はクライアント側の使い方。とは言っても、psql コマンドでポート番号を指定するオプションを付けるだけ。

なお、まだデータベース・ユーザを作成していないので、デフォルトの postgres ユーザを使用する。データベースもまだ作っていないので、最初から存在する postgres データベースを利用する。

まずは 9.0 を動かしている 5430 ポートを指定して psql を起動する。

 # su - postgres
 $ psql -p 5430 postgres
 psql (9.2.2, サーバー 9.0.11)
 注意: psql バージョン 9.2, サーバーバージョン 9.0.
          psql の機能の中で、動作しないものがあるかもしれません。
 "help" でヘルプを表示します.
 
 postgres=# 

ここで使っている psql コマンドは、9.2 バージョンになっている(9.0、9.1、9.2 の順番でインストールしたためだと思う)。サーバのバージョンが 9.0.11 (インストール時の 9.0 系最新)になっているのが見て取れる。

同じように 9.1、9.2 でも psql コマンドで接続してみる。

$ psql -p 5431 postgres
psql (9.2.2, サーバー 9.1.7)
注意: psql バージョン 9.2, サーバーバージョン 9.1.
         psql の機能の中で、動作しないものがあるかもしれません。
"help" でヘルプを表示します.

postgres=# 
$ psql -p 5432 postgres
psql (9.2.2)
"help" でヘルプを表示します.

postgres=# 

9.2 の時は、サーバのバージョンとクライアントのバージョンが同じなので「注意」の表示が出ない。

これで同一サーバで複数バージョンの同時利用という目的は達せられたのだけど、psql を立ち上げっぱなしにしていると、いまどのバージョンを利用しているのかが分からなくなる。

そこで、プロンプトを変更して「いまどのバージョンを利用しているのか」を常に表示するようにしてみた。これが「ちょっとした工夫」というところ。

psql コマンドには、その内部で利用する「変数」という概念がある。プロンプトを変更するためにも PROMPT1、PROMPT2、PROMPT3 という変数が用意されている。詳しくは公式ドキュメントを参照して欲しい。

こいつにバージョン番号とかを仕込んでしまえば良いなと思ったので、仕込んでみた。

デフォルトの PROMPT1 の設定が分からなかったので、psql の \set で表示させた。

 postgres=# \set
 【中略】
 PROMPT1 = '%/%R%# '
 PROMPT2 = '%/%R%# '
 PROMPT3 = '>> '
 【後略】

「\set PROMPT1 プロンプト文字列」で毎回セットするのもアレなので、psql コマンドのオプションで指定して起動してみることにした。

$ psql -p 5430 -v PROMPT1="v9.0 %/%R%# " -v PROMPT2="v9.0 %/%R%# " postgres

-v オプションが psql 変数を指定するオプション。デフォルトのプロンプト文字列の前にバージョン番号を入れた文字列を PROMPT1 と PROMPT2 にセットしている。

起動するとプロンプトがこのようになる。

v9.0 postgres=# 

ただ、毎回このオプションを手で入力するのはアレなので、alias 化してしまう。手元では bash を使っていたので、 ~/.bashrc へ次のように記述した。

 alias psql90='psql -p 5430 -v PROMPT1="v9.0 %/%R%# " -v PROMPT2="v9.0 %/%R%# "'
 alias psql91='psql -p 5431 -v PROMPT1="v9.1 %/%R%# " -v PROMPT2="v9.1 %/%R%# "'
 alias psql92='psql -p 5432 -v PROMPT1="v9.2 %/%R%# " -v PROMPT2="v9.2 %/%R%# "'

これで psql90、psql91、psql92 という alias で、それぞれ 9.0、9.1、9.2 へ接続することができ、各バージョン名が入ったプロンプトが表示される。

これで 9.x 系を比較しながら作業しやすい環境が整った。

ということで「やります!」と手をあげた翻訳書のレビューに本気出す!!(遅れててすみません。。。)