Urgent.News

What's breaking now, across thousands of outlets.

Tech

Adding a NOT NULL Column to a Large PostgreSQL Table: Constant Default, Backfill or NOT VALID

Disclosure: I build Schemity , a desktop ERD tool - this post is from our blog and uses it for the examples. TL;DR: On PostgreSQL 11 and later, ADD COLUMN ... NOT NULL DEFAULT 'new' is a catalogue change that took 10 ms on 5,000,000 rows, but a volatile default such as gen_random_uuid() rewrote the whole table in 10.4 seconds. When the value has to be computed per row, add the column as nullable,…

Adding a NOT NULL column to a large PostgreSQL table involves careful consideration of the default value and the migration approach. On PostgreSQL 11 and later, adding a column with a constant non-null default, such as NOW(), can be done quickly, often within milliseconds, as it only changes the table's metadata. However, using a volatile default like gen_random_uuid() requires rewriting the entire table, which can take around 10-12 seconds for a 5 million row table.

When the column value must be computed per row, a better approach is to add the column as nullable, backfill it in batches, and then prove it is NOT NULL. This method ensures that the full table scan does not block reads, as each batch of updates holds a short lock. Setting lock_timeout for all these statements is recommended, as they can be affected by open transactions.

The choice of migration method depends on the nature of the new column's values for existing rows. If the values are constant, the ALTER TABLE command with the NOT NULL DEFAULT clause is sufficient. However, if each row requires a unique value, splitting the process into steps is advised. First, add the column as nullable, backfill it in manageable batches, and then make the column NOT NULL.

This approach avoids the full table scan that occurs when trying to make a column NOT NULL without first ensuring there are no NULL values.

For backfilling, updating the column with a value that depends on another table's data can be done in batches to minimize locks. Finally, after backfilling, set the column to NOT NULL. On PostgreSQL versions 12 and later, adding a NOT VALID constraint check can skip the full table scan, making the process more efficient. VALIDATE CONSTRAINT, while necessary for confirming no NULL values exist, incurs a significant scan time. Once validated, the check constraint can be dropped to improve performance.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

How long do you keep a published claim provisional?

I retracted a benchmark this week. Two weeks ago I published a timing figure, described it as a fixed cost, and built an argument on it.

  • Author faces decision on retaining provisional claim validity.
  • Four instances of correcting published figures due to various issues.
  • Author suggests treating numbers as provisional with changelog.

My writing linter can be defeated by writing more. I measured how much more.

I ran my writing checker over one of my own published posts twice: once on the whole file, once on just the body with the front matter removed. Same post. Same prose.

  • Writing linter scores unchanged when front matter removed
  • Density-based tests can be reduced by adding non-objective text
  • Separating set-based and density-based scores prevents padding

More from Thursday 1 October →