はじめに
Rails Tips の 45 回目です。Rails のアプリを作成する前に PostgreSQL を設定します。Rails ガイドではシステム側の設定が不要な SQLite3 を利用していますが、少し凝ったことをするとなると PostgreSQL くらいは使いたくなります。いつも設計関係のいろんなコマンドなどを忘れてしまうので、たまにこうやって記事にしておこうと思います。
PostgreSQL をインストールする
Rails ガイドでは 3.1.2 の「SQLite3 をインストールする」ですが、ここでは PostgreSQL をインストールします。こちらは homebrew でインストールしました。PostgreSQL はバージョンごとにパッケージが異なり、最新版は postgresql@16 になっています。現在、単に postgresql とした場合は postgresql@14 が入るようになっており、@16 は /opt/homebrew/bin などにはパスが自動的にリンクされません。こちらの info でも postgresql@16 は keg-only でパスは設定されないので、自分で張るように指示されています。
==> postgresql@16: stable 16.1 (bottled) [keg-only] Object-relational database system https://www.postgresql.org/ /opt/homebrew/Cellar/postgresql@16/16.1_3 (3,796 files, 68.4MB) Poured from bottle using the formulae.brew.sh API on 2024-01-13 at 21:36:56 From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/p/postgresql@16.rb License: PostgreSQL ==> Dependencies Build: pkg-config ✔ Required: gettext ✔, icu4c ✔, krb5 ✔, lz4 ✔, openssl@3 ✔, readline ✔, zstd ✔ ==> Caveats This formula has created a default database cluster with: initdb --locale=C -E UTF-8 /opt/homebrew/var/postgresql@16 For more details, read: https://www.postgresql.org/docs/16/app-initdb.html postgresql@16 is keg-only, which means it was not symlinked into /opt/homebrew, because this is an alternate version of another formula. If you need to have postgresql@16 first in your PATH, run: fish_add_path /opt/homebrew/opt/postgresql@16/bin For compilers to find postgresql@16 you may need to set: set -gx LDFLAGS "-L/opt/homebrew/opt/postgresql@16/lib" set -gx CPPFLAGS "-I/opt/homebrew/opt/postgresql@16/include" For pkg-config to find postgresql@16 you may need to set: set -gx PKG_CONFIG_PATH "/opt/homebrew/opt/postgresql@16/lib/pkgconfig" To start postgresql@16 now and restart at login: brew services start postgresql@16 Or, if you don't want/need a background service you can just run: LC_ALL="C" /opt/homebrew/opt/postgresql@16/bin/postgres -D /opt/homebrew/var/postgresql@16
ほとんどのマシンはこのバージョンに上げていたのですが、今この記事を書いている持ち歩き用のマシンは普段開発をしていないので、postgresql でインストールした @14 のままでした。せっかくなので、このマシンも他のマシンと同様に @16 にアップグレードしてみます。校務支援システムでお世話になっている BPS 株式会社の TechRacho にこのアップグレードの記事が書いてありましたので、これを参考に上げていきましょう。
まず、@14 → @15 へのアップグレードをするために postgresql@15 のパッケージをインストールします。
brew install postgresql@15
ちなみに、15 の info は以下のようになっています。
==> postgresql@15: stable 15.5 (bottled) [keg-only] Object-relational database system https://www.postgresql.org/ /opt/homebrew/Cellar/postgresql@15/15.5_3 (3,700 files, 63MB) Poured from bottle using the formulae.brew.sh API on 2024-01-13 at 16:38:00 From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/p/postgresql@15.rb License: PostgreSQL ==> Dependencies Build: pkg-config ✔ Required: gettext ✔, icu4c ✔, krb5 ✔, lz4 ✔, openssl@3 ✔, readline ✔, zstd ✔ ==> Caveats This formula has created a default database cluster with: initdb --locale=C -E UTF-8 /opt/homebrew/var/postgresql@15 For more details, read: https://www.postgresql.org/docs/15/app-initdb.html postgresql@15 is keg-only, which means it was not symlinked into /opt/homebrew, because this is an alternate version of another formula. If you need to have postgresql@15 first in your PATH, run: fish_add_path /opt/homebrew/opt/postgresql@15/bin For compilers to find postgresql@15 you may need to set: set -gx LDFLAGS "-L/opt/homebrew/opt/postgresql@15/lib" set -gx CPPFLAGS "-I/opt/homebrew/opt/postgresql@15/include" For pkg-config to find postgresql@15 you may need to set: set -gx PKG_CONFIG_PATH "/opt/homebrew/opt/postgresql@15/lib/pkgconfig" To start postgresql@15 now and restart at login: brew services start postgresql@15 Or, if you don't want/need a background service you can just run: LC_ALL="C" /opt/homebrew/opt/postgresql@15/bin/postgres -D /opt/homebrew/var/postgresql@15
一方、現状の postgresql@14 はこんな感じです。
==> postgresql@14: stable 14.10 (bottled) Object-relational database system https://www.postgresql.org/ /opt/homebrew/Cellar/postgresql@14/14.10_1 (3,317 files, 46MB) * Poured from bottle using the formulae.brew.sh API on 2023-12-04 at 11:37:50 From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/p/postgresql@14.rb License: PostgreSQL ==> Dependencies Build: pkg-config ✔ Required: icu4c ✔, krb5 ✔, lz4 ✔, openssl@3 ✔, readline ✔ ==> Caveats This formula has created a default database cluster with: initdb --locale=C -E UTF-8 /opt/homebrew/var/postgresql@14 For more details, read: https://www.postgresql.org/docs/14/app-initdb.html To restart postgresql@14 after an upgrade: brew services restart postgresql@14 Or, if you don't want/need a background service you can just run: /opt/homebrew/opt/postgresql@14/bin/postgres -D /opt/homebrew/var/postgresql@14
この二つの情報から以下のコマンドでデータベースを upgrade します。
$ /opt/homebrew/Cellar/postgresql@15/15.5_3/bin/pg_upgrade \ -b /opt/homebrew/Cellar/postgresql@14/14.10_1/bin \ -d /opt/homebrew/var/postgresql@14 \ -B /opt/homebrew/Cellar/postgresql@15/15.5_3/bin \ -D /opt/homebrew/var/postgresql@15
サーバ稼働中のまま実行してしまったので以下のエラーが出ました。
旧クラスタで稼働中のpostmasterがあるようです。 そのpostmasterをシャットダウンしたのちにやり直してください。 失敗しました、終了しています
サーバを止めます。
$ brew services stop postgresql Stopping `postgresql@14`... (might take a while) ==> Successfully stopped `postgresql@14` (label: homebrew.mxcl.postgresql@14)
再度実行したところ、以下のように無事に転送が成功しました。
整合性チェックを実行しています。 ----------------------------- Checking cluster versions ok Checking database user is the install user ok Checking database connection settings ok Checking for prepared transactions ok Checking for system-defined composite types in user tables ok Checking for reg* data types in user tables ok Checking for contrib/isn with bigint-passing mismatch ok Creating dump of global objects ok Creating dump of database schemas ok Checking for presence of required libraries ok Checking database user is the install user ok Checking for prepared transactions ok Checking for new cluster tablespace directories ok この後pg_upgradeが失敗した場合は、続ける前に新しいクラスタを initdbで再作成する必要があります。 アップグレードを実行しています。 ------------------ Analyzing all rows in the new cluster ok Freezing all rows in the new cluster ok Deleting files from new pg_xact ok Copying old pg_xact to new server ok Setting oldest XID for new cluster ok Setting next transaction ID and epoch for new cluster ok Deleting files from new pg_multixact/offsets ok Copying old pg_multixact/offsets to new server ok Deleting files from new pg_multixact/members ok Copying old pg_multixact/members to new server ok Setting next multixact ID and offset for new cluster ok Resetting WAL archives ok Setting frozenxid and minmxid counters in new cluster ok Restoring global objects in the new cluster ok Restoring database schemas in the new cluster ok Copying user relation files ok Setting next OID for new cluster ok Sync data directory to disk ok Creating script to delete old cluster ok Checking for extension updates ok アップグレードが完了しました ---------------- オプティマイザーの統計は、pg_upgrade では転送されません。そのため 新サーバーを起動した後、以下を行うことを検討してください。 /opt/homebrew/Cellar/postgresql@15/15.5_3/bin/vacuumdb --all --analyze-in-stages このスクリプトを実行すると、旧クラスタのデータファイル ./delete_old_cluster.shが削除されます:
次に、そのまま @15 → @16 へのアップグレードをするために postgresql@16 のパッケージをインストールします。
brew install postgresql@16
上と同じように pg_upgrade を実施します。
/opt/homebrew/Cellar/postgresql@16/16.1_3/bin/pg_upgrade \ -b /opt/homebrew/Cellar/postgresql@15/15.5_3/bin \ -d /opt/homebrew/var/postgresql@15 \ -B /opt/homebrew/Cellar/postgresql@16/16.1_3/bin \ -D /opt/homebrew/var/postgresql@16 整合性チェックを実行しています。 ----------------------------- Checking cluster versions ok Checking database user is the install user ok Checking database connection settings ok Checking for prepared transactions ok Checking for system-defined composite types in user tables ok Checking for reg* data types in user tables ok Checking for contrib/isn with bigint-passing mismatch ok Checking for incompatible "aclitem" data type in user tables ok Creating dump of global objects ok Creating dump of database schemas ok Checking for presence of required libraries ok Checking database user is the install user ok Checking for prepared transactions ok Checking for new cluster tablespace directories ok この後pg_upgradeが失敗した場合は、続ける前に新しいクラスタを initdbで再作成する必要があります。 アップグレードを実行しています。 ------------------ Setting locale and encoding for new cluster ok Analyzing all rows in the new cluster ok Freezing all rows in the new cluster ok Deleting files from new pg_xact ok Copying old pg_xact to new server ok Setting oldest XID for new cluster ok Setting next transaction ID and epoch for new cluster ok Deleting files from new pg_multixact/offsets ok Copying old pg_multixact/offsets to new server ok Deleting files from new pg_multixact/members ok Copying old pg_multixact/members to new server ok Setting next multixact ID and offset for new cluster ok Resetting WAL archives ok Setting frozenxid and minmxid counters in new cluster ok Restoring global objects in the new cluster ok Restoring database schemas in the new cluster ok Copying user relation files ok Setting next OID for new cluster ok Sync data directory to disk ok Creating script to delete old cluster ok Checking for extension updates ok アップグレードが完了しました ---------------- オプティマイザーの統計は、pg_upgrade では転送されません。そのため 新サーバーを起動した後、以下を行うことを検討してください。 /opt/homebrew/Cellar/postgresql@16/16.1_3/bin/vacuumdb --all --analyze-in-stages このスクリプトを実行すると、旧クラスタのデータファイルが削除されます: ./delete_old_cluster.sh
アップデートされたので、サーバを起動してみます。
brew services start postgresql@16 ==> Successfully started `postgresql@16` (label: homebrew.mxcl.postgresql@16)
前述したように postgresql@16 は keg only なので、パスは自動で設定されません。このため、config.fish には以下のように PATH を設定しました。また、LDFLAGS, CPPFLAGS, PKG_CONFIG_PATH なども指示通りに設定します。
# homebrew set -gx PATH ~/bin /Library/TeX/texbin /opt/homebrew/opt/postgresql@16/bin /opt/homebrew/bin /usr/local/bin /usr/local/sbin ~/.cargo/bin $PATH set -gx LDFLAGS "-L/opt/homebrew/opt/postgresql@16/lib" set -gx CPPFLAGS "-I/opt/homebrew/opt/postgresql@16/include" set -gx PKG_CONFIG_PATH "/opt/homebrew/opt/postgresql@16/lib/pkgconfig"
シェルを起動して psql の場所を尋ねると以下のように @16 のものが検出されました。
which psql /opt/homebrew/opt/postgresql@16/bin/psql
ubuntu などの場合には postgres という専用ユーザが作成されますが、homebrew 版では利便性のためにログインユーザのアカウントが自動的に設定されています。そのため、psql template1 とするだけで、template1 データベースにアクセスできます。
$ psql template1 psql (16.1 (Homebrew)) "help"でヘルプを表示します。 template1=#
\du とすると既存のユーザが表示されます。16 だと日本語で表示されるのですね。
template1=# \du ロール一覧 ロール名 | 属性 ------------+------------------------------------------------------------------------------ hkob | スーパーユーザー, ロール作成可, DB作成可, レプリケーション可, RLS のバイパス rails7test | DB作成可 webcit | DB作成可
今回の blog ように blog ユーザを作成してみます。
create user blog; alter user blog with password 'パスワード'; alter user blog createdb;
再度ユーザを確認すると正しく作成されていることがわかります。
template1=# \du ロール一覧 ロール名 | 属性 ------------+------------------------------------------------------------------------------ blog | DB作成可 hkob | スーパーユーザー, ロール作成可, DB作成可, レプリケーション可, RLS のバイパス rails7test | DB作成可 webcit | DB作成可
Ubuntu などでは通常、pg_hba.conf を修正して権限設定が必要です。しかし、homebrew 版は基本的に開発用として考えられているため、localhost からのアクセスについては、許可という形の設定になっています。もし macOS 自体をサーバにするという場合にはこのあたりはちゃんと閉じる必要があると思います。
# "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust # IPv6 local connections: host all all ::1/128 trust # Allow replication connections from localhost, by a user with the # replication privilege. local replication all trust host replication all 127.0.0.1/32 trust host replication all ::1/128 trust
おわりに
とりあえず blog というユーザを作成したので、このユーザを元に明日は rails アプリの作成に入ります。