Skip to content

Commit 641ddf5

Browse files
committed
Improved locking for HNSW vacuum
1 parent 782a105 commit 641ddf5

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

src/hnswvacuum.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,14 +374,32 @@ RepairGraph(HnswVacuumState * vacuumstate)
374374
{
375375
HnswElement element = (HnswElement) lfirst(lc2);
376376
HnswElement entryPoint;
377+
LOCKMODE lockmode = ShareLock;
377378

378379
/* Check if any neighbors point to deleted values */
379380
if (!NeedsUpdated(vacuumstate, element))
380381
continue;
381382

383+
/* Get a shared lock */
384+
LockPage(index, HNSW_UPDATE_LOCK, lockmode);
385+
382386
/* Refresh entry point for each element */
383387
entryPoint = HnswGetEntryPoint(index);
384388

389+
/* Prevent concurrent inserts when likely updating entry point */
390+
if (entryPoint == NULL || element->level > entryPoint->level)
391+
{
392+
/* Release shared lock */
393+
UnlockPage(index, HNSW_UPDATE_LOCK, lockmode);
394+
395+
/* Get exclusive lock */
396+
lockmode = ExclusiveLock;
397+
LockPage(index, HNSW_UPDATE_LOCK, lockmode);
398+
399+
/* Get latest entry point after lock is acquired */
400+
entryPoint = HnswGetEntryPoint(index);
401+
}
402+
385403
/* Repair connections */
386404
RepairGraphElement(vacuumstate, element, entryPoint);
387405

@@ -391,6 +409,9 @@ RepairGraph(HnswVacuumState * vacuumstate)
391409
*/
392410
if (entryPoint == NULL || element->level > entryPoint->level)
393411
HnswUpdateMetaPage(index, HNSW_UPDATE_ENTRY_GREATER, element, InvalidBlockNumber, MAIN_FORKNUM);
412+
413+
/* Release lock */
414+
UnlockPage(index, HNSW_UPDATE_LOCK, lockmode);
394415
}
395416

396417
/* Reset memory context */

0 commit comments

Comments
 (0)