Improved locking code [skip ci]

This commit is contained in:
Andrew Kane
2023-08-21 15:42:59 -07:00
parent 3f3b3ca8e3
commit 0e1de45463
4 changed files with 22 additions and 10 deletions

View File

@@ -28,6 +28,10 @@
#define HNSW_METAPAGE_BLKNO 0
#define HNSW_HEAD_BLKNO 1 /* first element page */
/* Must correspond to page numbers since page lock is used */
#define HNSW_UPDATE_LOCK 0
#define HNSW_SCAN_LOCK 1
#define HNSW_DEFAULT_M 16
#define HNSW_MIN_M 2
#define HNSW_MAX_M 100

View File

@@ -519,7 +519,7 @@ HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_ti
* Get a shared lock for the duration of the insert. Use a page lock so it
* does not interfere with buffer lock (or reads when vacuuming).
*/
LockPage(index, HNSW_METAPAGE_BLKNO, lockmode);
LockPage(index, HNSW_UPDATE_LOCK, lockmode);
/* Get entry point */
entryPoint = HnswGetEntryPoint(index);
@@ -528,11 +528,11 @@ HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_ti
if (entryPoint == NULL || element->level > entryPoint->level)
{
/* Release shared lock */
UnlockPage(index, HNSW_METAPAGE_BLKNO, lockmode);
UnlockPage(index, HNSW_UPDATE_LOCK, lockmode);
/* Get exclusive lock */
lockmode = ExclusiveLock;
LockPage(index, HNSW_METAPAGE_BLKNO, lockmode);
LockPage(index, HNSW_UPDATE_LOCK, lockmode);
/* Get latest entry point after lock is acquired */
entryPoint = HnswGetEntryPoint(index);
@@ -548,7 +548,7 @@ HnswInsertTuple(Relation index, Datum *values, bool *isnull, ItemPointer heap_ti
WriteElement(index, procinfo, collation, element, m, efConstruction, dup, entryPoint);
/* Release shared lock */
UnlockPage(index, HNSW_METAPAGE_BLKNO, lockmode);
UnlockPage(index, HNSW_UPDATE_LOCK, lockmode);
return true;
}

View File

@@ -145,9 +145,17 @@ hnswgettuple(IndexScanDesc scan, ScanDirection dir)
HnswNormValue(so->normprocinfo, so->collation, &value, NULL);
}
LockPage(scan->indexRelation, HNSW_HEAD_BLKNO, ShareLock);
/*
* Get a shared lock. This allows vacuum to ensure no in-flight scans
* before marking tuples as deleted.
*/
LockPage(scan->indexRelation, HNSW_SCAN_LOCK, ShareLock);
so->w = GetScanItems(scan, value);
UnlockPage(scan->indexRelation, HNSW_HEAD_BLKNO, ShareLock);
/* Release shared lock */
UnlockPage(scan->indexRelation, HNSW_SCAN_LOCK, ShareLock);
so->first = false;
}

View File

@@ -316,8 +316,8 @@ RepairGraph(HnswVacuumState * vacuumstate)
RepairGraphEntryPoint(vacuumstate);
/* Wait for inserts to complete */
LockPage(index, HNSW_METAPAGE_BLKNO, ExclusiveLock);
UnlockPage(index, HNSW_METAPAGE_BLKNO, ExclusiveLock);
LockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock);
UnlockPage(index, HNSW_UPDATE_LOCK, ExclusiveLock);
while (BlockNumberIsValid(blkno))
{
@@ -405,8 +405,8 @@ MarkDeleted(HnswVacuumState * vacuumstate)
BufferAccessStrategy bas = vacuumstate->bas;
/* Wait for selects to complete */
LockPage(index, HNSW_HEAD_BLKNO, ExclusiveLock);
UnlockPage(index, HNSW_HEAD_BLKNO, ExclusiveLock);
LockPage(index, HNSW_SCAN_LOCK, ExclusiveLock);
UnlockPage(index, HNSW_SCAN_LOCK, ExclusiveLock);
while (BlockNumberIsValid(blkno))
{