Hi Noonari.
I was working on everything-personal project. I ran into a hiccup when I ran the `uv run manage.py migrate`. I was on `django 6.1.2`. And it turns out that from Django version 6.1 onwards, django will not be supporting postgres 14.XX or below along with any mysql below mysql 8.4.
I had two options. One take a step back to django version 5.2LTS or stay on the current version and take on the challenge of upgrading the postgres version. Ofcourse, I lack foresight, I chose later. I added another challenge to this. I will not use AI to do this. Claude could have helped me do all this without a hiccup and I would have been done and dusted in like less than 30 minutes. But it is me. You know me. How I was. So Here is it.
I started from postgres official documentation. Why you ask? I did that because, every tom dick and harry of a search engine website has added AI explanation/Summary. I learnt about pg_upgrade. Here is what the docs taught me. pg_upgrade upgrades a cluster in place. It needs the old Postgres and the new Postgres installed side by side, and it moves your data files from one to the other. Powerful, but a bit raw. You have to point it at both binary folders, both data directories and both configs, and one wrong path is a bad afternoon.
Then I found out Ubuntu ships a friendlier wrapper called pg_upgradecluster. It figures out all the paths for you. By default it does a dump and restore into the new cluster, which is slower than pg_upgrade on huge databases but perfectly fine for my 39 MB of personal projects. If you want the real pg_upgrade behind it, there is a --method=upgrade flag. Good to know for later.
Now the actual work.
- Look around first.
pg_lsclustersA cluster is one running Postgres server with its own port and data folder. I had 14 on port 5432. Remember this, you will need it.
- Backup. Before anything else. The docs repeat this like a broken record, so I listened.
cd /tmp && sudo -u postgres pg_dumpall > ~/pg14_backup.sqlThe cd /tmp is there because the postgres user cannot enter my home folder and complains about it. The complaint is harmless.
- Check the backup is real.
ls -lh ~/pg14_backup.sql
grep -c "^CREATE DATABASE" ~/pg14_backup.sql
tail -n 3 ~/pg14_backup.sql39 MB, 12 databases, and the last line said PostgreSQL database cluster dump complete. Good.
- Add the official PostgreSQL repo and install 18. Ubuntu’s own repo lags behind.
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install -y postgresql-18
pg_lsclustersSurprise. The installer quietly created an empty 18 main cluster on port 5433 because 14 was already on 5432. I also found a forgotten empty 16 main cluster hiding on 5434. Always run pg_lsclusters before you trust your memory.
- Get rid of the empty 18 cluster so the upgrade can use the name
main.
sudo pg_dropcluster 18 main --stop- The upgrade itself. One command.
sudo pg_upgradecluster -v 18 14 mainIt builds a fresh 18 cluster, copies every database and user over, gives it port 5432, and parks the old 14 on another port, switched off. My Django settings did not need a single change.
- Verify. Do not skip this.
pg_lsclusters
sudo -u postgres psql -c "SELECT version();"
sudo -u postgres psql -l
uv run manage.py migratePostgreSQL 18.6, all my databases listed, and migrate ran with no version error. That was the moment.
- Clean up, but only after step 7 passes.
sudo pg_dropcluster 14 main
sudo apt remove -y postgresql-14I kept the backup file anyway. It costs nothing.
Two things that scared me for no reason:
collation version mismatchwarnings showed up on the old clusters. Ubuntu updated its system libraries after those clusters were created. The upgrade builds the new cluster against the current libraries, so it does not carry over.- apt suggested
apt autoremove, and the list had ffmpeg and ImageMagick libraries in it. Nothing to do with Postgres. I removed only the oldpostgresql-client-xxpackages by hand.
What I took away from it: the “scary” upgrade was really three ideas. A cluster is just a server with a port. A backup you have checked is the reason you can stay calm. And the old cluster stays on disk until you decide to delete it, so there is a way back until the very last step.
With this today’s lecture ends. Remember Noonari, the docs are slower than a chatbot, but they stick. Stay sharp and stay hungry.