pg_upgrade

PostgreSQL 9.1.1文書
前のページ | 巻戻し | 付録 F. 追加で提供されるモジュール | 早送り | 次のページ

# F.36. pg_upgrade

pg_upgrade(これまではpg_migratorと呼ばれていました)を使用して、メジャーバージョンへの更新、例えば、8.4.7から現時点のメジャーリリースのPostgreSQL、に通常必要とされたデータのダンプ/リストアを行うことなく、PostgreSQLデータファイル内に格納されたデータをより最新のPostgreSQLメジャーバージョンに移行することができます。 これは、例えば9.0.1から9.0.4などマイナーバージョンへの更新では必要ありません。

PostgreSQLのメジャーリリースでは通常、システムテーブルのレイアウトをよく変更する、多くの機能が追加されます。 しかし内部データの格納書式はまれにしか変更されません。 pg_upgradeはこの事実を使用して、システムテーブルを新しく作成し、古いユーザデータファイルを単に再利用することで、高速なアップグレードを実施します。 将来のメジャーリリースがついに古いデータ書式を読み取ることができないようにデータ格納書式を変更した場合、pg_upgradeではこうしたアップグレードを扱うことができません。 （コミュニティはこうした状況を防ごうと考えています。）

pg_upgradeは古いクラスタと新しいクラスタとの間で、例えばコンパイル時の設定に互換性があるかどうか、32ビットバイナリか64ビットバイナリかなど、バイナリ互換性があることを確実にするために最善を尽くします。 任意の外部モジュールがバイナリ互換であることも重要ですが、これはpg_upgradeでは検査することができません。

## F.36.1. サポートされるバージョン

pg_upgradeは8.3.X以降から現時点のPostgreSQLのメジャーリリース(スナップショット版やαリリースを含む)への更新をサポートします。

## F.36.2. pg_upgradeのオプション

pg_upgradeは以下のコマンドライン引数を受け付けます。

`-b` `old_bindir`
`--old-bindir=``old_bindir`

  古いクラスタの実行ファイル格納ディレクトリ。`OLDBINDIR`環境変数

`-B` `new_bindir`
`--new-bindir=``new_bindir`

  新しいクラスタの実行ファイル格納ディレクトリ。`NEWBINDIR`環境変数

`-c`
`--check`

  クラスタの検査のみを行い、データの変更を行いません。

`-d` `old_datadir`
`--old-datadir=``old_datadir`

  古いクラスタのデータディレクトリ。`OLDDATADIR`環境変数

`-D` `new_datadir`
`--new-datadir=``new_datadir`

  新しいクラスタのデータディレクトリ。`NEWDATADIR`環境変数

`-g`
`--debug`

  デバッグ処理を有効にします。

`-G` `debug_filename`
`--debugfile=``debug_filename`

  デバッグ処理の結果をファイルに出力します。

`-k`
`--link`

  新しいクラスタにファイルをコピーするのではなく、ハードリンクを使用します。

`-l` `log_filename`
`--logfile=``log_filename`

  セッションの結果をファイルに記録します。

`-p` `old_port_number`
`--old-port=``old_portnum`

  古いクラスタのポート番号。`PGPORT`環境変数

`-P` `new_port_number`
`--new-port=``new_portnum`

  新しいクラスタのポート番号。`PGPORT`環境変数

`-u` `user_name`
`--user=``user_name`

  クラスタのスーパーユーザの名称。`PGUSER`環境変数

`-v`
`--verbose`

  冗長出力を有効にします。

`-V`
`--version`

  バージョン情報を表示し、終了します。

`-?`
`-h`
`--help`

  使用方法を表示し、終了します。

## F.36.3. 更新手順

1. 古いクラスタの移動（省略可能）

   バージョンに関連したインストーレーションディレクトリ(例えば`/opt/PostgreSQL/8.4`)を使用しているのであれば、古いクラスタを移動する必要はありません。 この1クリックで済むインストーラはすべて、バージョンに関連したインストレーションディレクトリを使用します。

   インストーレーションディレクトリがバージョンに関連していない（例えば`/usr/local/pgsql`）のであれば、新しいPostgreSQLのインストレーションに干渉しないように、現在のPostgreSQLインストレーションディレクトリを移動しなければなりません。 一度現在のPostgreSQLサーバを停止させていれば、PostgreSQLのインストレーションの名前を変更しても安全です。 古いディレクトリが`/usr/local/pgsql`であれば、以下のようにディレクトリ名を変更します。

       mv /usr/local/pgsql /usr/local/pgsql.old

2. ソースからのインストールの場合の新しいバージョンの構築

   古いクラスタと互換性を持つような`configure`オプションを付けて新しいPostgreSQLソースを構築してください。 pg_upgradeは更新を始める前にすべての設定が互換性を持っていることを確認するために`pg_controldata`を検査します。

3. 新しいPostgreSQLのバイナリのインストール

   新しいサーバのバイナリとサポートファイルをインストールしてください。 古いクラスタと新しいクラスタが同時に稼動することはありませんので、両クラスタで同じポート番号(通常5432)を使用することができます。

   ソースからインストールする場合、独自の場所に新しいサーバをインストールしたければ、以下のように`prefix`を使用してください。

       gmake prefix=/usr/local/pgsql.new install

4. pg_upgradeおよびpg_upgrade_supportのインストール

   新しいPostgreSQLクラスタにpg_upgradeバイナリおよびpg_upgrade_supportライブラリをインストールしてください。

5. 新しいPostgreSQLクラスタを初期化

   `initdb`を使用して新しいクラスタを初期化してください。 繰り返しますが、古いクラスタに合うように互換性がある`initdb`のオプションを使用してください。 あらかじめ組み込まれたインストーラの多くは、この手順を自動的に実施します。 新しいクラスタを起動する必要はありません。

6. 独自の共有オブジェクトファイル(またはDLL)をインストール

   例えば、`pgcrypto.so`、`contrib`や何らかのその他のソースからインストールしたものなど、古いクラスタで使用していた独自の共有オブジェクトファイル(またはDLL)をすべて、新しいクラスタにインストールしてください。 例えば`pgcrypto.sql`などのスキーマ定義はインストールしないでください。 これらは古いクラスタから更新されるためです。

7. 認証の調整

   `pg_upgrade`は古いサーバと新しいサーバに複数回接続します。 このため、パスワードの問い合わせが繰り替えされることを防ぐために、`pg_hba.conf`内で`trust`認証に設定、あるいは、`md5`を使用しているのであれば`~/.pgpass`ファイル(項31.14参照)の使用するようにした方が良いかもしれません。

8. 両サーバの停止

   両サーバが停止していることを確実にしてください。 例えばUnixでは以下を使用します。

       pg_ctl -D /opt/PostgreSQL/8.4 stop
       pg_ctl -D /opt/PostgreSQL/9.0 stop

   Windowsでは以下

       NET STOP postgresql-8.4
       NET STOP postgresql-9.0

   または以下を適切なサービス名で使用します。

       NET STOP pgsql-8.3  (PostgreSQL 8.3以前では異なるサービス名が使用されていました。)

9. pg_upgradeの実行

   古いサーバのものではなく、常に新しいサーバのpg_upgradeバイナリを実行してください。 pg_upgradeは古いクラスタおよび新しいクラスタのデータと実行形式ファイルの格納ディレクトリ（`bin`）の指定を要求します。 また、ユーザやポート番号の指定や、コピー(デフォルト)ではなくデータリンクを使用するかどうかを指定することができます。

   リンクモードを使用する場合、アップグレードは非常に高速になります(ファイルのコピーがありません)が、更新後に新しいクラスタを一度でも実行してしまうと、古いクラスタにアクセスすることができなくなります。 リンクモードはまた、古いクラスタと新しいクラスタのデータディレクトリが同じファイルシステムにあることが必要です。 すべてのオプションリストを参照するためには`pg_upgrade --help`を使用してください。

   Windowsユーザの場合、管理者アカウントでログオンしなければなりません。 また、`postgres`ユーザとしてシェルを起動し、適切なパスを設定してください。

       RUNAS /USER:postgres "CMD.EXE"
       SET PATH=%PATH%;C:\Program Files\PostgreSQL\9.0\bin;

   そして、以下の例のように、引用符でくくったディレクトリを付けてpg_upgradeを実行してください。

       pg_upgrade.exe
               --old-datadir "C:/Program Files/PostgreSQL/8.4/data"
               --new-datadir "C:/Program Files/PostgreSQL/9.0/data"
               --old-bindir "C:/Program Files/PostgreSQL/8.4/bin"
               --new-bindir "C:/Program Files/PostgreSQL/9.0/bin"

   起動後、`pg_upgrade`は2つのクラスタに互換性があるかどうか検証し、その後、アップグレードを行います。 検査のみを行う`pg_upgrade --check`を使用することができます。 この場合は古いサーバは稼動中であっても構いません。 また`pg_upgrade --check`は、アップグレード後に手作業で行わなければならない調整作業があればその概要を示します。 `pg_upgrade`は現在のディレクトリに対する書き込み権限を必要とします。

   言うまでもありませんが、アップグレード中はクラスタにアクセスしてはいけません。 アップグレード中の意図しないクライアント接続を防ぐために、新旧のクラスタで50432などのデフォルト以外のポート番号を使用することを検討してください。

   データベーススキーマのリストア中にエラーが発生した場合、`pg_upgrade`は終了しますので、後述のステップ14で示すように古いクラスタに戻さなければなりません。 再び`pg_upgrade`を試すためには、pg_upgradeによるスキーマのリストアが成功するように古いクラスタを変更しなければなりません。 問題がcontribモジュールであれば、そのモジュールがユーザデータを格納するために使用されていないことが前提ですが、古いクラスタからそのcontribモジュールをアンインストールし、アップグレードした後に新しいクラスタにそれをインストールする必要があるかもしれません。

10. `pg_hba.conf`の復旧

    `pg_hba.conf`を`trust`を使用するように変更している場合は、元の認証設定に戻してください。

11. 移行後の処理

    アップグレード後の処理が必要な場合、pg_upgradeはその終了時に警告を発します。 また、管理者として実行しなければならないスクリプトファイルを生成します。 このスクリプトファイルは、アップグレード後の処理を必要とするデータベースそれぞれに接続します。 各スクリプトは以下を使用して実行しなければなりません。

        psql --username postgres --file script.sql postgres

    スクリプトは任意の順番で実行することができ、また、実行が終わったら削除することができます。

    注意
    一般的には、再構築用のスクリプトの実行が完了するより前に、再構築用のスクリプトで参照されるテーブルにアクセスすることは安全ではありません。 これを行うと間違った結果が生じたり、性能が劣化することがあり得ます。 再構築用のスクリプトで参照されないテーブルにはすぐにアクセスすることができます。

12. 統計情報

    オプティマイザの統計情報は`pg_upgrade`により転送されませんので、アップグレード後に統計情報を再生成するコマンドを実行するように指示されます。

13. 古いクラスタの削除

    更新処理が満足いくものであれば、`pg_upgrade`の終了時に示されたスクリプトを使用して、古いクラスタのデータディレクトリを削除することができます。 （`bin`、`share`など）古いインストレーションディレクトリは削除することもできます。

14. 古いクラスタへの復旧

    `pg_upgrade`を実行した後に古いクラスタに戻したい場合、いくつかの選択肢があります。

    - `--check`を付けた`pg_upgrade`を実行した場合、古いクラスタには変更はまったくなされていませんので、いつでも再使用することができます。

    - `--link`を付けた`pg_upgrade`を実行した場合、データファイルは古いクラスタと新しいクラスタとで共有されます。 もし新しいクラスタを起動していた場合、新しいサーバはこの共有されたファイルに書き出しを行いますので、古いクラスタで使用することは危険です。

    - `--link`を付けずに`pg_upgrade`を実行した場合、あるいは、新しいサーバを起動していない場合、`$PGDATA/global/pg_control`とおそらくテーブル空間ディレクトリに`.old`接尾辞が追加される点を除き、古いクラスタは変更されません。 古いクラスタを再度使用するためには、`$PGDATA/global/pg_control`から`.old`を取り除きます。 もし8.4以前にアップグレードする場合は、アップグレード処理で生成されたテーブル空間ディレクトリを削除し、テーブル空間ディレクトリ名から`.old`接尾辞を取り除きます。 その後、古いクラスタを再起動することができます。

## F.36.4. PostgreSQL 8.3からの移行における制限

PostgreSQL 8.3からアップグレードを行う場合には、それ以降のリリースのPostgreSQLからのアップグレードの場合にはない追加の制限があります。 例えば、ユーザ列が以下のように定義されていた場合、pg_upgradeは正常に8.3から移行できません。

- `tsquery`データ型

- `name`データ型が先頭列でない場合。

こうした列はすべて削除し、手作業でそれをアップグレードしなければなりません。

`ltree` contribモジュールがデータベース内にインストールされている場合、pg_upgradeは動作しません。

pg_upgradeは以下の場合、テーブルの再作成を要求します。

- ユーザ列が`tsvector`データ型の場合。

pg_upgradeは以下の場合インデックスの再作成を要求します。

- ハッシュまたはGINインデックス。

- `bpchar_pattern_ops`を使用するインデックス。

また、PostgreSQL 8.3より後では、日付時刻データのデフォルトの格納形式は整数型に変わりました。 pg_upgradeは、古いクラスタと新しいクラスタで使用される日付時刻データの格納形式が合致するかどうかを検査します。 確実に`--disable-integer-datetimes`を付けてconfigureを実行して新しいクラスタを構築してください。

Windowsユーザの場合、1クリックで済むインストーラとMSIインストーラで使用される整数日付時刻設定が異なるため、バージョン8.3の1クリックで済む配布物からバージョン8.4以降の1クリックで済む配布物への更新のみが可能であることに注意してください。 MSIインストーラから1クリックで済むインストーラへの更新を行うことはできません。

## F.36.5. 注意

pg_upgradeは次のOIDを参照する`reg*`システムデータ型を含むデータベースのアップグレードをサポートしません。 `regproc`、`regprocedure`、`regoper`、`regoperator`、`regclass`、`regconfig`、`regdictionary`。（`regtype`はアップグレード可能です。）

インストレーションに影響する場合、失敗、再構築、インデックス再作成はすべてpg_upgradeにより報告されます。 テーブルおよびインデックスを再構築するアップグレード後処理スクリプトは自動的に生成されます。

展開試験を行うのであれば、古いクラスタのスキーマのみをコピーしたものを作成し、ダミーデータを挿入してから、アップグレードを行ってください。

リンクモードを使用したいが、新しいクラスタを起動した時に古いクラスタを変更させたくない場合は、古いクラスタのコピーを取得してからリンクモードでアップグレードを行ってください。 有効な古いクラスタのコピーを取得するためには、サーバ稼動中に`rsync`を使用して古いクラスタの変動があるかもしれないコピーを作成し、古いサーバを停止させた後に、`rsync`を再度実行して一貫性を保つために何らかの変更をコピーに反映させます。

前のページ | ホーム | 次のページ
pg_trgm | 上に戻る | seg