古いPostgreSQLのバージョンがインストールされている開発マシンがあったので、pg_upgradeの公式ドキュメントを参考に、PostgreSQL10.15 から PostgreSQL12.5 に移行してみました。
ドキュメントに よると
pg_upgradeは8.4.X以降から現時点のPostgreSQLのメジャーリリース(スナップショット版やβリリースを含む)へのアップグレードをサポートします。
ということで、古めのバージョンであってもpg_upgradeで一気にバージョンを上げられます。
前提
- 環境: Ubuntu 18.04 LTS デスクトップ
- 移行前バージョン: PostgreSQL10.15
- 移行後バージョン PostgreSQL12.5
バックアップを取得
念の為全DatabaseのDumpバックアップを取っておきます。
$ pg_dumpall > backup.sql
postgresql12をインストール
UbuntuへのPostgresqlのインストールは、公式の手順に従いました。
GPG keyを追加して、aptのsource.listにリポジトリを追加します。
$ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - $ echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" |sudo tee /etc/apt/sources.list.d/pgdg.list
このリポジトリには
- postgresql-client-12
- postgresql-12
- libpq-dev
- postgresql-contrib-9.x
- postgresql-server-dev-12
- pgadmin packages
といった一般的なパッケージやサードパーティアドオンのような様々なパッケージが含まれているようです。
apt updateして、postgresql12をインストールします。
$ sudo apt update
$ sudo apt -y install postgresql-12 postgresql-client-12
インストールが終わったら、念の為がpostgresql12のクラスタサービスが起動しているか確認します。
$ systemctl status postgresql@12-main.service ● postgresql@12-main.service - PostgreSQL Cluster 12-main Loaded: loaded (/lib/systemd/system/postgresql@.service; indirect; vendor pre Active: active (running) since Sat 2021-01-02 12:13:16 JST; 14min ago Process: 19223 ExecStop=/usr/bin/pg_ctlcluster --skip-systemctl-redirect -m fa Process: 22868 ExecStart=/usr/bin/pg_ctlcluster --skip-systemctl-redirect 12-m Main PID: 22877 (postgres) Tasks: 7 (limit: 4915) CGroup: /system.slice/system-postgresql.slice/postgresql@12-main.service ├─22877 /usr/lib/postgresql/12/bin/postgres -D /var/lib/postgresql/12 ├─22882 postgres: 12/main: checkpointer ├─22883 postgres: 12/main: background writer ├─22884 postgres: 12/main: walwriter ├─22885 postgres: 12/main: autovacuum launcher ├─22886 postgres: 12/main: stats collector └─22887 postgres: 12/main: logical replication launcher
バージョンを戻すことを考慮に入れて一応postgresqlサービスの状態を確認したうえで、停止しておきます。
$ systemctl is-enabled postgresql
enabled
$ sudo systemctl stop postgresql.service
アップグレード
postgresユーザでpg_upgradeを実行します。
$ sudo su postgres /usr/lib/postgresql/12/bin/pg_upgrade \ --old-datadir=/var/lib/postgresql/10/main \ --new-datadir=/var/lib/postgresql/12/main \ --old-bindir=/usr/lib/postgresql/10/bin \ --new-bindir=/usr/lib/postgresql/12/bin \ --old-options '-c config_file=/etc/postgresql/10/main/postgresql.conf' \ --new-options '-c config_file=/etc/postgresql/12/main/postgresql.conf' 整合性チェックを実行しています。 ----------------------------- Checking cluster versions ok Checking database user is the install user ok Checking database connection settings ok Checking for prepared transactions ok Checking for reg* data types in user tables ok Checking for contrib/isn with bigint-passing mismatch ok Checking for tables WITH OIDS ok Checking for invalid "sql_identifier" user columns ok Creating dump of global objects ok Creating dump of database schemas ok Checking for presence of required libraries ok Checking database user is the install user ok Checking for prepared transactions ok Checking for new cluster tablespace directories ok この後pg_upgradeが失敗した場合は、続ける前に新しいクラスタを initdbで再作成する必要があります。 アップグレードを実行しています。 ------------------ Analyzing all rows in the new cluster ok Freezing all rows in the new cluster ok Deleting files from new pg_xact ok Copying old pg_xact to new server ok Setting next transaction ID and epoch for new cluster ok Deleting files from new pg_multixact/offsets ok Copying old pg_multixact/offsets to new server ok Deleting files from new pg_multixact/members ok Copying old pg_multixact/members to new server ok Setting next multixact ID and offset for new cluster ok Resetting WAL archives ok Setting frozenxid and minmxid counters in new cluster ok Restoring global objects in the new cluster ok Restoring database schemas in the new cluster ok ユーザリレーションのファイルをコピーしています ok Setting next OID for new cluster ok Sync data directory to disk ok Creating script to analyze new cluster ok Creating script to delete old cluster ok アップグレードが完了しました ---------------- オプティマイザーの統計は、pg_upgrade では転送されません。そのため 新サーバーを起動した後、./analyze_new_cluster.sh を動かすことを検討してください。 このスクリプトを実行すると、旧クラスタのデータファイル ./delete_old_cluster.shが削除されます:
アップグレードが終わったので、postgresユーザから一般ユーザに戻します。
exit
新しくPostgreSQLバージョンのクラスタのポートがデフォルトポートではないため、postgresql.conf
のport番号を変更します。
$ sudo vim /etc/postgresql/12/main/postgresql.conf port = 5433 # (change requires restart) => port = 5432 # (change requires restart)
同様にpostgresql10のポートも変更します。
$ sudo vim /etc/postgresql/10/main/postgresql.conf port = 5432 # (change requires restart) => port = 5433 # (change requires restart)
もし、他にもpostgresql.confを変更している箇所があったり、rootユーザパスワードの認証なしでログインできる等の設定をpg_hba.confで行っている場合は、PostgreSQL12の方でも手動変更しておきます。
再度postgresサービスを起動し、接続を確認してみます。
sudo systemctl start postgresql.service
再度、postgresユーザに戻りpsqlコマンドがpostgresql12の方に接続しに行っているか確認します。
$ sudo su postgres $ psql -c "SELECT version();" PostgreSQL 12.5 (Ubuntu 12.5-1.pgdg18.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit
続いて、pg_upgrade実行時に生成されたanalyze_new_cluster.shを実行し、オプティマイザの統計情報を収集しておきます。
$ ./analyze_new_cluster.sh vacuumdb: データベース"calendar_development"の処理中です: 最適化のための情報を最小限生成します(1対象) vacuumdb: データベース"calendar_development"の処理中です: 最適化のための情報を最小限生成します(1対象) 〜〜〜 vacuumdb: データベース"world_myroom_development"の処理中です: 最適化のための情報をデフォルト数(全て)生成します Done
postgresql10の削除
接続が確認できたらpostgresql10は不要なので削除します。
$ sudo apt-get remove postgresql-10 postgresql-server-dev-10 $ sudo rm -rf /etc/postgresql/10/
再度、postgresユーザに戻って、pg_upgrade時に生成されたdelete_old_cluster.shを実行しておきます。
$ sudo su postgres ./delete_old_cluster.sh