概要
一般的に、postgresのバージョンアップは一方通行(accelerator)と言われています。
アップグレードは以下の通りとても簡単にできるのですが、不可逆であることが通説です。
■バージョンアップ:pg_dumpall -h 古いバージョン | psql -h 新しいバージョン
■バージョンダウン:pg_dumpall -h 新しいバージョン | psql -h 古いバージョン ←大変たくさん警告が出ます。もちろんキチンと戻りません
本記事では、準備をしておけばpostgresのダウングレードを"出来る/出来た"ことを共有したいと思います。
postgresをバージョンアップして暫く運用していたが、止む無く戻さざるを得ない状況でのノウハウです。
※私の場合ではpostgre9.4⇒postgres8.2へ下げられました
本記事の対象読者
- これからpostgresをバージョンアップしようとされている方
- とりあえずpostgresのVersion上げてみたら散々な結果になった方(レアケースとは思います)
- postgresマスター(どうぞ、私の間違いを正してください)
手順概要
- 事前
- バージョンアップ前環境のスキーマ定義をダンプしておく(pg_dumpall -s)
- バージョンアップ後環境でDDLを実行した場合は、それをメモっておく
- リストア時
- バージョンアップ前環境のスキーマダンプをcreate系ファイルとalter系ファイルに分割
- バージョンアップ後のDDLをcreate系ファイル、alter系ファイルへ手動で反映
- 前バージョンのDBへcreate系ファイルでスキーマをリストア(psql -f create系ファイル)
- 新バージョンのDBの設定を変更(bytea_output = 'hex' ⇒ 'escape')
- 新バージョンのDBからデータだけリストア(pg_dumpall -a -h 前バージョンDB)
- 前バージョンのDBへalter系ファイルで外部キー制約などをリストア(psql -f alter系ファイル)
実際の手順
バージョンアップ前
- バージョンアップ前環境のスキーマ定義をダンプしておく(pg_dumpall -s)
pg_dumpall -s > 前バージョンのスキーマダンプ
リストア時
1.バージョンアップ前環境のスキーマダンプをcreate系ファイルとalter系ファイルに分割
TGTFILE=前バージョンのスキーマダンプ
awk -v DATE=`date +%Y%m%d%H%M%S` 'BEGIN{FILE = "pg_dump_create_"DATE }{
if(($0 ~ /^\\connect|^SET/)){print $0 >> "pg_dump_create_"DATE ; print $0 >> "pg_dump_alter_"DATE}
if(($1 ~ /^--/)){FILE = "pg_dump_create_"DATE ; next}
if(($1 ~ /^CREATE/)){FILE = "pg_dump_create_"DATE}
if(($0 ~ /ALTER TABLE ONLY/)){FILE = "pg_dump_alter_"DATE}
{print $0 >> FILE}
}' ${TGTFILE}
※create系ファイル"pg_dump_create_日時"と、
alter系ファイル"pg_dump_alter_日時"の2個のファイルを作成しています
2.バージョンアップ後のDDLをcreate系ファイル、alter系ファイルへ手動で反映
※ここは手動(ハートウォーミング)でやるしかないです...
3.前バージョンのDBへcreate系ファイルでスキーマをリストア(psql -f create系ファイル)
4.新バージョンのDBのバイナリデータ型の設定を変更(bytea_output = 'hex' ⇒ 'escape')
vi /新しいバージョン/DB領域/postgres.conf
#bytea_output = 'hex'
↓
bytea_output = 'escape'
5.新バージョンのDBからデータだけリストア(pg_dumpall -a -h 前バージョンDB)
6.前バージョンのDBへalter系ファイルで外部キー制約などをリストア
補足
- スキーマダンプをcreate系とalter系に分ける理由は、外部キー制約によってpg_dumpallで直接データをリストアできないためです
- 経験的に画像ファイル(jpgなど)のラージオブジェクトのデータはver9⇒ver8で戻せませんでした。どうしても戻す必要がある場合、実ファイルを手動でDBへinsertし直す必要があります
- ver9⇒ver8へ戻す場合"ERROR: unrecognized configuration parameter "lock_timeout"は無視してよいです
最後に
postgresのダウングレードは、公式にはサポートされていません。
しかし、プロダクション環境で片道切符しか用意しないというのは心臓によくありません。
ぜひ事前にリストア検証を行って頂き、少しでも安心材料を増やしてアップグレードに挑んで頂ければと存じます。