WARNING! If your database is very large, you will need a lot of extra disk space (2x database size) and should be very careful with this upgrade!
We’ve just landed changes to upgrade our Docker image to PostgreSQL 15. Any site admins rebuilding Discourse from the command line will be upgraded to PostgreSQL 15 from the previous PostgreSQL 13. Note that if you held back from upgrading when the PostgreSQL 13 update happened back in 2020, you can skip that upgrade and go straight to PostgreSQL 15.
If you had held back the upgrade previously, change the PostgreSQL template in app.yml
from templates/postgres.12.template.yml
to templates/postgres.template.yml
.
As with any upgrade, it is strongly advised to take a backup before doing anything.
Updating
Official Install Guide (single container)
On your next rebuild, you will see this message at the end:
-------------------------------------------------------------------------------------
UPGRADE OF POSTGRES COMPLETE
Old 13 database is stored at /shared/postgres_data_old
To complete the upgrade, rebuild again using:
./launcher rebuild app
-------------------------------------------------------------------------------------
That means everything went well in the upgrade! You just need to issue a new rebuild to get your site back and running.
Data Container Install
If you are running a setup with a dedicated data container based in the sample supplied in our discourse_docker repository, you want to be sure you are shutting down PostgreSQL in a safe and clean way.
Nowadays, we have background jobs running queries spanning several minutes, so shutting down the web container will help the data container be shutdown safely.
./launcher stop web_only
./launcher stop data
./launcher rebuild data
./launcher rebuild data
./launcher rebuild web_only
Before issuing the first rebuild to the data container, you can tail the PostgreSQL log to see if it was shutdown properly.
Running a tail -f shared/data/log/var-log/postgres/current
should give you the following log if it was clean:
2025-01-24 09:19:06.437 UTC [37] LOG: received smart shutdown request
2025-01-24 09:19:06.444 UTC [37] LOG: background worker "logical replication launcher" (PID 54) exited with exit code 1
2025-01-24 09:19:06.446 UTC [49] LOG: shutting down
2025-01-24 09:19:06.468 UTC [37] LOG: database system is shut down
Doing a manual update / space constrained environments
YOU MUST BACKUP THE POSTGRES_DATA BEFORE TRYING THIS
If you are in a constrained space environment without any way to get more space you can try the following:
./launcher stop app #(or both web_only and data if that is your case)
mkdir -p /var/discourse/shared/standalone/postgres_data_new
docker run --rm \
--entrypoint=/bin/bash \
-v /var/discourse/shared/standalone/postgres_data:/var/lib/postgresql/13/data \
-v /var/discourse/shared/standalone/postgres_data_new:/var/lib/postgresql/15/data \
tianon/postgres-upgrade:13-to-15 \
-c "apt-get update && apt-get install -y postgresql-15-pgvector && docker-upgrade"
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 #(or first data and then web_only if that is your case)
On my tests this procedure requires less than 1x your current database size in free space.
Postponing the update
If you need to postpone the update during your next rebuild, you can swap the PostgreSQL template on your app.yml file by changing "templates/postgres.template.yml"
to "templates/postgres.13.template.yml"
.
This is not recommended, as some site admins will forget to revert the change afterwards.
Post update optional tasks
Optimizing PostgreSQL statistics
After the update, the new PostgreSQL won’t have table statistics on hand. You can generate those using:
docker exec -u postgres app \
/usr/lib/postgresql/15/bin/vacuumdb -d discourse --analyze-in-stages
Cleaning up old data
For a standard install, you can delete the old data in PG13 format with the following command:
cd /var/discourse
./launcher cleanup
If you have a separate data container, you’ll need to remove the backup copy like this:
rm -fr /var/discourse/shared/data/postgres_data_old/
FAQ
The source cluster was not shut down cleanly
If you get a upgrade failed with the above message, you can try a simpler approach to get it back into a better state.
Restart the old container with ./launcher start app
. Wait a few minutes until it is back up.
Now shut it down again with ./launcher stop app
. After that tail the logs to see if it was a clean one:
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
If the logs look like above, you can now try to upgrade again using ./launcher rebuild app
.
lc_collate values for database “postgres” do not match
This errors happens if you are using non-default locales for your database. It was reported that you need 3 variables for it to succeed. Ensure that the env:
section of you app.yml file has the 3 lines:
LC_ALL: en_US.UTF-8
LANG: en_US.UTF-8
LANGUAGE: en_US.UTF-8
Changing en_US.UTF-8
to your locale.
Every rebuild does the upgrade again aka upgrade loop
When this happens your upgrade logs will contain
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
This means that there are still files from the last upgrade lingering around. Move those elsewhere before continuing.
Upgrade Complete suggestion scripts - do I need to do anything?
Once the upgrade completes, you’ll see output from the pg_upgrade
message saying:
Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade.
Once you start the new server, consider running:
/usr/lib/postgresql/15/bin/vacuumdb --all --analyze-in-stages
Running this script will delete the old cluster's data files:
./delete_old_cluster.sh
You can safely ignore this message.
I did skip the PostgreSQL 13 update, what to do now?
You can follow the standard instructions at the top of this guide and they will upgrade from your version to 15 without issues.
If you are following the space constrained instructions, adapt the version numbers accordingly.
Rebuilding indexes can give you significant disk space savings. Follow the steps from our PostgreSQL 13 update after the upgrade.