Migrate PostgreSQL from version 17 to 18 (Gentoo Linux)



# The short way (untested)
# I have lerned it the long/hard way! Below, I provide my not so professional way as well in order to find the error messages and its solutions.
# I have decided to write this in English although my PostgreSQL server is installed in German with the corresponding success and error messages. 

As a prerequisite to migrate from PostgreSQL version 17 to version 18, it is necessary to have (or have not) checksums activated.
This approach describes how to activate it for the version to be replaced. There is an alternative approche mentioned below.

To activate checksums on running instance (postgresql-17.7) the following steps are required:

Be root to stop the current server version:

  $ sudo su
  # /etc/init.d/postgresql-17 stop

Switch user to postgres and afterwards via cd to the postgres home directory

  # su postgres   # perform actions as user postgres
  sh-5.3$ cd      # switch to postgres home directory

Enable checksums on version 17

  sh-5.3$ pg_checksums --enable -D /var/lib/postgresql/17/data/
  Prüfsummenoperation abgeschlossen
  Überprüfte Dateien:     1234
  Überprüfte Blöcke:      606060
  Geschriebene Dateien:   1111
  Geschriebene Blöcke:    606050
  pg_checksums: synchronisiere Datenverzeichnis
  pg_checksums: aktualisiere Kontrolldatei
  Prüfsummen wurden im Cluster eingeschaltet

Check checksums via SQL

  # /etc/init.d/postgresql-17 start
   * Caching service dependencies ...    [ ok ]
   * Starting PostgreSQL 17 ...          [ ok ]

  # exit

  $ /usr/bin/psql -U postgres

  SHOW data_checksums;
   data_checksums
  ----------------
   on
  (1 Zeile)

  \q


Stop server to prepare migration to v18

  # /etc/init.d/postgresql-17 stop


Aternative approach: 
As mentioned above, there is an alternative approach to this,
One can disable checksums on new cluster (v18), perform migration (described below) and activate checksums afterwards.


Switch to PostgreSQL version 18

Check the current default PostgreSQL version and set it to the desired one 

  # eselect postgresql list
  Available PostgreSQL Slots
  17 *                      17.7 (Clients Only)
  18                        18.1 (Clients Only)

  # eselect postgresql set 18

Install the required basic configuration for PostgreSQL 18:

  # emerge --config dev-db/postgresql:18

Again, switch user to postgres and afterwards via cd to the users home directory

  # su postgres
  sh-5.3$ cd          # goto postgres home directory
  sh-5.3$ pwd         # /var/lib/postgresql
  

Perform a upgrade/migration check before:

  sh-5.3$ /usr/lib64/postgresql-18/bin/pg_upgrade --check \
          --old-datadir '/var/lib/postgresql/17/data/'  \
          --new-datadir '/var/lib/postgresql/18/data/'  \
          --old-bindir '/usr/lib64/postgresql-17/bin/'  \
          --new-bindir '/usr/lib64/postgresql-18/bin/'

  Führe Konsistenzprüfungen durch
  -------------------------------
  Checking cluster versions                                     ok
  [...]
  *Cluster sind kompatibel*
  *Clusters are compatible*   # English success message

Do the upgrade/migration:

  sh-5.3$ /usr/lib64/postgresql-18/bin/pg_upgrade         \
          --old-datadir '/var/lib/postgresql/17/data/'  \
          --new-datadir '/var/lib/postgresql/18/data/'  \
          --old-bindir '/usr/lib64/postgresql-17/bin/'  \
          --new-bindir '/usr/lib64/postgresql-18/bin/'

  Führe Konsistenzprüfungen durch
  -------------------------------
  Checking cluster versions                                     ok
  [...]
  Führe Upgrade durch
  [...]
  Upgrade abgeschlossen


Final steps are mentioned at the end of the update/migration process:

  sh-5.3$ /usr/lib64/postgresql-18/bin/vacuumdb --all --analyze-in-stages --missing-stats-only
  sh-5.3$ /usr/lib64/postgresql-18/bin/vacuumdb --all --analyze-only

  sh-5.3$ exit

  # rm -rf '/var/lib/postgresql/17/data'  # as root; lack of postgres user permissions in my case


Start the current version of the server

  # sudo /etc/init.d/postgresql-18 start
   * Starting PostgreSQL 18 ...            [ ok ]

Finally, test the migration on database and/or application level!

Sources:
* https://wiki.gentoo.org/wiki/PostgreSQL/QuickStart
* https://www.postgresql.org/docs/current/app-pgchecksums.html
* https://www.postgresql.org/docs/current/pgupgrade.html
* https://www.credativ.de/blog/postgresql/postgresql-18-aktiviert-standardmaessig-daten-checksummen/











































































# the long/hard way
# aka the naive approach (assuming the OS/package maintainer will take care)
# 

sudo eselect postgresql list
sudo /etc/init.d/postgresql-17 stop
sudo eselect postgresql set 18
  sudo /etc/init.d/postgresql-18 status
   * Checking PostgreSQL 18 status ...
  pg_ctl: Verzeichnis »/var/lib/postgresql/18/data« existiert nicht
sudo /etc/init.d/postgresql-18 start
 * Directory not found: /var/lib/postgresql/18/data
 * HINT: Ensure that DATA_DIR points to the right path.
 * HINT: Or perhaps you need to create the database cluster:
 *     emerge --config dev-db/postgresql:18
 * ERROR: postgresql-18 failed to start

# RTFM
https://wiki.gentoo.org/wiki/PostgreSQL/QuickStart#Migrating_PostgreSQL

/usr/lib64/postgresql-18/bin/pg_upgrade --check \
--old-datadir '/var/lib/postgresql/17/data/' \
--new-datadir '/var/lib/postgresql/18/data/' \
--old-bindir '/usr/lib64/postgresql-17/bin/' \
--new-bindir '/usr/lib64/postgresql-18/bin/'

konnte Zugriffsrechte von Verzeichnis »/var/lib/postgresql/18/data« nicht lesen: Keine Berechtigung
Fehlgeschlagen, Programm wird beendet

sudo /usr/lib64/postgresql-18/bin/pg_upgrade ...
pg_upgrade: kann nicht als root ausgeführt werden
Fehlgeschlagen, Programm wird beendet

cat /etc/passwd | grep postg
postgres:x:70:70:PostgreSQL program user:/var/lib/postgresql:/bin/sh

su postgres
/usr/lib64/postgresql-18/bin/pg_upgrade
konnte Zugriffsrechte von Verzeichnis »/var/lib/postgresql/18/data« nicht lesen: Datei oder Verzeichnis nicht gefunden
Fehlgeschlagen, Programm wird beendet

ls -l /var/lib/postgresql/17/
insgesamt 0
drwx------ 1 postgres postgres 512 13. Feb 10:06 data

ls -l /var/lib/postgresql/18
ls: Zugriff auf '/var/lib/postgresql/18' nicht möglich: Datei oder Verzeichnis nicht gefunden

mkdir /var/lib/postgresql/18
mkdir /var/lib/postgresql/18/data

/usr/lib64/postgresql-18/bin/pg_upgrade
Sie müssen Lese- und Schreibzugriff im aktuellen Verzeichnis haben.
Fehlgeschlagen, Programm wird beendet

exit (back to root)
# sudo /etc/init.d/postgresql-18 start
 * /etc/postgresql-18/postgresql.conf not found
 * HINT: mv /var/lib/postgresql/18/data/*.conf /etc/postgresql-18/
 * ERROR: postgresql-18 failed to start

emerge --config dev-db/postgresql:18
Configuring pkg...
[...]
 * The given directory, '/var/lib/postgresql/18/data', is not empty.
 * Modify DATA_DIR to point to an empty directory.
 * ERROR: dev-db/postgresql-18.1::gentoo failed
[...]

# rm -rf /var/lib/postgresql/18
emerge --config dev-db/postgresql:18
 [...]
 * Creating the data directory ...
 * Initializing the database ...
 [...]
Erfolg.

# /etc/init.d/postgresql-18 start
 * Starting PostgreSQL 18 ...                                                                                                                                        [ ok ]
# /etc/init.d/postgresql-18 stop
 * Stopping PostgreSQL 18 (this can take up to 92 seconds) ...


su postgres
sh-5.3$ /usr/lib64/postgresql-18/bin/pg_upgrade --check \
--old-datadir '/var/lib/postgresql/17/data/' \
--new-datadir '/var/lib/postgresql/18/data/' \
--old-bindir '/usr/lib64/postgresql-17/bin/' \
--new-bindir '/usr/lib64/postgresql-18/bin/'

Sie müssen Lese- und Schreibzugriff im aktuellen Verzeichnis haben.
Fehlgeschlagen, Programm wird beendet

# compared
# /etc/conf.d/postgresql-17 and /etc/conf.d/postgresql-18
# /etc/postgresql-17/pg_hba.conf and /etc/postgresql-18/pg_hba.conf

# checked permissions
/var/lib/postgresql/17/ compared to /var/lib/postgresql/18/
/var/lib/postgresql/17/data/ compared to /var/lib/postgresql/18/data/

# su postgres

/usr/lib64/postgresql-18/bin/pg_upgrade --check --old-datadir '/var/lib/postgresql/17/data/' --new-datadir '/var/lib/postgresql/18/data/' --old-bindir '/usr/lib64/postgresql-17/bin/' --new-bindir '/usr/lib64/postgresql-18/bin/'

Sie müssen Lese- und Schreibzugriff im aktuellen Verzeichnis haben.
Fehlgeschlagen, Programm wird beendet

sh-5.3$ cd # goto postgres home directory
sh-5.3$ pwd
/var/lib/postgresql

sh-5.3$ /usr/lib64/postgresql-18/bin/pg_upgrade --check --old-datadir '/var/lib/postgresql/17/data/' --new-datadir '/var/lib/postgresql/18/data/' --old-bindir '/usr/lib64/postgresql-17/bin/' --new-bindir '/usr/lib64/postgresql-18/bin/'
Führe Konsistenzprüfungen durch
-------------------------------
Checking cluster versions                                     ok

der alte Cluster verwendet keine Datenprüfsummen, aber der neue verwendet sie
Fehlgeschlagen, Programm wird beendet

# RTFM again (regarding checksums)
# There is a troubleshooting section on the gentoo page below
# v18 has checksums activated by default - v17 not - but it has to match

# check and grep config files for it (assumed it is configured in a file)
vi /etc/postgresql-17/postgresql.conf
vi /etc/postgresql-17/pg_hba.conf
grep initdb /etc/postgresql-18/*
/etc/postgresql-18/postgresql.conf:# These settings are initialized by initdb, but they can be changed.
grep dataChecksums /etc/postgresql-18/*
grep -ir dataChecksums /etc/*


pg_checksums --help
Wenn kein Datenverzeichnis angegeben ist, wird die Umgebungsvariable
PGDATA verwendet.

sh-5.3$ echo $PGDATA

sh-5.3$ pg_checksums -c /var/lib/postgresql/17/data
pg_checksums: Fehler: CRC-Wert in pg_control ist falsch
sh-5.3$ pg_checksums --enable -D /var/lib/postgresql/17/data
pg_checksums: Fehler: CRC-Wert in pg_control ist falsch
sh-5.3$ pg_checksums --enable -D /var/lib/postgresql/17
pg_checksums: Fehler: konnte Datei »/var/lib/postgresql/17/global/pg_control« nicht zum Lesen öffnen: Datei oder Verzeichnis nicht gefunden
exit

# eselect postgresql list
  17                        17.7 (Clients Only)
  18 *                      18.1 (Clients Only)

# eselect postgresql set 17
Unsetting 18 as default...find: ‘/usr/include/pg_config_ext.h’: Datei oder Verzeichnis nicht gefunden
done.
Setting 17 as the default...success!

su postgres
sh-5.3$ pg_checksums --enable
pg_checksums: Fehler: kein Datenverzeichnis angegeben
pg_checksums: Tipp: Versuchen Sie »pg_checksums --help« für weitere Informationen.
sh-5.3$ pg_checksums --enable -D /var/lib/postgresql/17/data/
Prüfsummenoperation abgeschlossen
Überprüfte Dateien:     1234
Überprüfte Blöcke:      606060
Geschriebene Dateien:   1111
Geschriebene Blöcke:    606050
pg_checksums: synchronisiere Datenverzeichnis
pg_checksums: aktualisiere Kontrolldatei
Prüfsummen wurden im Cluster eingeschaltet

# /etc/init.d/postgresql-17 start
 * Caching service dependencies ...                                                                                                                                  [ ok ]
 * Starting PostgreSQL 17 ...                                                                                                                                        [ ok ]
exit
$ /usr/bin/psql -U postgres
SHOW data_checksums;
 data_checksums
----------------
 on
(1 Zeile)

\q

# /etc/init.d/postgresql-17 stop
 * Stopping PostgreSQL 17 (this can take up to 92 seconds) ...                                                                                                       [ ok ]

# eselect postgresql set 18
# su postgres
sh-5.3$ cd
sh-5.3$ /usr/lib64/postgresql-18/bin/pg_upgrade --check --old-datadir '/var/lib/postgresql/17/data/' --new-datadir '/var/lib/postgresql/18/data/' --old-bindir '/usr/lib64/postgresql-17/bin/' --new-bindir '/usr/lib64/postgresql-18/bin/'
Führe Konsistenzprüfungen durch
-------------------------------
Checking cluster versions                                     ok
[...]
*Cluster sind kompatibel*


/usr/lib64/postgresql-18/bin/pg_upgrade --old-datadir '/var/lib/postgresql/17/data/' --new-datadir '/var/lib/postgresql/18/data/' --old-bindir '/usr/lib64/postgresql-17/bin/' --new-bindir '/usr/lib64/postgresql-18/bin/'
Führe Konsistenzprüfungen durch
-------------------------------
Checking cluster versions                                     ok
[...]
Führe Upgrade durch
[...]
Upgrade abgeschlossen


sh-5.3$ /usr/lib64/postgresql-18/bin/vacuumdb --all --analyze-in-stages --missing-stats-only
sh-5.3$ /usr/lib64/postgresql-18/bin/vacuumdb --all --analyze-only

sh-5.3$ ./delete_old_cluster.sh
rm: das Entfernen von '/var/lib/postgresql/17/data' ist nicht möglich: Keine Berechtigung
sh-5.3$ exit

sudo /etc/init.d/postgresql-18 start
 * Starting PostgreSQL 18 ...




by Markus Sesser