PostgreSQL 13 アップデート

:warning: 警告! データベースが非常に大きい場合、大量の追加ディスク容量(データベースサイズの 2 倍)が必要となり、このアップグレードには非常に注意が必要です!

Docker イメージを PostgreSQL 13 にアップグレードする変更が適用されました。コマンドラインから Discourse を再構築するサイト管理者は、以前の PostgreSQL 12 から PostgreSQL 13 にアップグレードされます。PostgreSQL 12 の更新が 5 月に発生した際 にアップグレードを見送った場合、そのアップグレードをスキップして直接 PostgreSQL 13 に移行できます。

以前アップグレードを見送っていた場合は、app.yml 内の PostgreSQL テンプレートを templates/postgres.10.template.yml から templates/postgres.template.yml に変更してください。

どのアップグレードでも同様ですが、何を行う前に必ずバックアップを取得することを強く推奨します。

アップデート方法

公式インストールガイド(シングルコンテナ)

次回の再構築時に、最後に以下のメッセージが表示されます。

-------------------------------------------------------------------------------------
UPGRADE OF POSTGRES COMPLETE

Old 12 database is stored at /shared/postgres_data_old

To complete the upgrade, rebuild again using:

./launcher rebuild app
-------------------------------------------------------------------------------------

これはアップグレードが正常に完了したことを意味します。サイトを再び稼働させるには、単に新しい再構築を実行するだけです。

データコンテナインストール

Discourse_docker リポジトリで提供されているサンプルに基づいた専用データコンテナを使用して設定している場合、PostgreSQL を安全かつクリーンにシャットダウンしていることを確認してください。

現在、数分間にわたるクエリを実行するバックグラウンドジョブが実行されているため、Web コンテナをシャットダウンすると、データコンテナの安全なシャットダウンに役立ちます。

./launcher stop web_only
./launcher stop data
./launcher rebuild data
./launcher rebuild data
./launcher rebuild web_only

データコンテナに対して最初の再構築を実行する前に、PostgreSQL ログを tail して正しくシャットダウンされたか確認できます。

クリーンなシャットダウンの場合、tail -f shared/data/log/var-log/postgres/current を実行すると、以下のようなログが表示されます。

2020-05-13 18:33:33.457 UTC [36] LOG:  received smart shutdown request
2020-05-13 18:33:33.464 UTC [36] LOG:  worker process: logical replication launcher (PID 52) exited with exit code 1
2020-05-13 18:33:33.465 UTC [47] LOG:  shutting down
2020-05-13 18:33:33.479 UTC [36] LOG:  database system is shut down

手動アップデート / 容量制約のある環境

:warning::warning::warning:
試す前に必ず PG_DATA をバックアップしてください
:warning::warning::warning:

容量が制限された環境で追加の容量を取得する方法がない場合は、以下を試すことができます。

./launcher stop app #(または、その場合は web_only と data の両方)
mkdir -p /var/discourse/shared/standalone/postgres_data_new
docker run --rm \
	-v /var/discourse/shared/standalone/postgres_data:/var/lib/postgresql/12/data \
	-v /var/discourse/shared/standalone/postgres_data_new:/var/lib/postgresql/13/data \
	tianon/postgres-upgrade:12-to-13
mv /var/discourse/shared/standalone/postgres_data /var/discourse/shared/standalone/postgres_data_old
mv /var/discourse/shared/standalone/postgres_data_new /var/discourse/shared/standalone/postgres_data
./launcher rebuild app #(または、その場合はまず data、次に web_only)

私のテストでは、この手順には現在のデータベースサイズ未満の空き容量(1 倍未満)しか必要ありません。

アップデートの延期

次回の再構築時にアップデートを延期する必要がある場合は、app.yml ファイル内の PostgreSQL テンプレートを "templates/postgres.template.yml" から "templates/postgres.12.template.yml" に変更することで交換できます。

後で変更を元に戻すことを忘れるサイト管理者がいる可能性があるため、これは推奨されません。

アップデート後のオプションタスク

PostgreSQL 統計情報の最適化

アップデート後、新しい PostgreSQL にはテーブル統計情報が含まれていません。以下を使用して生成できます。

cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
VACUUM VERBOSE ANALYZE;
\q
exit
exit

または、上記の 1 行バージョン:

/var/discourse/launcher run app "echo 'vacuum verbose analyze;' | su postgres -c 'psql discourse'"

インデックスの再作成

このアップグレードの主な機能は、すべてのインスタンスで最大のテーブルである post_timings テーブルとそのインデックスにおける大幅なファイルサイズの削減です。正常にアップデートした後、インデックスを再構築して恩恵を受けるためにコマンドを実行する必要があります。

cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
REINDEX SCHEMA CONCURRENTLY public;
\q
exit
exit

REINDEX の前後で post_timings のサイズを確認できれば、共有できる素晴らしい統計データになります!

以下のクエリを使用して、再構築前後に 20 個の最大のデータオブジェクトを確認できます。

WITH RECURSIVE pg_inherit(inhrelid, inhparent) AS
    (select inhrelid, inhparent
    FROM pg_inherits
    UNION
    SELECT child.inhrelid, parent.inhparent
    FROM pg_inherit child, pg_inherits parent
    WHERE child.inhparent = parent.inhrelid),
pg_inherit_short AS (SELECT * FROM pg_inherit WHERE inhparent NOT IN (SELECT inhrelid FROM pg_inherit))
SELECT table_schema
    , TABLE_NAME
    , row_estimate
    , pg_size_pretty(total_bytes) AS total
    , pg_size_pretty(index_bytes) AS INDEX
    , pg_size_pretty(toast_bytes) AS toast
    , pg_size_pretty(table_bytes) AS TABLE
  FROM (
    SELECT *, total_bytes-index_bytes-COALESCE(toast_bytes,0) AS table_bytes
    FROM (
         SELECT c.oid
              , nspname AS table_schema
              , relname AS TABLE_NAME
              , SUM(c.reltuples) OVER (partition BY parent) AS row_estimate
              , SUM(pg_total_relation_size(c.oid)) OVER (partition BY parent) AS total_bytes
              , SUM(pg_indexes_size(c.oid)) OVER (partition BY parent) AS index_bytes
              , SUM(pg_total_relation_size(reltoastrelid)) OVER (partition BY parent) AS toast_bytes
              , parent
          FROM (
                SELECT pg_class.oid
                    , reltuples
                    , relname
                    , relnamespace
                    , pg_class.reltoastrelid
                    , COALESCE(inhparent, pg_class.oid) parent
                FROM pg_class
                    LEFT JOIN pg_inherit_short ON inhrelid = oid
                WHERE relkind IN ('r', 'p')
             ) c
             LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
  ) a
  WHERE oid = parent
) a
ORDER BY total_bytes DESC LIMIT 20;

古いデータのクリーンアップ

標準インストールの場合、以下のコマンドで PG12 形式の古いデータを削除できます。

cd /var/discourse
./launcher cleanup

別々のデータコンテナを使用している場合は、以下のようにバックアップコピーを削除する必要があります。

rm -fr /var/discourse/shared/data/postgres_data_old/

よくある質問 (FAQ)

ソースクラスタがクリーンにシャットダウンされませんでした

上記のメッセージでアップグレードに失敗した場合、より簡単なアプローチでより良い状態に戻すことができます。

./launcher start app で古いコンテナを再起動します。復旧するまで数分待ってください。

次に ./launcher stop app で再度シャットダウンします。その後、ログを tail してクリーンなシャットダウンだったか確認します。

tail -f shared/data/log/var-log/postgres/current
2020-05-13 18:33:33.457 UTC [36] LOG:  received smart shutdown request
2020-05-13 18:33:33.464 UTC [36] LOG:  worker process: logical replication launcher (PID 52) exited with exit code 1
2020-05-13 18:33:33.465 UTC [47] LOG:  shutting down
2020-05-13 18:33:33.479 UTC [36] LOG:  database system is shut down

ログが上記のようであれば、./launcher rebuild app を使用して再度アップグレードを試みることができます。

データベース “postgres” の lc_collate 値が一致しません

このエラーは、データベースにデフォルト以外のロケールを使用している場合に発生します。成功するには 3 つの変数が必要であることが報告されています。app.yml ファイルの env: セクションに以下の 3 行が含まれていることを確認してください。

  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8

en_US.UTF-8 をお使いのロケールに変更してください。

再構築のたびにアップグレードが再度実行される(アップグレードループ)

この場合、アップグレードログには以下が含まれます。

mv: cannot move '/shared/postgres_data' to '/shared/postgres_data_old/postgres_data': Directory not empty
mv: cannot move '/shared/postgres_data_new' to '/shared/postgres_data/postgres_data_new': Directory not empty

これは、最後のアップグレードからファイルが残っていることを意味します。続行する前にそれらを別の場所に移動してください。

アップグレード完了の提案スクリプト - 何か行う必要がありますか?

アップグレードが完了すると、pg_upgrade メッセージから以下のような出力が表示されます。

Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
    ./analyze_new_cluster.sh

Running this script will delete the old cluster's data files:
    ./delete_old_cluster.sh

このメッセージは安全に無視できます。

PostgreSQL 12 のアップデートをスキップしましたが、今どうすればよいですか?

このガイドの上部にある標準的な手順に従うだけで、問題なくお使いのバージョンから 13 にアップグレードできます。

容量制約のある手順に従っている場合は、バージョン番号を適宜調整してください。

「いいね!」 38
PostgreSQL Details
Discourse 2.7.0.beta2 Release Notes
Forum offline due to failed rebuilds on Tests-Pass
Nginx upstream timed out (110: Connection timed out)
Firewall issue with running multiple containers after upgrade
Help! Problem with firewall/permissions and postgre?
PostgreSQL 13 update from PostgreSQL 10 fails
PostgreSQL 13 update from PostgreSQL 10 fails
Unrecognized error type (ActiveRecord::StatementInvalid: PG::ProgramLimitExceeded
Recover from filesystem backup: can't rebuild nor start
Rebuild error: Errno::ENOENT: No such file or directory @ rb_sysopen - /e tc/postgresql/13/main/pg_hba.conf
Discourse broken after upgrade
Upgrade Failed from 2.7.0.beta1 to 2.7.0.beta3
Invalid location error after update
Upgrade failed!
Upgrade failed: PostgreSQL version 13 ... not compatible with ... version 10.12
Improved Bookmarks with Reminders
Importing old database to latest version
Errors encountered when uploading images
What else do I need to take care of when self hosting?
Rebuild freezing when attempting to stop container
Backup failed due to PG/SQL errors
Restore Failing - Check Free Disk Space
Supported postgresql versions
Wrong Error Message for too short replies for Reply-by-Email
Upgrade Postgres with REALLY limited space
Upgrade Postgres with REALLY limited space
Postgres has 100% CPU for large databases, Discourse 2.7.7
Upgrade failing with FAILED TO BOOTSTRAP
Stuck in an update loop after PostgreSQL 13 update
Problem with rebuild Discourse at Docker
After Rebuild got error: postgres:10/main, Causes CPU to go high
Call AdminDashboardGeneralData.refresh_stats at boot?
ERROR: You are running an old version of the Discourse image
Failed to upgrade to v2.9.0beta3
Failed to upgrade to v2.9.0beta3
SMTP Settings in app.yml reset?
Upgrade container - keeping config and data
Site down after failed update: permission denied to create extension "unaccent"
Rebuild fails on db:migrate w/PG12
Update from 2.9.0 beta2 to beta4 failed (my site is down)
Performance optimisation tips
Upgrading from 2.4 to 2.9. Need slight assistance on what order to run the final commands & reboot in
Problem when updating Discourse Forum
Troubleshooting severe performance issues with latest Discourse?
Slow Profile Loads with 100GB+ database
Use Nginx Proxy Manager to manage multiple sites with Discourse
Horizontal loading slider
Upgrading Discourse from 2.6.0.beta2
PostgreSQL 15 update
Got a lot of "Failed to backfill 'Reader' badge" errors
Trouble updating discourse after some time - UPGRADE OF POSTGRES FAILED
Database size/maintenance
Upgrade gone sideways [deprecated Guest Gate plugin]
Upgrade Issues: Failed Upgrade due to Duplicate Key, Failed Snapshot Restore
2.7.0.beta2 upgrade failed with ERROR: duplicate key
Problem, rebuild to latest version
Urgent, upgraded build failed UniqueViolation