Help us understand the problem. What is going on with this article?

postgresでメジャーバージョンを跨いでダウングレードが出来た話(ver9.4⇒ver8.2)

More than 3 years have passed since last update.

概要

一般的に、postgresのバージョンアップは一方通行(accelerator)と言われています。
アップグレードは以下の通りとても簡単にできるのですが、不可逆であることが通説です。

■バージョンアップ:pg_dumpall -h 古いバージョン | psql -h 新しいバージョン
■バージョンダウン:pg_dumpall -h 新しいバージョン | psql -h 古いバージョン ←大変たくさん警告が出ます。もちろんキチンと戻りません

本記事では、準備をしておけばpostgresのダウングレードを"出来る/出来た"ことを共有したいと思います。
postgresをバージョンアップして暫く運用していたが、止む無く戻さざるを得ない状況でのノウハウです。
※私の場合ではpostgre9.4⇒postgres8.2へ下げられました

本記事の対象読者

  • これからpostgresをバージョンアップしようとされている方
  • とりあえずpostgresのVersion上げてみたら散々な結果になった方(レアケースとは思います)
  • postgresマスター(どうぞ、私の間違いを正してください)

手順概要

  • 事前
    1. バージョンアップ前環境のスキーマ定義をダンプしておく(pg_dumpall -s)
    2. バージョンアップ後環境でDDLを実行した場合は、それをメモっておく
  • リストア時
    1. バージョンアップ前環境のスキーマダンプをcreate系ファイルとalter系ファイルに分割
    2. バージョンアップ後のDDLをcreate系ファイル、alter系ファイルへ手動で反映
    3. 前バージョンのDBへcreate系ファイルでスキーマをリストア(psql -f create系ファイル)
    4. 新バージョンのDBの設定を変更(bytea_output = 'hex' ⇒ 'escape')
    5. 新バージョンのDBからデータだけリストア(pg_dumpall -a -h 前バージョンDB)
    6. 前バージョンのDBへalter系ファイルで外部キー制約などをリストア(psql -f alter系ファイル)

実際の手順

バージョンアップ前

  1. バージョンアップ前環境のスキーマ定義をダンプしておく(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系ファイル)
/前バージョン/bin/psql -h 前バージョンのDB -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)
/新しいバージョン/bin/pg_dumpall -a -h バージョンアップ後DB | /前バージョン/bin/psql -h 前バージョンDB

6.前バージョンのDBへalter系ファイルで外部キー制約などをリストア
/前バージョン/bin/psql -h 前バージョンのDB -f alter系ファイル

補足

  • スキーマダンプをcreate系とalter系に分ける理由は、外部キー制約によってpg_dumpallで直接データをリストアできないためです
  • 経験的に画像ファイル(jpgなど)のラージオブジェクトのデータはver9⇒ver8で戻せませんでした。どうしても戻す必要がある場合、実ファイルを手動でDBへinsertし直す必要があります
  • ver9⇒ver8へ戻す場合"ERROR: unrecognized configuration parameter "lock_timeout"は無視してよいです

最後に

postgresのダウングレードは、公式にはサポートされていません。
しかし、プロダクション環境で片道切符しか用意しないというのは心臓によくありません。
ぜひ事前にリストア検証を行って頂き、少しでも安心材料を増やしてアップグレードに挑んで頂ければと存じます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした