Commit 8424dfce authored by Tom Lane's avatar Tom Lane

Avoid O(N^2) behavior when the standby process releases many locks.

When replaying a transaction that held many exclusive locks on the
primary, a standby server's startup process would expend O(N^2)
effort on manipulating the list of locks.  This code was fine when
written, but commit 1cff1b95 made repetitive list_delete_first()
calls inefficient, as explained in its commit message.  Fix by just
iterating the list normally, and releasing storage only when done.
(This'd be inadequate if we needed to recover from an error occurring
partway through; but we don't.)

Back-patch to v13 where 1cff1b95 came in.

Nathan Bossart

Discussion: https://postgr.es/m/CD2F0E7F-9822-45EC-A411-AE56F14DEA9F@amazon.com
parent bd9f4cf0
......@@ -986,9 +986,11 @@ StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid)
static void
StandbyReleaseLockList(List *locks)
{
while (locks)
ListCell *lc;
foreach(lc, locks)
{
xl_standby_lock *lock = (xl_standby_lock *) linitial(locks);
xl_standby_lock *lock = (xl_standby_lock *) lfirst(lc);
LOCKTAG locktag;
elog(trace_recovery(DEBUG4),
......@@ -1002,9 +1004,9 @@ StandbyReleaseLockList(List *locks)
lock->xid, lock->dbOid, lock->relOid);
Assert(false);
}
pfree(lock);
locks = list_delete_first(locks);
}
list_free_deep(locks);
}
static void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment