- Develop a playbook and tests on a similar PostgreSQL environment (created using a back-up from staging) for these tests.
- Create an image of staging in your cloud provider.
- Initialise a new VM/Docker/? based on this image. (use a backup from staging to get the upgrade project in contact with the environment)
- Run the pertinent commands to develop a migration note/script.
- Iterate and test the integration craft a set of end-to-end tests. Validate the crafted end-to-end tests in staging.
- Execute a snapshot from the database disk that could be used in a restore scenario.
- Execute any pre-checks for the project.
- Stop the traffic and applications that access the database.
- Do not receive traffic.
- Stop the proxy.
- Stop the middleware.
- Execute the migration (note/script) to carry out the PostgreSQL upgrade.
- Verify the integrity and status of the database. Execute the end-to-end tests.
- Start the applications connected to the DB and execute tests suites. Execute local unit tests on the upgraded database.
- Stop the cluster with PostgreSQL 14.
- Restore the configuration to PostgreSQL 10.
- Initialize the database in version 10.
- Start receiving traffic
The next commands were executed in an Ubuntu 18.04.4 LTS.
First create a backup of all the databases for that (You can continue from B if you dont need a backup)
- Log in as postgres user
sudo su postgres
- Create a backup .sql file for all the data you have in all the databases
pg_dumpall > backup.sql
-
Download ca-certificates
sudo apt update sudo apt-get install wget ca-certificates
-
Add the GPG key and PostgreSQL repository
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'
-
Update apt and get latest postgres version
sudo apt update sudo apt -y install postgresql=14\* postgresql-client=14\* postgresql-contrib=14\*
-
(Optional) Check installed versions
dpkg -l 'postgres*' | grep ^i
-
(Option 1: Manual)
-
Stop postgreSQL
sudo systemctl stop postgresql.service
-
Make sure you are logged in as postgres user
sudo su postgres
-
And you are running the next commands from a directory that is writable by the postgres user like
/var/lib/postgresql
cd /var/lib/postgresql && ls # output: 10 14 pg_lsclusters # Ver Cluster Port Status Owner Data directory Log file # 10 main 5433 down,binaries_missing postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log # 14 main 5432 online postgres /var/lib/postgresql/14/main /var/log/postgresql/postgresql-14-main.log
-
Run
[pg_upgrade](https://www.postgresql.org/docs/14/pgupgrade.html)
to migrate the data/usr/lib/postgresql/14/bin/pg_upgrade \ --old-datadir=/var/lib/postgresql/10/main \ --new-datadir=/var/lib/postgresql/14/main \ --old-bindir=/usr/lib/postgresql/10/bin \ --new-bindir=/usr/lib/postgresql/14/bin \ --old-options '-c config_file=/etc/postgresql/10/main/postgresql.conf' \ --new-options '-c config_file=/etc/postgresql/14/main/postgresql.conf'
-
Edit
pg_hba.conf
and change peer to trust to allow incoming connectionssudo vim /etc/postgresql/14/main/pg_hba.conf # change 'peer' to 'trust' for all/all for both host and local / 127.0.0.1/32
-
Example file result
# TYPE DATABASE USER ADDRESS METHOD # Database administrative login by Unix domain socket local all postgres trust # peer -> trust # "local" is for Unix domain socket connections only local all all trust # peer -> trust # IPv4 local connections: host all all 127.0.0.1/32 trust # scram-sha-256 -> trust # IPv6 local connections: host all all ::1/128 trust # scram-sha-256 -> trust # Allow replication connections from localhost, by a user with the # replication privilege. local replication all peer host replication all 127.0.0.1/32 scram-sha-256 host replication all ::1/128 scram-sha-256
-
-
Update anything required by the
pg_upgrade
command (likeupdate_extensions.sql
)Note: When upgrading, the executable outputted:
Your installation contains extensions that should be updated with the ALTER EXTENSION command. The file update_extensions.sql, when executed by psql by the database superuser will update these extensions.
Now is the time to do so. π
-
Switch to regular user
exit
-
Swap the ports and delete the old version.
sudo vim /etc/postgresql/14/main/postgresql.conf # change port to 5432 sudo vim /etc/postgresql/10/main/postgresql.conf # change port to 5433
-
-
(Option 2: Automatic. Use at your own risk π΅βπ«)
-
Delete the PostgreSQL brand new cluster to migrate the old one instead
sudo pg_dropcluster 14 main --stop # Docs: http://manpages.ubuntu.com/manpages/trusty/man8/pg_dropcluster.8.html
-
Upgrade / Migrate
sudo pg_upgradecluster -v 14 10 main # Docs: http://manpages.ubuntu.com/manpages/trusty/man8/pg_upgradecluster.8.html # pg_upgradecluster [-v newversion] oldversion name [newdatadir]
-
- Start the postgresql service
sudo systemctl restart postgresql.service
- Log in as postgres user
sudo su postgres
- Check your new postgres version
psql -c "SELECT version();"
A.k.a cleanup up the old version's mess (manual version of pg_dropcluster
stated in 5.b
)
-
(Option 1: Manual)
-
Return as a normal(default user)
exit
-
Uninstall postgres packages if present
dpkg -l 'postgres*' | grep ^i
sudo apt-get remove postgresql-10 postgresql-client-10
-
Remove the old postgresql directory if present
sudo rm -rf /etc/postgresql/10/
-
Login as postgres user
sudo su postgres
-
Go inside psql folder and remove old data (
/var/lib/postgresql
)sudo rm -rf '/var/lib/postgresql/10/main' # by the time this guide was written: equivalent to ./delete_old_cluster.sh rmdir 10 # remove folder 10 if empty sudo rm delete_old_cluster.sh # remove script file, equivalent to the first line of this snippet and not useful anymore
-
-
(Option 2: Automatic. Use at your own risk π΅βπ«)
sudo pg_dropcluster 10 main --stop
Note: If everything works well in 2-3, we dont have to apply the backup as we have already migrated the data from the older version to the newer version, the backup is just in case anything goes wrong.