Loading Now

Faster, Safer Version Upgrades for Databases with Large Objects

By Varun Dhawan, Ilan Benschikovski, and Alexander Kukushkin – Azure PostgreSQL, Microsoft

TL;DR: We’ve enhanced major version upgrades for PostgreSQL databases with a significant number of large objects. Upgrades targeting PostgreSQL 15 and above now manage large-object metadata more efficiently, easing memory and temporary space demands and ensuring smoother upgrades.

Some PostgreSQL applications store documents, images, PDFs, and other files as large objects (LOBs). While this works well under normal conditions, a high number of LOBs can slow down, complicate, or even lead to failures during a major version upgrade.

This update is designed to make upgrades safer and more predictable for users of Azure Database for PostgreSQL flexible server.

When performing a major version upgrade, PostgreSQL employs pg_upgrade, which internally uses pg_dump to transfer schema and metadata to the new version.

With databases containing millions of LOBs, the previous upgrade method processed large-object metadata one piece at a time, causing excessive memory and temporary space usage during the schema dump.

This update alters that upgrade procedure. Rather than processing large-object metadata individually, PostgreSQL can now transfer it in bulk. This enhancement solely affects how metadata is handled, not the actual large-object data.

This enhancement builds on advancements made in upstream PostgreSQL, optimising how large-object metadata is managed during upgrades. We’ve incorporated these benefits into Azure Database for PostgreSQL flexible server for any upgrades to PostgreSQL 15 and higher, so users with large-object-heavy workloads can take advantage without delay.

AreaBeforeAfter
Metadata HandlingOne operation per large objectBulk metadata transfer
Memory/temp pressureHeavily increased with LOB countMuch more stable and predictable
High LOB countsRisk of OOM or temp space failureMore reliable completion for PostgreSQL 15+ targets
Customer workaroundvacuumlo + frequent scaling requiredReduced need for LOB-specific workarounds on PostgreSQL 15+ targets

In simpler terms: the upgrade process doesn’t need to handle each large object individually anymore. Instead, the metadata transfers in bulk, making the upgrade quicker, safer, and less prone to failure with high LOB counts.

We conducted tests upgrading from PostgreSQL 13, with large-object counts between 10 million to 500 million. The outdated method is illustrated as PostgreSQL 13 → 14, while the improved method is represented by PostgreSQL 13 → 15.

Note: These results were based on testing across multiple databases with large objects distributed over 100 databases. Since pg_dump operates per database, single-database scenarios with the same total LOB count may yield different execution times.

Cap



Illustration: A bar chart showcasing the time taken for major version upgrades with the older and improved large-object methods. Time decreases significantly at higher LOB counts.



Illustration: A bar chart that highlights how the improved pathway is significantly faster at various large-object counts.

Large ObjectsOlder PathImproved PathWhat Changed
10M48 min16 min3x faster
20M1h 02m18 min3.4x faster
30M2h 41m21 min7.6x faster
50MPreviously failed26-30 minNow completes
100MPreviously failed54 minNow completes
500MPreviously failed4h 01mNow completes

Main takeaway: This improvement is about more than just speed. For larger LOB counts, it shifts the outcome from upgrade failures to successful completions.



Illustration: A line chart illustrating runtime for the enhanced upgrade process, showing successful upgrades from 10 million to 500 million large objects.

If your database houses large binary content as PostgreSQL large objects, this concerns you.

Workload PatternWhy It Matters
Document ManagementHandling PDFs, contracts, scanned images, and other archived files
Attachment-Heavy AppsStores files directly within PostgreSQL as opposed to using external storage solutions
Legacy Applications using lo APIsLOLs may accumulate over time
Image/Archive SystemsYou might quietly build up millions of binary objects
Prior Upgrade FailuresFailures during schema dumps may relate to this situation

Carry out these checks in every database you plan to upgrade.

-- Count PostgreSQL large objects in the current database
SELECT
  current_database() AS database_name,
  count(*) AS large_object_count
FROM pg_largeobject_metadata;

-- Estimate size of large-object data and metadata
SELECT
  pg_size_pretty(pg_total_relation_size('pg_largeobject'::regclass)) AS large_object_data_size,
  pg_size_pretty(pg_total_relation_size('pg_largeobject_metadata'::regclass)) AS large_object_metadata_size;

-- Review the shape of large-object metadata
SELECT
  count(*) AS total_large_objects,
  count(lomacl) AS large_objects_with_custom_acl,
  count(DISTINCT lomowner) AS distinct_large_object_owners
FROM pg_largeobject_metadata;

-- Find top large-object owners
SELECT
  lomowner::regrole AS owner,
  count(*) AS large_object_count
FROM pg_largeobject_metadata
GROUP BY lomowner
ORDER BY large_object_count DESC
LIMIT 10;

If Your Situation Is…Recommended Action
Targeting PostgreSQL 15 or laterAim for PostgreSQL 15 or later to take advantage of better large-object metadata handling.
Targeting PostgreSQL 14 or earlierWhenever possible, choose PostgreSQL 15+; very high LOB counts may encounter limitations of the older paths.
Very large or unusual databaseConsider restoring a backup and practicing the upgrade before going live.
Suspected orphan LOBsThink about using vacuumlo, but only after adequate testing. It can delete valid LOBs if your app has custom references.
Planning any major version upgradeEnsure you have sufficient free space and take advantage of pre-upgrade validation checks to verify extension/schema compatibility beforehand.

If large objects have made upgrading your PostgreSQL a gamble, this enhancement offers a safer and more predictable upgrade path. For databases heavy with large objects, upgrades targeted at PostgreSQL 15 and later now exhibit quicker runtimes, diminished memory/temp-space pressure, and successful validations even with up to 500 million large objects.

Share this content:


Discover more from Qureshi

Subscribe to get the latest posts sent to your email.

Discover more from Qureshi

Subscribe now to keep reading and get access to the full archive.

Continue reading