I know that when an index is being created concurrently, only a SHARE ShareUpdateExclusiveLock lock is needed.
But is there a more strict type of lock needed at the very start of the process for a small amount of time? Or is only a SHARE ShareUpdateExclusiveLock lock needed for the entire operation?
I'm asking because I'm wondering what types of timeouts are advantageous to set when creating an index concurrently.
Best Answer
Well, when documentation is not enough it is possible to looking directly in code. I will give links to already released
PostgreSQL 13.1
(REL_13_1
tag) in order to avoid possible line number changes in future.I probably will not describe the entire code path of the command from the client. By grammar we know that we need
IndexStmt
command node - same grammar for both concurrently and non-concurrently create index. Everything useful will start inProcessUtilitySlow
And here, in comment to
case T_IndexStmt
, can be found direct answer for question:In general PostgreSQL will do not upgrade lock during command execution. And will take the strongest lock that will eventually be needed. For
CREATE INDEX CONCURRENTLY
it'sShareUpdateExclusiveLock
. Not aSHARE
lock as mentioned in question.But let's continue reading:
find_all_inheritors
will acquire same lockmode on inheritors.transformIndexStmt
can be found some locking modes, butNoLock
andAccessShareLock
- they are weaker thanShareUpdateExclusiveLock
DefineIndex
we see another reminder:And decide to take againg ShareUpdateExclusiveLock for concurrently build. This part of the code is noticeably long (still not as large as, for example, planner), but readable.
I am missing something? Probably. So let's build PostgreSQL with
-DLOCK_DEBUG
option to debug locking behavior and see that happens:trace_locks
will log many things, but we are interested in:lock [12664,16387]
here means databaseOID = 12664
,pg_class
OID = 16387
(such rows are logged fromLockAcquireExtended
).So, we actually acquire only
ShareUpdateExclusiveLock
on table itself.OID=16393
with several other locks is the index that this command built. Although heavy locking levels are mentioned for this object, it will not interfere with other queries.Create index concurrently
command is specially designed to work safely while running normal application queries.