Skip to content

Commit ac4d148

Browse files
committed
PostgreSQL アップグレードガイドを追加
- pg_upgrade によるデータ保持アップグレード - インストール方法 - トラブルシューティングなど
1 parent c381616 commit ac4d148

File tree

1 file changed

+346
-0
lines changed

1 file changed

+346
-0
lines changed

doc/how_to_upgrade_postgresql.md

Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
# PostgreSQL アップグレードガイド
2+
3+
## 背景
4+
5+
`heroku pg:pull` でデータベースをプルする際、**本番環境とローカル環境の PostgreSQL メジャーバージョンが一致している必要があります**
6+
7+
バージョンが異なると、以下のようなエラーが発生します:
8+
9+
```
10+
pg_dump: エラー: サーバーバージョンの不一致のため処理を中断します
11+
pg_dump: 詳細: サーバーバージョン: X.Y、pg_dump バージョン: X.Y (Homebrew)
12+
```
13+
14+
****(2026年1月時点):
15+
- 本番環境: PostgreSQL 17.6
16+
- ローカル環境: PostgreSQL 16.9
17+
- 結果: バージョン不一致でエラー
18+
19+
## 本番環境のバージョンを確認
20+
21+
まず、本番環境(Heroku)の PostgreSQL バージョンを確認します:
22+
23+
```bash
24+
heroku pg:info --app coderdojo-japan | grep "PG Version"
25+
```
26+
27+
## 現在のローカルバージョンを確認
28+
29+
```bash
30+
psql --version
31+
```
32+
33+
本番環境と同じメジャーバージョン(例: 両方とも 17.x)であれば問題ありません。異なる場合はアップグレードが必要です。
34+
35+
## アップグレード方法
36+
37+
どちらのオプションを選ぶべきか:
38+
- **他のプロジェクトのデータベースも保持したい****オプション1(pg_upgrade)を推奨**
39+
- **すべてのデータベースを本番から再プルできる** → オプション2(クリーンインストール)が簡単
40+
41+
### オプション1: データを保持してアップグレード(pg_upgrade 使用)
42+
43+
既存のローカル DB データを保持したい場合、PostgreSQL の `pg_upgrade` ツールを使用します。
44+
45+
**このオプションの利点**:
46+
- すべてのデータベース(複数プロジェクト)を一度に移行できる
47+
- データ損失のリスクがない
48+
- 移行後すぐに作業を再開できる
49+
50+
**このオプションの欠点**:
51+
- 手順が複雑(10ステップ)
52+
- 互換性チェックやデータディレクトリの準備が必要
53+
54+
```bash
55+
# 1. 新しいバージョンをインストール
56+
brew install postgresql@<新しいバージョン>
57+
58+
# 2. 古いバージョンを停止
59+
brew services stop postgresql@<古いバージョン>
60+
61+
# 3. 互換性チェック(安全確認、データは変更されない)
62+
/opt/homebrew/opt/postgresql@<新しいバージョン>/bin/pg_upgrade \
63+
--old-datadir /opt/homebrew/var/postgresql@<古いバージョン> \
64+
--new-datadir /opt/homebrew/var/postgresql@<新しいバージョン> \
65+
--old-bindir /opt/homebrew/opt/postgresql@<古いバージョン>/bin \
66+
--new-bindir /opt/homebrew/opt/postgresql@<新しいバージョン>/bin \
67+
--check
68+
69+
# 4. データディレクトリの準備(brew install で自動初期化されるため)
70+
mv /opt/homebrew/var/postgresql@<新しいバージョン> \
71+
/opt/homebrew/var/postgresql@<新しいバージョン>.initial
72+
mkdir -p /opt/homebrew/var/postgresql@<新しいバージョン>
73+
/opt/homebrew/opt/postgresql@<新しいバージョン>/bin/initdb \
74+
-D /opt/homebrew/var/postgresql@<新しいバージョン> \
75+
--locale=en_US.UTF-8 -E UTF-8
76+
77+
# 5. 実際のアップグレード実行(--check フラグなし)
78+
/opt/homebrew/opt/postgresql@<新しいバージョン>/bin/pg_upgrade \
79+
--old-datadir /opt/homebrew/var/postgresql@<古いバージョン> \
80+
--new-datadir /opt/homebrew/var/postgresql@<新しいバージョン> \
81+
--old-bindir /opt/homebrew/opt/postgresql@<古いバージョン>/bin \
82+
--new-bindir /opt/homebrew/opt/postgresql@<新しいバージョン>/bin
83+
84+
# 6. 新しいバージョンを起動
85+
brew services start postgresql@<新しいバージョン>
86+
87+
# 7. PATH を更新(新しいターミナルで有効化)
88+
echo 'export PATH="/opt/homebrew/opt/postgresql@<新しいバージョン>/bin:$PATH"' >> ~/.zshrc
89+
90+
# 8. 現在のセッションで PATH を更新
91+
export PATH="/opt/homebrew/opt/postgresql@<新しいバージョン>/bin:$PATH"
92+
93+
# 9. オプティマイザ統計を更新(pg_upgrade 推奨)
94+
/opt/homebrew/opt/postgresql@<新しいバージョン>/bin/vacuumdb --all --analyze-in-stages
95+
96+
# 10. バージョン確認
97+
psql --version
98+
```
99+
100+
**Intel Mac の場合**: `/opt/homebrew``/usr/local` に置き換えてください。
101+
102+
### オプション2: クリーンインストール(簡単だが注意が必要)
103+
104+
**⚠️ 警告**: このオプションでは、古いバージョンの**すべてのデータベース**が削除されます。他の Rails プロジェクトのデータベースも含まれます。
105+
106+
**このオプションが適している場合**:
107+
- すべてのプロジェクトのデータベースを本番から再プルできる
108+
- ローカルに重要なデータベースがない
109+
- または、必要なデータベースを事前にバックアップ済み
110+
111+
**手順**:
112+
113+
```bash
114+
# 0. 重要なデータベースをバックアップ(必要に応じて)
115+
psql -l # 現在のデータベース一覧を確認
116+
pg_dump <データベース名> > backup_<データベース名>.sql
117+
118+
# 1. 古いバージョンを停止・アンインストール
119+
brew services stop postgresql@<古いバージョン>
120+
brew uninstall postgresql@<古いバージョン>
121+
122+
# 2. 新しいバージョンをインストール
123+
brew install postgresql@<新しいバージョン>
124+
125+
# 3. 新しいバージョンを起動
126+
brew services start postgresql@<新しいバージョン>
127+
128+
# 4. PATH を更新(新しいターミナルで有効化)
129+
echo 'export PATH="/opt/homebrew/opt/postgresql@<新しいバージョン>/bin:$PATH"' >> ~/.zshrc
130+
131+
# 5. 現在のセッションで PATH を更新
132+
export PATH="/opt/homebrew/opt/postgresql@<新しいバージョン>/bin:$PATH"
133+
134+
# 6. バージョン確認
135+
psql --version
136+
137+
# 7. バックアップから復元(必要に応じて)
138+
createdb <データベース名>
139+
psql <データベース名> < backup_<データベース名>.sql
140+
```
141+
142+
**Intel Mac の場合**: `/opt/homebrew``/usr/local` に置き換えてください。
143+
144+
**推奨**: 他のプロジェクトのデータベースも保持したい場合は、**オプション1(pg_upgrade)を使用してください**。すべてのデータベースを安全に移行できます。
145+
146+
## アップグレード後の確認
147+
148+
```bash
149+
# 1. PostgreSQL サービスの状態確認
150+
brew services list | grep postgresql
151+
# 期待される出力: postgresql@<新しいバージョン> started
152+
153+
# 2. 古いバージョンが動いていないか確認(重要)
154+
# 複数バージョンが "started" の場合、古いバージョンに接続される可能性あり
155+
# 古いバージョンが動いている場合: brew services stop postgresql@<古いバージョン>
156+
157+
# 3. psql のバージョン確認
158+
psql --version
159+
160+
# 4. 実際に接続してサーバーバージョンを確認
161+
psql -d postgres -c "SELECT version();"
162+
# クライアント(psql)とサーバーのバージョンが一致しているか確認
163+
```
164+
165+
## 本番データベースのプル
166+
167+
アップグレード後、本番環境のデータベースをローカルにプルできます:
168+
169+
```bash
170+
# ローカル DB を削除してから本番データをプル
171+
RAILS_ENV=development DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rails db:drop
172+
heroku pg:pull DATABASE_URL coderdojo_jp_development --app coderdojo-japan
173+
174+
# マイグレーションを実行(必要に応じて)
175+
bundle exec rails db:migrate
176+
177+
# ローカルサーバーを起動して確認
178+
bundle exec rails server
179+
```
180+
181+
## トラブルシューティング
182+
183+
### 複数バージョンが起動していて接続先が間違う
184+
185+
**症状**: `psql --version` は新しいバージョンを表示するが、`SELECT version()` で古いバージョンに接続される
186+
187+
**原因**: 複数の PostgreSQL サービスが同時に起動している
188+
189+
**解決方法**:
190+
```bash
191+
# すべての PostgreSQL サービスの状態を確認
192+
brew services list | grep postgresql
193+
194+
# 古いバージョンをすべて停止
195+
brew services stop postgresql@<古いバージョン>
196+
197+
# 新しいバージョンを再起動
198+
brew services restart postgresql@<新しいバージョン>
199+
200+
# 接続先を確認
201+
psql -d postgres -c "SELECT version();"
202+
```
203+
204+
### heroku pg:pull でバージョン不一致エラーが出る
205+
206+
**症状**: `psql --version` は正しいが、`heroku pg:pull` で「pg_dump バージョン: <古い>」エラー
207+
208+
**原因**: Heroku CLI が古い pg_dump を使用している(PATH を無視)
209+
210+
**解決方法**:
211+
```bash
212+
# 1. ターミナルを完全に再起動(PATH を完全にリロード)
213+
# または
214+
# 2. 新しいターミナルウィンドウを開く
215+
216+
# 3. それでもダメな場合、Heroku CLI を再インストール
217+
brew reinstall heroku/brew/heroku
218+
```
219+
220+
### PATH が正しく設定されていない
221+
222+
**症状**: `psql --version` が古いバージョンを表示
223+
224+
**解決方法**:
225+
```bash
226+
# 現在の psql のパスを確認
227+
which psql
228+
229+
# 期待されるパス(Apple Silicon)
230+
# /opt/homebrew/opt/postgresql@<新しいバージョン>/bin/psql
231+
232+
# 期待されるパス(Intel Mac)
233+
# /usr/local/opt/postgresql@<新しいバージョン>/bin/psql
234+
235+
# 現在のセッションで PATH を更新
236+
export PATH="/opt/homebrew/opt/postgresql@<新しいバージョン>/bin:$PATH"
237+
238+
# 新しいターミナルで確認
239+
psql --version
240+
```
241+
242+
### PostgreSQL サービスが起動しない
243+
244+
```bash
245+
# サービスの状態を確認
246+
brew services list | grep postgresql
247+
248+
# エラー状態の場合、ログを確認
249+
tail -f /opt/homebrew/var/log/postgresql@<バージョン>.log
250+
251+
# サービスを再起動
252+
brew services restart postgresql@<バージョン>
253+
254+
# データディレクトリの権限を確認
255+
ls -la /opt/homebrew/var/postgresql@<バージョン>
256+
```
257+
258+
## アップグレード完了後のクリーンアップ(オプション)
259+
260+
**⚠️ 重大な警告**: クリーンアップは非常に危険な操作です。**他のプロジェクトのデータベースも削除される可能性があります**
261+
262+
### クリーンアップ前の必須確認(絶対に省略しないでください)
263+
264+
アップグレードで使用しなかった**すべての PostgreSQL バージョン**に、重要なデータベースが残っていないか確認してください。
265+
266+
```bash
267+
# 1. インストールされているすべての PostgreSQL バージョンを確認
268+
brew list | grep postgresql
269+
270+
# 2. 各バージョンのデータベースを確認(重要!)
271+
# 例: PostgreSQL 14, 15, 16 など、アップグレードに使用しなかったバージョン
272+
273+
# PostgreSQL 14 のデータベース一覧を確認
274+
/opt/homebrew/opt/postgresql@14/bin/psql -l 2>/dev/null
275+
276+
# PostgreSQL 15 のデータベース一覧を確認
277+
/opt/homebrew/opt/postgresql@15/bin/psql -l 2>/dev/null
278+
279+
# 3. 重要なデータベースが見つかった場合、必ずバックアップを取る
280+
/opt/homebrew/opt/postgresql@<バージョン>/bin/pg_dump <データベース名> > ~/backup_<データベース名>_$(date +%Y%m%d).sql
281+
282+
# 4. すべてのプロジェクトで使用されていないことを確認
283+
# 例: ~/project1, ~/project2 などの config/database.yml を確認
284+
```
285+
286+
### クリーンアップの安全な手順
287+
288+
すべてのデータベースを確認し、必要なバックアップを取った後のみ実行してください。
289+
290+
```bash
291+
# 1. 新しいバージョンが正常に動作していることを確認
292+
psql -d postgres -c "SELECT version();"
293+
brew services list | grep postgresql
294+
295+
# 2. 削除対象のデータベースを最終確認(再度確認!)
296+
echo "以下のデータベースが削除されます:"
297+
/opt/homebrew/opt/postgresql@<削除するバージョン>/bin/psql -l
298+
299+
# 3. 本当に削除して良いか、もう一度確認してください
300+
# バックアップは取りましたか?
301+
# 他のプロジェクトで使用していませんか?
302+
303+
# 4. 古いバージョンのサービスを停止
304+
brew services stop postgresql@<削除するバージョン>
305+
306+
# 5. データディレクトリを削除
307+
rm -rf /opt/homebrew/var/postgresql@<削除するバージョン>
308+
309+
# 6. pg_upgrade で作成されたバックアップも削除(オプション1を使用した場合)
310+
rm -rf /opt/homebrew/var/postgresql@<新しいバージョン>.initial
311+
312+
# 7. Homebrew パッケージをアンインストール
313+
brew uninstall postgresql@<削除するバージョン>
314+
315+
# 8. クリーンアップされた状態を確認
316+
brew services list | grep postgresql
317+
du -sh /opt/homebrew/var/postgresql@* 2>/dev/null
318+
```
319+
320+
### 実際に発生した災害事例
321+
322+
**ケース**: 複数の Rails プロジェクトで異なる PostgreSQL バージョンを使用していた環境で、PostgreSQL 16 → 17 へのアップグレード後、PostgreSQL 14 のデータディレクトリを確認せずに削除してしまった。
323+
324+
**結果**:
325+
- PostgreSQL 14 を使用していた他の商用プロジェクトのデータベースがすべて失われた
326+
- 本番環境からの再プルが必要になり、復旧に時間がかかった
327+
- 本番環境がないプロジェクトのデータは完全に失われた
328+
329+
**教訓**:
330+
1. クリーンアップ前に**すべての PostgreSQL バージョン**のデータベースを確認する
331+
2. `rm -rf` を実行する前に必ずバックアップを取る
332+
3. 疑わしい場合は削除しない(ディスク容量は後で整理できる)
333+
4. 複数プロジェクトを管理している場合、特に注意が必要
334+
335+
**推奨**: クリーンアップを急ぐ必要はありません。数週間運用して問題がないことを確認してから削除しても遅くありません。
336+
337+
## 参考情報
338+
339+
- Heroku の PostgreSQL バージョン: https://devcenter.heroku.com/articles/heroku-postgresql#version-support-and-legacy-infrastructure
340+
- Homebrew PostgreSQL: https://formulae.brew.sh/formula/postgresql
341+
- PostgreSQL バージョン一覧: https://www.postgresql.org/support/versioning/
342+
- pg_upgrade 公式ドキュメント: https://www.postgresql.org/docs/current/pgupgrade.html
343+
344+
## 更新履歴
345+
346+
- 2026-01-21: 初版作成、pg_upgrade の正しい手順を追加、実際の経験に基づく改善

0 commit comments

Comments
 (0)