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