Postgres version: 13.8
A week or so ago we ran a migration to safely drop a column on one of our tables. This column is not referenced by any other table and there was no index on the column. As far as I'm aware of, dropping a column acquires an exclusive lock on the table but only for a brief moment while it removes the column from the catalog. However this migration took around a minute to run and locked the table during the entire time. This table is heavily used and has around 17 million rows.
I've been trying to figure out why the drop column migration took a lot of time. This table also has a very commonly used SELECT FOR UPDATE
query ran against it. Would a row-level lock like this affect a drop column statement or am I looking down the wrong path?
1 Answer 1
Short answer is yes.
Row-level locks taken with SELECT FOR UPDATE
also take a table-level ROW SHARE
lock, that conflicts with the exclusive lock for ALTER TABLE
.
See for yourself. Start a transaction in one session:
BEGIN;
SELECT FROM tbl WHERE id = 1 FOR UPDATE;
-- ROLLBACK; -- later
Then run in a separate session:
BEGIN;
ALTER TABLE tbl DROP COLUMN some_column;
-- ROLLBACK; -- later
You'll see the 2nd transaction waiting until the first commits or rolls back.
(Be sure to close the 2nd transactions with ROLLBACK;
unless you actually want drop the column.)
ROW SHARE
(RowShareLock
)Conflicts with the
EXCLUSIVE
andACCESS EXCLUSIVE
lock modes.The
SELECT
command acquires a lock of this mode on all tables on which one of theFOR UPDATE
,FOR NO KEY UPDATE
,FOR SHARE
, orFOR KEY SHARE
options is specified (in addition toACCESS SHARE
locks on any other tables that are referenced without any explicitFOR ...
locking option).
-
Thanks for the quick response! Good to know!jarviliam– jarviliam2023年03月30日 04:00:28 +00:00Commented Mar 30, 2023 at 4:00