Macで複数のバージョンのPostgresqlを共存させる


Postgresql 9.1から9.3にアップデートする必要があったのですが、一時的にMac内に2つのバージョンを共存させておく必要がありました。ちょっと試行錯誤して、homebrewを使って実現できたので書いておきます。

環境

  • Mac 10.11 El Capitan
  • Homebrew 0.9.5

Postgresqlのインストール

まずPostgresqlの新バージョンをインストールします。homebrew versionsを使用するとバージョンを指定することができます。バージョン名がtap名になってるので、brew upgrade をしても勝手にメジャーバージョンが上がってしまうことがないので便利。

📄bin/pg
$ brew tap homebrew/versions

インストール可能なPostgresqlをリストアップしてみます。

$ brew search postgresql
homebrew/versions/postgresql8     homebrew/versions/postgresql92    postgresql
homebrew/versions/postgresql9     homebrew/versions/postgresql93
homebrew/versions/postgresql91 ✔  homebrew/versions/postgresql94

postgresql91(バージョン9.1)にチェックが付いているのはインストール済みだから。さっそく9.3をインストールします。

$ brew install postgresql93

インストールが完了したら「initdbしろよ」的なメッセージが表示されると思います。その前に現在brew linkされているpostgresqlのバージョンを確認しておきます。

$ which initdb | xargs readlink
../Cellar/postgresql91/9.1.18/bin/initdb

つまり9.3はただインストールされただけで、linkはされてない(=パスが通ってない)という状況です。どちらのバージョンを使うかその都度切り替えられるようにしたいので、まずは現在の9.1のデータディレクトリをリネームします。(データディレクトリはinitdb時に指定するのですが、通常は/usr/local/var/postgresになってると思います。)

$ brew unlink postgresql91 # 先にunlinkしておく
$ mv /usr/local/var/postgres /usr/local/var/postgres91

これで9.3をセットアップする準備ができました。さっそくlinkしてinitdbを。

$ brew link postgresql93
$ initdb /usr/local/var/postgres93 -E utf8

9.3用のデータディレクトリを作成できました。

起動・停止スクリプト

あとはbrew link/unlinkを駆使して起動・停止するPostgresqlのバージョンをその都度切り替えられるようにします。私が作ったスクリプトを貼っておきます。簡易的なものですが、普段使いには問題ないと思います。

#!/bin/bash

readonly INSTALLED_VERSIONS=(`brew list | command grep postgresql | tr -d postgresql`)

is_supported_version() {
  local found=false
  for v in ${INSTALLED_VERSIONS[@]}; do
    if [ $v -eq $1 ]; then
      found=true
      break
    fi
  done
  echo $found
}

get_current_version() {
  echo `which pg_ctl \
      | xargs readlink \
      | sed -e 's/.*Cellar\/postgresql//g' \
      | sed -e 's/\/.*pg_ctl//g'`
}


if [ $# -ne 2 ]; then
  echo "Usage: `basename $0` [version] [pg_ctl option]" 1>&2
  exit 1
fi

version=$1
pg_ctl_option=$2

if [ `is_supported_version $version` = false ]; then
  echo "${version} is unsupported version." 1>&2
  echo "Supported versions are ${INSTALLED_VERSIONS[@]}." 1>&2
  exit 1
fi

current_version=`get_current_version`
if [ -z $current_version ]; then
  command brew link postgresql${version}
elif [ $version != $current_version ]; then
  command brew unlink postgresql${current_version}
  command brew link postgresql${version}
fi

readonly PG_DIR="/usr/local/var/postgres${version}"
command pg_ctl -D $PG_DIR -l $PG_DIR/server.log $pg_ctl_option

exit 0

使い方は以下のような感じ。

$ pg
Usage: pg [version] [pg_ctl option]
$ pg 91 start # 9.1を起動
$ pg 91 stop  # 9.1を停止
$ pg 93 start # 9.3を起動
$ pg 93 stop  # 9.3を停止

 

素直に仮想環境使えよとも思うんですが、独りプロジェクトとかだと手間の割にあんまりメリットがないんですよねー。独りでできるぐらいなので環境自体シンプルだし。Rails使うことが多いんですが、Rubyはrbenv、gemはbundlerで環境分けられるし。

何かの役に立てば幸いです。

関連する記事


コメントする

メールアドレスが公開されることはありません。

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください