Skip to content

Instantly share code, notes, and snippets.

@cabecada
Created October 11, 2024 17:57
Show Gist options
  • Save cabecada/0332411795a7cabf3ddcdae35db05eba to your computer and use it in GitHub Desktop.
Save cabecada/0332411795a7cabf3ddcdae35db05eba to your computer and use it in GitHub Desktop.
reduce lock time for set not null on a large table
postgres=# create table t(col1 int, col2 int);
CREATE TABLE
Time: 3.670 ms
postgres=# insert into t select x,x from generate_series(1, 1000000) x;
INSERT 0 1000000
Time: 3495.578 ms (00:03.496)
postgres=# select 't'::regclass::oid;
oid
-------
16395
(1 row)
Time: 0.530 ms
postgres=# alter system set client_min_messages TO log;
ALTER SYSTEM
Time: 5.631 ms
postgres=# alter system set trace_lock_table = 16395;
ALTER SYSTEM
Time: 6.875 ms
postgres=# select pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)
Time: 0.780 ms
postgres=# alter table t add constraint col2_not_null check (col2 is not null) not valid;
LOG: LockAcquire: lock [5,16395] AccessExclusiveLock
LOG: LockAcquire: new: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(AccessExclusiveLock)
LOG: LockAcquire: new: proclock(0x7a4e8c430780) lock(0x7a4e8c385778) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: LockCheckConflicts: no conflict: proclock(0x7a4e8c430780) lock(0x7a4e8c385778) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: GrantLock: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(100) req(0,0,0,0,0,0,0)=1 grant(0,0,0,0,0,0,0)=1 wait(0) type(AccessExclusiveLock)
LOG: LockAcquire: lock [5,16395] AccessExclusiveLock
LOG: LockReleaseAll: proclock(0x7a4e8c430780) lock(0x7a4e8c385778) method(1) proc(0x7a4e8c6b7f00) hold(100)
LOG: LockReleaseAll: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(100) req(0,0,0,0,0,0,0)=1 grant(0,0,0,0,0,0,0)=1 wait(0) type(INVALID)
LOG: UnGrantLock: updated: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(AccessExclusiveLock)
LOG: UnGrantLock: updated: proclock(0x7a4e8c430780) lock(0x7a4e8c385778) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: LockReleaseAll: updated: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(INVALID)
LOG: CleanUpLock: deleting: proclock(0x7a4e8c430780) lock(0x7a4e8c385778) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: CleanUpLock: deleting: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(INVALID)
ALTER TABLE
Time: 9.359 ms
postgres=# alter table t validate constraint col2_not_null;
LOG: LockAcquire: lock [5,16395] ShareUpdateExclusiveLock
LOG: LockAcquire: new: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(ShareUpdateExclusiveLock)
LOG: LockAcquire: new: proclock(0x7a4e8c430780) lock(0x7a4e8c385778) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: LockCheckConflicts: no conflict: proclock(0x7a4e8c430780) lock(0x7a4e8c385778) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: GrantLock: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(10) req(0,0,0,1,0,0,0)=1 grant(0,0,0,1,0,0,0)=1 wait(0) type(ShareUpdateExclusiveLock)
LOG: LockAcquire: lock [5,16395] ShareUpdateExclusiveLock
LOG: LockReleaseAll: proclock(0x7a4e8c430780) lock(0x7a4e8c385778) method(1) proc(0x7a4e8c6b7f00) hold(10)
LOG: LockReleaseAll: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(10) req(0,0,0,1,0,0,0)=1 grant(0,0,0,1,0,0,0)=1 wait(0) type(INVALID)
LOG: UnGrantLock: updated: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(ShareUpdateExclusiveLock)
LOG: UnGrantLock: updated: proclock(0x7a4e8c430780) lock(0x7a4e8c385778) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: LockReleaseAll: updated: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(INVALID)
LOG: CleanUpLock: deleting: proclock(0x7a4e8c430780) lock(0x7a4e8c385778) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: CleanUpLock: deleting: lock(0x7a4e8c385778) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(INVALID)
ALTER TABLE
Time: 504.997 ms
postgres=# alter table t alter column col2 set not null;
LOG: LockAcquire: lock [5,16395] AccessExclusiveLock
LOG: LockAcquire: new: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(AccessExclusiveLock)
LOG: LockAcquire: new: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: LockCheckConflicts: no conflict: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: GrantLock: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(100) req(0,0,0,0,0,0,0)=1 grant(0,0,0,0,0,0,0)=1 wait(0) type(AccessExclusiveLock)
LOG: LockAcquire: lock [5,16395] AccessExclusiveLock
LOG: LockReleaseAll: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(100)
LOG: LockReleaseAll: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(100) req(0,0,0,0,0,0,0)=1 grant(0,0,0,0,0,0,0)=1 wait(0) type(INVALID)
LOG: UnGrantLock: updated: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(AccessExclusiveLock)
LOG: UnGrantLock: updated: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: LockReleaseAll: updated: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(INVALID)
LOG: CleanUpLock: deleting: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: CleanUpLock: deleting: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(INVALID)
ALTER TABLE
Time: 3.318 ms
postgres=# alter table t drop constraint col2_not_null;
LOG: LockAcquire: lock [5,16395] AccessExclusiveLock
LOG: LockAcquire: new: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(AccessExclusiveLock)
LOG: LockAcquire: new: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: LockCheckConflicts: no conflict: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: GrantLock: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(100) req(0,0,0,0,0,0,0)=1 grant(0,0,0,0,0,0,0)=1 wait(0) type(AccessExclusiveLock)
LOG: LockAcquire: lock [5,16395] AccessExclusiveLock
LOG: LockAcquire: lock [5,16395] AccessExclusiveLock
LOG: LockReleaseAll: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(100)
LOG: LockReleaseAll: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(100) req(0,0,0,0,0,0,0)=1 grant(0,0,0,0,0,0,0)=1 wait(0) type(INVALID)
LOG: UnGrantLock: updated: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(AccessExclusiveLock)
LOG: UnGrantLock: updated: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: LockReleaseAll: updated: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(INVALID)
LOG: CleanUpLock: deleting: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: CleanUpLock: deleting: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(INVALID)
ALTER TABLE
Time: 3.326 ms
postgres=# -- now compare this with directly setting not null without invalid constraint route
postgres=# alter table t alter column col1 set not null; -- this will hold excl lock
LOG: LockAcquire: lock [5,16395] AccessExclusiveLock
LOG: LockAcquire: new: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(AccessExclusiveLock)
LOG: LockAcquire: new: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: LockCheckConflicts: no conflict: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: GrantLock: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(100) req(0,0,0,0,0,0,0)=1 grant(0,0,0,0,0,0,0)=1 wait(0) type(AccessExclusiveLock)
LOG: LockAcquire: lock [5,16395] AccessExclusiveLock
LOG: LockReleaseAll: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(100)
LOG: LockReleaseAll: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(100) req(0,0,0,0,0,0,0)=1 grant(0,0,0,0,0,0,0)=1 wait(0) type(INVALID)
LOG: UnGrantLock: updated: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(AccessExclusiveLock)
LOG: UnGrantLock: updated: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: LockReleaseAll: updated: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(INVALID)
LOG: CleanUpLock: deleting: proclock(0x7a4e8c430730) lock(0x7a4e8c3856d0) method(1) proc(0x7a4e8c6b7f00) hold(0)
LOG: CleanUpLock: deleting: lock(0x7a4e8c3856d0) id(5,16395,0,0,0,1) grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 wait(0) type(INVALID)
ALTER TABLE
Time: 234.771 ms
also :
https://gist.github.com/jjb/fab5cc5f0e1b23af28694db4fc01c55a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment