You are currently viewing PostgreSQL Update to Version.16, Major Upgrade Including Data Migration

PostgreSQL Update to Version.16, Major Upgrade Including Data Migration

PostgreSQL Step-by-Step Guide for Updating to Version 16 with Full Data Migration. Currently the recommended version.

Notes:

In this example, we are using “Immich Foto” as the container name; you must adapt the container name and the database container to your environment.

All commands in this guide are optimized for the Windows Command Prompt (CMD).

Before updating, verify that PostgreSQL version 16 is compatible with your application.


🎯 What to expect

This upgrade moves your PostgreSQL database from version 14 to the recommended version 16. In addition to the version upgrade, the vector extension is also being updated from pgvecto.rs to VectorChord – the current PostgreSQL standard method with significant performance improvements for vector operations.

The process uses logical backup and restore (pg_dumpall / psql), which is the safest method for major upgrades.

Special features of this guide:

  • Explanation of the critical shm_size setting for PostgreSQL 16
  • Why POSTGRES_INITDB_ARGS: '--data-checksums' protects your data
  • Troubleshooting for common issues

📋 Prerequisites

  • Running PostgreSQL installation with Docker Compose
  • Sufficient free disk space (at least size of current database + 20%)
  • Access to the Docker host console

Video: PostgreSQL Update to Version.16, Major Upgrade Including Data Migration

Language: 🇩🇪|🇬🇧
☝️ Use YouTube subtitles for all languages.

🔧 Step 1: Prepare the Docker Compose file

Open your docker-compose.yml and replace the existing PostgreSQL service:

OLD Service (PostgreSQL 14 with pgvecto.rs):

yaml

db:
  image: postgres:14
  environment:
    POSTGRES_PASSWORD: ${DB_PASSWORD}
    POSTGRES_USER: ${DB_USERNAME}
    POSTGRES_DB: ${DB_DATABASE_NAME}
  volumes:
    - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
  restart: always

NEW Service (PostgreSQL 16 with VectorChord):

yaml

db:
  image: postgres:16
  environment:
    POSTGRES_PASSWORD: ${DB_PASSWORD}
    POSTGRES_USER: ${DB_USERNAME}
    POSTGRES_DB: ${DB_DATABASE_NAME}
    POSTGRES_INITDB_ARGS: '--data-checksums'
  volumes:
    - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
  restart: always
  shm_size: 128mb

Save the file.


🛑 Step 2: Stop dependent services

Stop all services that access the database:

cmd

docker compose stop immich-server immich-machine-learning redis

Adjust the service names to match your environment.


💾 Step 3: Create a database backup

Create a complete backup:

cmd

docker exec immich_postgres pg_dumpall -c -U postgres > immich_backup.sql

Check if the backup was successful:

cmd

dir immich_backup.sql

The file should have a reasonable size (not 0 bytes).


🗑️ Step 4: Remove the old database container

cmd

docker compose down db

The old container is deleted, but your data in the volume remains.


🚨 Step 5: Clear the database volume (critical!)

The new PostgreSQL 16 container cannot start with old PostgreSQL 14 data. You must clear the volume:

First, check where your data is located:

cmd

type .env | findstr DB_DATA_LOCATION

Depending on the path type:

Case 1 – Relative path (starts with . or ./):

cmd

rmdir /s /q postgres

Case 2 – Absolute path (e.g., D:\DockerData\postgres):

cmd

rmdir /s /q D:\DockerData\postgres

Case 3 – Docker volume:

cmd

docker volume ls
docker volume rm INSERT_VOLUME_NAME_HERE

⚠️ Warning: This step deletes the old PostgreSQL 14 data. Make sure your backup from Step 3 exists!

🚀 Step 6: Start the new PostgreSQL 16 container

cmd

docker compose up -d db

The container now initializes an empty database cluster with PostgreSQL 16 and VectorChord, including:

  • Data Checksums (via --data-checksums)
  • Increased Shared Memory (via shm_size: 128mb)

Check if the container is running:

cmd

docker ps | findstr postgres

The output should show the container with status Up.

If there are problems, check the container logs:

cmd

docker logs immich_postgres --tail 50

📥 Step 7: Import the backup into the new database

cmd

docker exec -i immich_postgres psql -U postgres < immich_backup.sql

This process may take several minutes depending on the database size. Do not interrupt!

Note: For very large databases, the import may take an hour or longer – this is normal.


🔄 Step 8: Restart all services

cmd

docker compose up -d

✅ Step 9: Verify success

Check the PostgreSQL version:

cmd

docker exec immich_postgres psql -U postgres -c "SHOW server_version;"

Expected output: 16.x (not 14.x)

Check if checksums are enabled:

cmd

docker exec immich_postgres psql -U postgres -c "SELECT datname, datchecksum FROM pg_database;"

Check the logs for errors:

cmd

docker compose logs --tail 50

❓ The two important special questions – explained

1. Why shm_size: 128mb?

Shared Memory (/dev/shm) is a temporary memory area that PostgreSQL uses for parallel queries and vector operations.

The problem: Docker only allocates 64 MB by default – too little for PostgreSQL 16.

The consequences without this setting:

text

ERROR: could not resize shared memory segment
FATAL: could not create shared memory segment

The solution: With shm_size: 128mb you get sufficient shared memory. For very large databases (>50,000 entries), 256 MB or 512 MB are recommended.

2. What does POSTGRES_INITDB_ARGS: '--data-checksums' do?

This enables checksums for every data page in PostgreSQL.

Advantages:

  • Detection of silent data corruption (defective hard drives, bitrot, RAM errors)
  • Early warning system instead of unnoticed incorrect data
  • Enables targeted recovery from backups

The cost: Only 2-3% performance overhead – perfectly acceptable for most applications.

Important: This only takes effect during the initial database initialization – exactly what happens during this upgrade.


🚨 Troubleshooting

Error: “Container is restarting”

Cause: The container cannot start, usually due to incompatible old data.

Solution:

  1. Stop container: docker compose down db
  2. Clear volume (see Step 5)
  3. Restart container: docker compose up -d db
  4. Re-import backup

Error: “psql: could not connect to server”

Cause: The PostgreSQL server is not running.

Solution:

cmd

docker ps -a | findstr postgres
docker logs immich_postgres --tail 50

The logs will show the exact cause.

Error: “permission denied” during import

Cause: Permission issues inside the container.

Solution:

cmd

docker exec -i immich_postgres psql -U postgres -f - < immich_backup.sql

📊 After the upgrade

Recommended actions:

  1. Keep the backup – only delete immich_backup.sql after successful operation
  2. Monitor performance – indexes will be rebuilt during the first few hours
  3. Set up regular backups – now take advantage of the checksums

🎓 Conclusion

The major upgrade from PostgreSQL 14 to 16 is safe and clean with this procedure. The combination of:

  • Logical backup (pg_dumpall)
  • Cleaned database volume
  • Migration from pgvecto.rs to VectorChord
  • Additional optimizations (shm_sizedata-checksums)

makes your database future-proof and more robust against data corruption.

Important note: After this upgrade, you cannot simply return to the old container – the database structure is not backward compatible. A rollback would only be possible by restoring the old backup on a PostgreSQL 14 container.


Donate Bild

Support / Donation Link for the Channel
If my posts have been helpful or supported you in any way, I’d truly appreciate your support 🙏

PayPal Link
Bank transfer, Bitcoin and Lightning


#PostgreSQL16 #PostgreSQLUpdate #MajorUpgrade #DatabaseMigration #DockerPostgreSQL #VectorChord #pgvectors

Leave a Reply