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では検査することができません。
pg_upgradeは8.3.X以降から現時点のPostgreSQLのメジャーリリース(スナップショット版やαリリースを含む)へのアップグレードをサポートします。
pg_upgradeは以下のコマンドライン引数を受け付けます。
古いPostgreSQLの実行ファイル格納ディレクトリ。PGBINOLD環境変数
新しいPostgreSQLの実行ファイル格納ディレクトリ。PGBINNEW環境変数
クラスタの検査のみを行い、データの変更を行いません。
古いクラスタのデータディレクトリ。PGDATAOLD環境変数
新しいクラスタのデータディレクトリ。PGDATANEW環境変数
使用する同時実行プロセスまたはスレッド数。
新しいクラスタにファイルをコピーするのではなく、ハードリンクを使用します。(Windowsではジャンクションポイントを使用してください。)
古いpostgresコマンドに直接渡すオプションです。
新しいpostgresコマンドに直接渡すオプションです。
古いクラスタのポート番号。PGPORTOLD環境変数
新しいクラスタのポート番号。PGPORTNEW環境変数
正常に完了した場合であってもSQLファイルとログファイルを保持します。
クラスタのスーパーユーザの名称。PGUSER環境変数
冗長な内部ログを有効にします。
バージョン情報を表示し、終了します。
使用方法を表示し、終了します。
pg_upgradeを用いたアップグレードを行う手順を示します。
古いクラスタの移動(省略可能)
バージョンに関連したインストレーションディレクトリ(例えば/opt/PostgreSQL/9.1)を使用しているのであれば、古いクラスタを移動する必要はありません。 グラフィカルインストーラはすべて、バージョンに関連したインストレーションディレクトリを使用します。
インストレーションディレクトリがバージョンに関連していない(例えば/usr/local/pgsql)のであれば、新しいPostgreSQLのインストレーションに干渉しないように、現在のPostgreSQLインストレーションディレクトリを移動しなければなりません。 一度現在のPostgreSQLサーバを停止させていれば、PostgreSQLのインストレーションの名前を変更しても安全です。 古いディレクトリが/usr/local/pgsqlであれば、以下のようにディレクトリ名を変更します。
mv /usr/local/pgsql /usr/local/pgsql.old
ソースからのインストールの場合の新しいバージョンの構築
古いクラスタと互換性を持つようなconfigureオプションを付けて新しいPostgreSQLソースを構築してください。 pg_upgradeはアップグレードを始める前にすべての設定が互換性を持っていることを確認するためにpg_controldataを検査します。
新しいPostgreSQLのバイナリのインストール
新しいサーバのバイナリとサポートファイルをインストールしてください。
ソースからインストールする場合、独自の場所に新しいサーバをインストールしたければ、以下のようにprefixを使用してください。
make prefix=/usr/local/pgsql.new install
pg_upgradeおよびpg_upgrade_supportのインストール
新しいPostgreSQLインストレーションにpg_upgradeバイナリおよびpg_upgrade_supportライブラリをインストールしてください。
新しいPostgreSQLクラスタを初期化
initdbを使用して新しいクラスタを初期化してください。 繰り返しますが、古いクラスタに合うように互換性があるinitdbのオプションを使用してください。 あらかじめ組み込まれたインストーラの多くは、この手順を自動的に実施します。 新しいクラスタを起動する必要はありません。
独自の共有オブジェクトファイルをインストール
例えば、pgcrypto.so、contribや何らかのその他のソースからインストールしたものなど、古いクラスタで使用していた独自の共有オブジェクトファイル(またはDLL)をすべて、新しいクラスタにインストールしてください。 例えばpgcrypto.sqlなどのスキーマ定義はインストールしないでください。 これらは古いクラスタからアップグレードされるためです。 また、独自の全文検索ファイル(辞書、同義語、類語辞書、ストップワード)も新しいクラスタにコピーしなければなりません。
認証の調整
pg_upgradeは古いサーバと新しいサーバに複数回接続します。 このため、pg_hba.conf内でtrustまたはpeer認証に設定、あるいは、~/.pgpassファイル(項31.15参照)を使用するようにした方が良いかもしれません。
両サーバの停止
両サーバが停止していることを確実にしてください。 例えば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以前では異なるサービス名が使用されていました。)
pg_upgradeの実行
古いサーバのものではなく、常に新しいサーバのpg_upgradeバイナリを実行してください。 pg_upgradeは古いクラスタおよび新しいクラスタのデータと実行形式ファイルの格納ディレクトリ(bin)の指定を要求します。 また、ユーザやポート番号の指定や、コピー(デフォルト)ではなくデータリンクを使用するかどうかを指定することができます。
リンクモードを使用する場合、アップグレードは非常に高速になり(ファイルのコピーがありません)、ディスク容量が少なくなりますが、アップグレード後に新しいクラスタを一度でも実行してしまうと、古いクラスタにアクセスすることができなくなります。 リンクモードはまた、古いクラスタと新しいクラスタのデータディレクトリが同じファイルシステムにあることが必要です。 (テーブル空間およびpg_xlogは異なるファイルシステムに置くことができます。) すべてのオプションリストを参照するためにはpg_upgrade --helpを使用してください。
--jobsオプションにより複数のCPUコアを使用して、並行してファイルのコピー・リンク、データベーススキーマのダンプと再ロードを行うことができます。 この値の最大値として検討を始める際には、CPUコア数またはテーブル空間数を勧めます。 このオプションはマルチプロセッサを持つマシンで実行している複数のデータベースサーバをアップグレードする時間を大きく減らします。
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は、アップグレード後に手作業で行わなければならない調整作業があればその概要を示します。 リンクモードを使用する予定であれば、リンクモード固有の検査を有効にするために--checkを付けて--linkを使用すべきです。 pg_upgradeは現在のディレクトリに対する書き込み権限を必要とします。
言うまでもありませんが、アップグレード中はクラスタにアクセスしてはいけません。 意図しないクライアント接続を防ぐために、デフォルトではpg_upgradeは50432ポートでサーバを稼働します。 古いクラスタと新しいクラスタが同時に稼動することはありませんので、両クラスタで同じポート番号を使用することができます。 しかし実行中の古いクラスタを検査する時には、新旧で異なるポート番号でなければなりません。
データベーススキーマのリストア中にエラーが発生した場合、pg_upgradeは終了しますので、後述のステップ14で示すように古いクラスタに戻さなければなりません。 再びpg_upgradeを試すためには、pg_upgradeによるスキーマのリストアが成功するように古いクラスタを変更しなければなりません。 問題がcontribモジュールであれば、そのモジュールがユーザデータを格納するために使用されていないことが前提ですが、古いクラスタからそのcontribモジュールをアンインストールし、アップグレードした後に新しいクラスタにそれをインストールする必要があるかもしれません。
pg_hba.confの復旧
pg_hba.confを変更している場合は、元の認証設定に戻してください。 また新しいクラスタにおけるこの他の設定ファイル、例えばpostgresql.conf、も古いクラスタに合わせるように調整する必要があります。
移行後の処理
アップグレード後の処理が必要な場合、pg_upgradeはその終了時に警告を発します。 また、管理者として実行しなければならないスクリプトファイルを生成します。 このスクリプトファイルは、アップグレード後の処理を必要とするデータベースそれぞれに接続します。 各スクリプトは以下を使用して実行しなければなりません。
psql --username postgres --file script.sql postgres
スクリプトは任意の順番で実行することができ、また、実行が終わったら削除することができます。
注意 |
一般的には、再構築用のスクリプトの実行が完了するより前に、再構築用のスクリプトで参照されるテーブルにアクセスすることは安全ではありません。 これを行うと間違った結果が生じたり、性能が劣化することがあり得ます。 再構築用のスクリプトで参照されないテーブルにはすぐにアクセスすることができます。 |
統計情報
オプティマイザの統計情報はpg_upgradeにより転送されませんので、アップグレード後に統計情報を再生成するコマンドを実行するように指示されます。 新しいクラスタに合わせるために接続パラメータを設定する必要があるかもしれません。
古いクラスタの削除
アップグレード処理が満足いくものであれば、pg_upgradeの終了時に示されたスクリプトを使用して、古いクラスタのデータディレクトリを削除することができます。 (古いデータディレクトリ内にユーザ定義のテーブル空間がある場合には、自動削除は不可能です。) (bin、shareなど)古いインストレーションディレクトリも削除できます。
古いクラスタへの戻し
pg_upgradeを実行した後に古いクラスタに戻したい場合、いくつかの選択肢があります。
--checkを付けたpg_upgradeを実行した場合、古いクラスタには変更はまったくなされていませんので、いつでも再使用することができます。
--linkを付けたpg_upgradeを実行した場合、データファイルは古いクラスタと新しいクラスタとで共有されます。 もし新しいクラスタを起動していた場合、新しいサーバはこの共有されたファイルに書き出しを行いますので、古いクラスタで使用することは危険です。
--linkを付けずにpg_upgradeを実行した場合、あるいは、新しいサーバを起動していない場合、リンク処理が始まると、$PGDATA/global/pg_controlに.old接尾辞が追加される点を除き、古いクラスタは変更されません。 古いクラスタを再度使用するためには、$PGDATA/global/pg_controlから.old接尾辞を取り除きます。 その後、古いクラスタを再起動することができます。
pg_upgradeは次のOIDを参照するreg*システムデータ型を含むデータベースのアップグレードをサポートしません。 regproc、regprocedure、regoper、regoperator、regconfig、regdictionary。(regtypeはアップグレード可能です。)
インストレーションに影響する場合、失敗、再構築、インデックス再作成はすべてpg_upgradeにより報告されます。 テーブルおよびインデックスを再構築するアップグレード後処理スクリプトは自動的に生成されます。 多くのクラスタのアップグレードを自動化することを考えているのであれば、 すべてのクラスタのアップグレードにおいて同一のデータベーススキーマを持つクラスタが同じアップグレード後処理を必要とすることが分かるはずです。 これはアップグレード後処理がデータ自体ではなくデータベーススキーマに基づいているためです。
展開試験を行うのであれば、古いクラスタのスキーマのみをコピーしたものを作成し、ダミーデータを挿入してから、アップグレードを行ってください。
設定ファイルしか持たないディレクトリを使用するPostgreSQL 9.2よりも前のクラスタをアップグレードする場合、例えば-d /real-data-directory -o '-D /configuration-directory'のように、実際のデータディレクトリの場所をpg_upgradeに通知しなければならず、さらに設定用ディレクトリの場所をサーバに通知しなければなりません。
デフォルト以外のUnixドメインソケットディレクトリを使用する、または新しいクラスタのデフォルトとは異なるデフォルトを使用する9.1より前の古いサーバを使用している場合、古いサーバのソケット位置を指し示すようにPGHOSTを設定してください。(これはWindowsでは関係ありません。)
サーバは書き込みを許可しなければなりませんので、ログシッピングスタンバイサーバ(項25.2)をアップグレードすることができません。 最も簡単な方法は、プライマリをアップグレードし、スタンバイを再構築するためにrsyncを使用することです。 プライマリを停止している間、またはベースバックアップ(項24.3.2)の一部としてrsyncを実行して古いスタンバイクラスタを上書きすることができます。
リンクモードを使用したいが、新しいクラスタを起動した時に古いクラスタを変更させたくない場合は、古いクラスタのコピーを取得してからリンクモードでアップグレードを行ってください。 有効な古いクラスタのコピーを取得するためには、サーバ稼動中にrsyncを使用して古いクラスタの変動があるかもしれないコピーを作成し、古いサーバを停止させた後に、rsyncを再度実行して一貫性を保つために何らかの変更をコピーに反映させます。 例えば項24.3.3で説明したpostmaster.pidなど、一部のファイルを除外したいと考えるかもしれません。 スナップショットやコピーは同時、もしくはデータベースサーバが停止しているときに作らなければなりませんが、ファイルシステムがファイルシステムのスナップショットやコピーオンライトファイルコピーをサポートしているのなら、それを古いクラスタとテーブル空間のバックアップをするのに使うことができます。
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ユーザの場合、グラフィカルインストーラとMSIインストーラで使用される整数日付時刻設定が異なるため、バージョン8.3のインストーラによる配布物からバージョン8.4以降のインストーラによる配布物へのアップグレードのみが可能であることに注意してください。 MSIインストーラから新しいグラフィカルインストーラへのアップグレードを行うことはできません。