mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-11 07:06:57 +08:00
Fixed locking for non-MVCC snapshots
This commit is contained in:
@@ -40,6 +40,9 @@
|
|||||||
#define IVFFLAT_METAPAGE_BLKNO 0
|
#define IVFFLAT_METAPAGE_BLKNO 0
|
||||||
#define IVFFLAT_HEAD_BLKNO 1 /* first list page */
|
#define IVFFLAT_HEAD_BLKNO 1 /* first list page */
|
||||||
|
|
||||||
|
/* Must correspond to page numbers since page lock is used */
|
||||||
|
#define IVFFLAT_SCAN_LOCK 0
|
||||||
|
|
||||||
/* IVFFlat parameters */
|
/* IVFFlat parameters */
|
||||||
#define IVFFLAT_DEFAULT_LISTS 100
|
#define IVFFLAT_DEFAULT_LISTS 100
|
||||||
#define IVFFLAT_MIN_LISTS 1
|
#define IVFFLAT_MIN_LISTS 1
|
||||||
@@ -246,6 +249,7 @@ typedef struct IvfflatScanOpaqueData
|
|||||||
int probes;
|
int probes;
|
||||||
int dimensions;
|
int dimensions;
|
||||||
bool first;
|
bool first;
|
||||||
|
bool hasLock;
|
||||||
Buffer buf;
|
Buffer buf;
|
||||||
ItemPointerData heaptid;
|
ItemPointerData heaptid;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "pgstat.h"
|
#include "pgstat.h"
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
|
#include "storage/lmgr.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compare list distances
|
* Compare list distances
|
||||||
@@ -263,6 +264,7 @@ ivfflatbeginscan(Relation index, int nkeys, int norderbys)
|
|||||||
so = (IvfflatScanOpaque) palloc(offsetof(IvfflatScanOpaqueData, lists) + probes * sizeof(IvfflatScanList));
|
so = (IvfflatScanOpaque) palloc(offsetof(IvfflatScanOpaqueData, lists) + probes * sizeof(IvfflatScanList));
|
||||||
so->buf = InvalidBuffer;
|
so->buf = InvalidBuffer;
|
||||||
so->first = true;
|
so->first = true;
|
||||||
|
so->hasLock = false;
|
||||||
ItemPointerSetInvalid(&so->heaptid);
|
ItemPointerSetInvalid(&so->heaptid);
|
||||||
so->probes = probes;
|
so->probes = probes;
|
||||||
so->dimensions = dimensions;
|
so->dimensions = dimensions;
|
||||||
@@ -347,6 +349,13 @@ ivfflatgettuple(IndexScanDesc scan, ScanDirection dir)
|
|||||||
if (scan->orderByData == NULL)
|
if (scan->orderByData == NULL)
|
||||||
elog(ERROR, "cannot scan ivfflat index without order");
|
elog(ERROR, "cannot scan ivfflat index without order");
|
||||||
|
|
||||||
|
/* Get a shared lock for non-MVCC snapshots */
|
||||||
|
if (!so->hasLock && !IsMVCCSnapshot(scan->xs_snapshot))
|
||||||
|
{
|
||||||
|
so->hasLock = true;
|
||||||
|
LockPage(scan->indexRelation, IVFFLAT_SCAN_LOCK, ShareLock);
|
||||||
|
}
|
||||||
|
|
||||||
if (scan->orderByData->sk_flags & SK_ISNULL)
|
if (scan->orderByData->sk_flags & SK_ISNULL)
|
||||||
value = PointerGetDatum(InitVector(so->dimensions));
|
value = PointerGetDatum(InitVector(so->dimensions));
|
||||||
else
|
else
|
||||||
@@ -422,6 +431,10 @@ ivfflatendscan(IndexScanDesc scan)
|
|||||||
if (BufferIsValid(so->buf))
|
if (BufferIsValid(so->buf))
|
||||||
ReleaseBuffer(so->buf);
|
ReleaseBuffer(so->buf);
|
||||||
|
|
||||||
|
/* Release lock */
|
||||||
|
if (so->hasLock)
|
||||||
|
UnlockPage(scan->indexRelation, IVFFLAT_SCAN_LOCK, ShareLock);
|
||||||
|
|
||||||
pairingheap_free(so->listQueue);
|
pairingheap_free(so->listQueue);
|
||||||
tuplesort_end(so->sortstate);
|
tuplesort_end(so->sortstate);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "commands/vacuum.h"
|
#include "commands/vacuum.h"
|
||||||
#include "ivfflat.h"
|
#include "ivfflat.h"
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
|
#include "storage/lmgr.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bulk delete tuples from the index
|
* Bulk delete tuples from the index
|
||||||
@@ -65,14 +66,10 @@ ivfflatbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
|||||||
|
|
||||||
vacuum_delay_point();
|
vacuum_delay_point();
|
||||||
|
|
||||||
buf = ReadBufferExtended(index, MAIN_FORKNUM, searchPage, RBM_NORMAL, bas);
|
/* Ensure no in-flight index scans for non-MVCC snapshots */
|
||||||
|
LockPage(index, IVFFLAT_SCAN_LOCK, ExclusiveLock);
|
||||||
|
|
||||||
/*
|
buf = ReadBufferExtended(index, MAIN_FORKNUM, searchPage, RBM_NORMAL, bas);
|
||||||
* ambulkdelete cannot delete entries from pages that are
|
|
||||||
* pinned by other backends
|
|
||||||
*
|
|
||||||
* https://www.postgresql.org/docs/current/index-locking.html
|
|
||||||
*/
|
|
||||||
LockBufferForCleanup(buf);
|
LockBufferForCleanup(buf);
|
||||||
|
|
||||||
state = GenericXLogStart(index);
|
state = GenericXLogStart(index);
|
||||||
@@ -114,6 +111,8 @@ ivfflatbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
|||||||
GenericXLogAbort(state);
|
GenericXLogAbort(state);
|
||||||
|
|
||||||
UnlockReleaseBuffer(buf);
|
UnlockReleaseBuffer(buf);
|
||||||
|
|
||||||
|
UnlockPage(index, IVFFLAT_SCAN_LOCK, ExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user