DEV Community

nabbisen
nabbisen

Posted on • Originally published at obsd.solutions

PostgreSQL on OpenBSD: Upgrade 16 to 17 with pg_upgrade

Summary

OpenBSD gives us good documentation as a series of the project. (For example, the man pages are cared and kept maintained.) It's applied to principal service packages as well as the OS. So is as to PostgreSQL.

Well, according to their pkg-readme on PostgreSQL (/usr/local/share/doc/pkg-readmes/postgresql-server), they suggest we have two ways to upgrade the database:

  1. pg_upgrade
  2. pg_dumpall

The former is faster and suitable for big databases, although installation on the additional ports package is required. The latter is vice versa. This post is about the former.

Environment

  • OS: OpenBSD 7.7 (upgraded from 7.6)
  • DB: PostgreSQL 17 (upgraded from 16)

Tutorial

Backup (Optional)

When you worry about backup, pg_dumpall is available:

$ pg_dumpall -U postgres > pg.sqldump 
Enter fullscreen mode Exit fullscreen mode

You may be asked by the superuser's password at the number of the existing databases. The result was:

$ ls -lh pg.sqldump -rw-r--r-- 1 myuser myuser 28.2M Apr 28 07:26 pg.sqldump 
Enter fullscreen mode Exit fullscreen mode

OS upgrade (optional)

It is up to the situation around why upgrading PostgreSQL 16 to 17 is required.

The situation of this post is to upgrade OpenBSD 7.6 to 7.7 which requires it.
It is supposed running sysupgrade, sysmerge, syspatch and pkg_add -u are done. }}index.html">This post might be useful.

Here, running pkg_add -u asked like below:

$ pkg_add -u (...) postgresql-client-16.8->17.4 forward dependencies: | Dependency of postgresql-server-16.8 on postgresql-client-=16.8 doesn't match | Dependency of postgresql-contrib-16.8 on postgresql-client-=16.8 doesn't match Merging postgresql-server-16.8->17.4 (ok) Merging postgresql-contrib-16.8->17.4 (ok) postgresql-server-17.4: Updating across a major version - data migration needed, see the pkg-readme. Do you want to update now ? [y/N/a] y 
Enter fullscreen mode Exit fullscreen mode

Enter "y" as above. The result was below:

postgresql-client+postgresql-contrib+postgresql-server-16.8->17.4: ok .libs1-postgresql-previous-13.5p0+.libs1-postgresql-previous-14.6p0+postgresql-previous-15.4p0->post.libs1-postgresql-previous-13.5p0+.libs1-postgresql-previous-14.6p0+postgresql-previous-15.4p0->post (...) New and changed readme(s): /usr/local/share/doc/pkg-readmes/postgresql-server 
Enter fullscreen mode Exit fullscreen mode

Install pg_upgrade

The Ports package system helps:

$ doas pkg_add postgresql-pg_upgrade quirks-7.103 signed on 2025-04-23T19:09:39Z postgresql-pg_upgrade-17.4: ok 
Enter fullscreen mode Exit fullscreen mode

Stop the daemon

Stopping the server:

$ doas rcctl stop postgresql postgresql(ok) 
Enter fullscreen mode Exit fullscreen mode

Now we are ready. Let's upgrade the database !!

Create cluster of upgraded PostgreSQL

Prepare for creating the data directory.
Move the current:

$ doas mv /var/postgresql/data /var/postgresql/data-16 
Enter fullscreen mode Exit fullscreen mode

Then mkdir it and initdb for PostgreSQL:

$ # doas su _postgresql -c "mkdir /var/postgresql/data && cd /var/postgresql && \  initdb -D /var/postgresql/data -U postgres -A scram-sha-256 -E UTF8 -W" $ doas su _postgresql -c "mkdir /var/postgresql/data && cd /var/postgresql && \  initdb -D /var/postgresql/data -U postgres -A scram-sha-256 -E UTF8 --locale=ja_JP.UTF-8 -W" 
Enter fullscreen mode Exit fullscreen mode

The former above is due to the pkg-readme, and the latter is specific for my case, in which --locale=(...) option is added.

The result was:

The files belonging to this database system will be owned by user "_postgresql". This user must also own the server process. The database cluster will be initialized with locale "ja_JP.UTF-8". initdb: could not find suitable text search configuration for locale "ja_JP.UTF-8" The default text search configuration will be set to "simple". Data page checksums are disabled. Enter new superuser password: Enter it again: 
Enter fullscreen mode Exit fullscreen mode

Enter the password of your PostgreSQL superuser twice. Then it will be followed by the below:

fixing permissions on existing directory /var/postgresql/data ... ok creating subdirectories ... ok selecting dynamic shared memory implementation ... posix selecting default "max_connections" ... 25 selecting default "shared_buffers" ... 128MB selecting default time zone ... Asia/Tokyo creating configuration files ... ok running bootstrap script ... ok performing post-bootstrap initialization ... ok syncing data to disk ... ok Success. You can now start the database server using: rcctl start postgresql To start the PostgreSQL server automatically at boot: rcctl enable postgresql 
Enter fullscreen mode Exit fullscreen mode

The database has been successfully initialized.

Configure for migration

The steps here are temporary for the data migration.

Edit pg_hba.conf of the current (and also the next):

$ doas nvim /var/postgresql/data-16/pg_hba.conf 
Enter fullscreen mode Exit fullscreen mode

in order to allow local connection by the superuser:

 # TYPE DATABASE USER ADDRESS METHOD + local all postgres trust 
Enter fullscreen mode Exit fullscreen mode

Note that you should put the line at the top in order to let it be the most highly prioritized.

Then copy the files below to the data directory, which includes pg_hba.conf. They are used by the upgraded software:

$ doas cp -p /var/postgresql/data-16/pg_hba.conf /var/postgresql/data/  $ # in addition, in case that tls is used: $ doas cp -p /var/postgresql/data-16/server.{crt,key} /var/postgresql/data/ 
Enter fullscreen mode Exit fullscreen mode

Besides, there is caution as below in the pkg-readme (/usr/local/share/doc/pkg-readmes/postgresql-server):

Some postgresql.conf settings changed or disappeared in this version.
Examine your old file for local changes and apply them to the new version (/var/postgresql/data/postgresql.conf). The following command may help identify them:

# diff -wu /usr/local/share/postgresql-16/postgresql.conf.sample \  /var/postgresql/data-16/postgresql.conf 

Run pg_upgrade

Your database is now waiting for the upgrade. Run the command lines:

$ doas su _postgresql -c "cd /var/postgresql && \  pg_upgrade -b /usr/local/bin/postgresql-16/ -B /usr/local/bin \ -U postgres -d /var/postgresql/data-16/ -D /var/postgresql/data" 
Enter fullscreen mode Exit fullscreen mode

Well, if you meet the error saying "connection to server on socket "/var/postgresql/.s.PGSQL.(...)" failed: fe_sendauth: no password supplied", either .pgpass or PGPASSWORD environment variable might be helpful:

$ # alternatively, in case to pass password with temporary environment variable: $ # doas su _postgresql -c "cd /var/postgresql && \  env PGPASSWORD='your-password' pg_upgrade -b /usr/local/bin/postgresql-16/ -B /usr/local/bin \ -U postgres -d /var/postgresql/data-16/ -D /var/postgresql/data" 
Enter fullscreen mode Exit fullscreen mode

The result was below:

Performing Consistency Checks ----------------------------- Checking cluster versions ok Checking database user is the install user ok Checking database connection settings ok Checking for prepared transactions ok Checking for contrib/isn with bigint-passing mismatch ok Checking data type usage 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 If pg_upgrade fails after this point, you must re-initdb the new cluster before continuing. Performing Upgrade ------------------ Setting locale and encoding for new cluster ok 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 oldest XID for new cluster 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 Copying user relation files ok Setting next OID for new cluster ok Sync data directory to disk ok Creating script to delete old cluster ok Checking for extension updates ok Upgrade Complete ---------------- Optimizer statistics are not transferred by pg_upgrade. Once you start the new server, consider running: /usr/local/bin/vacuumdb -U postgres --all --analyze-in-stages Running this script will delete the old cluster's data files: ./delete_old_cluster.sh 
Enter fullscreen mode Exit fullscreen mode

Successful.

Restore configuration

Restore the configuration by removing the temporary line:

$ doas nvim /var/postgresql/data/pg_hba.conf  $ # in addition, if you care about restoring the previous one: $ doas nvim /var/postgresql/data-16/pg_hba.conf 
Enter fullscreen mode Exit fullscreen mode

like below:

 # TYPE DATABASE USER ADDRESS METHOD - local all postgres trust 
Enter fullscreen mode Exit fullscreen mode

Configure for the new PostgreSQL (Optional)

When you have specific configuration with postgresql.conf etc., apply them:

$ # create the backup (optional): $ doas cp -p /var/postgresql/data/postgresql.conf /var/postgresql/data/postgresql.conf.org  $ doas nvim /var/postgresql/data/postgresql.conf 
Enter fullscreen mode Exit fullscreen mode

like below (for example):

 (...) + listen_addresses = '*'  (...) + ssl = on  (...) 
Enter fullscreen mode Exit fullscreen mode

Besides, the original of postgresql.conf is placed as /usr/local/share/postgresql/postgresql.conf.sample.

Start the daemon again

All on the upgrade have been done. Let's start the database server:

$ doas rcctl start postgresql 
Enter fullscreen mode Exit fullscreen mode

I hope the result is successful :)

Remove the package (Optional)

You are now free to farewell with appreciation to the package which worked fine:

$ doas pkg_delete postgresql-pg_upgrade postgresql-pg_upgrade-17.4: ok 
Enter fullscreen mode Exit fullscreen mode

Conclusion

Through the steps above, we can upgrade PostgreSQL 16 to 17 with upgrading OpenBSD 7.6 to 7.7.

Besides, the data-16 directory may become "old" one in some future.

Wish you pretty happy time with the latest PostgreSQL on the latest OpenBSD 🌟

Top comments (0)