InletDownload

Is this migration safe?

Before you run a schema change on production: which lock it takes, what it blocks while it waits and runs, and whether it rewrites or scans the table. Each answer comes from running the statement on real servers and reading the locks it held.

PostgreSQL

Checked on PostgreSQL 14, 15, 16, 17 and 18.

StatementLockBlocksRewrites
ALTER TABLE t ADD CONSTRAINT c_check CHECK (c >= 0)ACCESS EXCLUSIVEReads and writesScans the table
ALTER TABLE t ADD COLUMN c int NOT NULL DEFAULT 0ACCESS EXCLUSIVEReads and writesNo for a constant default; yes for a volatile one
ALTER TABLE orders ADD FOREIGN KEY (customer_id) REFERENCES customers (id)SHARE ROW EXCLUSIVEWritesScans the table
ALTER TABLE t ADD PRIMARY KEY (id)ACCESS EXCLUSIVEReads and writesNo, but scans the table and builds an index
ALTER TABLE t ADD CONSTRAINT t_c_key UNIQUE (c)ACCESS EXCLUSIVEReads and writesNo, but scans the table and builds an index
ALTER TABLE t ALTER COLUMN c SET DEFAULT 0ACCESS EXCLUSIVEReads and writesNo
ALTER TABLE t ALTER COLUMN c TYPE bigintACCESS EXCLUSIVEReads and writesDepends on the change (see the table)
ALTER TABLE t ADD COLUMN c intACCESS EXCLUSIVEReads and writesNo
ALTER TABLE t DROP COLUMN cACCESS EXCLUSIVEReads and writesNo
ALTER TABLE t RENAME COLUMN a TO bACCESS EXCLUSIVEReads and writesNo
ALTER TABLE parent ATTACH PARTITION p FOR VALUES FROM ('2026-10-01') TO ('2026-11-01')SHARE UPDATE EXCLUSIVEOther DDL onlyScans the new partition (skipped with a matching CHECK)
CREATE INDEX CONCURRENTLY t_c_idx ON t (c)SHARE UPDATE EXCLUSIVEOther DDL onlyNo (scans the table twice)
CREATE INDEX t_c_idx ON t (c)SHAREWritesScans the table
DROP INDEX t_c_idxACCESS EXCLUSIVEReads and writesNo
REINDEX INDEX t_c_idxSHARE, plus ACCESS EXCLUSIVE on the indexReads and writesRebuilds the index, not the table
ALTER TABLE t RENAME TO t2ACCESS EXCLUSIVEReads and writesNo
ALTER TABLE t ALTER COLUMN c SET NOT NULLACCESS EXCLUSIVEReads and writesScans the table
TRUNCATE tACCESS EXCLUSIVEReads and writesNo (swaps in a new empty file)
VACUUM FULL tACCESS EXCLUSIVEReads and writesYes

MySQL

Checked on MySQL 8.4, with MariaDB 11.4’s differences noted.

StatementLockBlocksRewrites
ALTER TABLE orders ADD INDEX idx_customer (customer_id), ALGORITHM=INPLACE, LOCK=NONEShared upgradable metadata lock; exclusive briefly at start and endOther DDL onlyScans the table
ALTER TABLE orders ADD COLUMN source varchar(20), ALGORITHM=INSTANTExclusive metadata lock (milliseconds)Reads and writesNo
ALTER TABLE orders MODIFY total decimal(12,2) NOT NULLSHARED_NO_WRITE metadata lock (LOCK=SHARED)WritesYes
ALTER TABLE orders RENAME COLUMN note TO comment, ALGORITHM=INSTANTExclusive metadata lock (milliseconds)Reads and writesNo