We all know that PostgreSQL 10 has reached end of support, so if you’re still running it, the time to upgrade is now. Staying on an unsupported version means no more security fixes or bug patches, which puts your applications and data at risk.

There are a few different upgrade paths to consider. For example, you can use pg_dump/pg_restore, or go with a logical replication approach as shown in Replication Between PostgreSQL Versions Using Logical Replication.

In this post, we’ll walk through an example upgrade from PostgreSQL 10 to PostgreSQL 13 using the native pg_upgrade utility, including how to handle tables with OID columns and installed extensions along the way.

We have PostgreSQL 10 running with the below list of extensions and some tables with OID columns:

What is OID?

Object identifiers (OIDs) are used internally by PostgreSQL as primary keys for various system tables. Type OID represents an object identifier.

If we have tables with OID created, then the pg_upgrade check will fail with the below error FATAL message:

We can use the below SQL to find tables with OID, and it also generates the DDL to remove.

Connect to each database in the cluster and run the above SQL query:

Now we can execute the DDL to ALTER these tables.

Once ALTER is completed, we can perform once again pg_upgrade checks:

It shows an error related to PostGIS Extension; hence we need to download the PostGIS package for PostgreSQL-13.

Re-run the pg_upgrade checks:

Now we will perform the actual upgrade as shown below:

Start the Target DB cluster:

Connect to DB and run the UPDATE Extension SQL command:

Now we can perform vacuum analyze to update all statistics:

Note: In case we want to retain OID post upgrade, then we need to follow a couple of steps:

Before the upgrade, on the source database:

After the upgrade, on the target database:

Conclusion

Upgrading PostgreSQL can feel straightforward until you run into details like OID columns, extension compatibility, or missing libraries. As this example shows, even a direct pg_upgrade requires careful preparation and post-upgrade adjustments.

That’s why the bigger challenge isn’t just performing one upgrade; it’s managing PostgreSQL at scale over time. Every upgrade, patch, and configuration change takes focus away from other priorities.

If you’re starting to feel the weight of managing PostgreSQL in-house, you’re not alone. Take a look at our guide, PostgreSQL in the Enterprise: The Real Cost of Going DIY, to understand why running PostgreSQL internally demands more time, expertise, and resources than most teams expect—and what it means for IT and the business.

PostgreSQL in the Enterprise: The Real Cost of Going DIY

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
imran

Thanks for the post. Why didn’t you use –link option prior to upgrade?