mirror of
https://github.com/pgvector/pgvector.git
synced 2026-07-11 07:06:57 +08:00
Fixed issue with index not reusing space
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
## 0.2.4 (unreleased)
|
||||||
|
|
||||||
|
- Fixed issue with index not reusing space
|
||||||
|
|
||||||
## 0.2.3 (2022-01-30)
|
## 0.2.3 (2022-01-30)
|
||||||
|
|
||||||
- Added indexing progress for Postgres 12+
|
- Added indexing progress for Postgres 12+
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ InsertTuples(Relation index, IvfflatBuildState * buildstate, ForkNumber forkNum)
|
|||||||
IvfflatCommitBuffer(buf, state);
|
IvfflatCommitBuffer(buf, state);
|
||||||
|
|
||||||
/* Set the start and insert pages */
|
/* Set the start and insert pages */
|
||||||
IvfflatUpdateList(index, state, buildstate->listInfo[i], insertPage, startPage, forkNum);
|
IvfflatUpdateList(index, state, buildstate->listInfo[i], insertPage, InvalidBlockNumber, startPage, forkNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ void IvfflatKmeans(Relation index, VectorArray samples, VectorArray centers);
|
|||||||
FmgrInfo *IvfflatOptionalProcInfo(Relation rel, uint16 procnum);
|
FmgrInfo *IvfflatOptionalProcInfo(Relation rel, uint16 procnum);
|
||||||
bool IvfflatNormValue(FmgrInfo *procinfo, Oid collation, Datum *value, Vector * result);
|
bool IvfflatNormValue(FmgrInfo *procinfo, Oid collation, Datum *value, Vector * result);
|
||||||
int IvfflatGetLists(Relation index);
|
int IvfflatGetLists(Relation index);
|
||||||
void IvfflatUpdateList(Relation index, GenericXLogState *state, ListInfo listInfo, BlockNumber insertPage, BlockNumber startPage, ForkNumber forkNum);
|
void IvfflatUpdateList(Relation index, GenericXLogState *state, ListInfo listInfo, BlockNumber insertPage, BlockNumber originalInsertPage, BlockNumber startPage, ForkNumber forkNum);
|
||||||
void IvfflatCommitBuffer(Buffer buf, GenericXLogState *state);
|
void IvfflatCommitBuffer(Buffer buf, GenericXLogState *state);
|
||||||
void IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum);
|
void IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **state, ForkNumber forkNum);
|
||||||
Buffer IvfflatNewBuffer(Relation index, ForkNumber forkNum);
|
Buffer IvfflatNewBuffer(Relation index, ForkNumber forkNum);
|
||||||
|
|||||||
@@ -77,11 +77,12 @@ InsertTuple(Relation rel, IndexTuple itup, Relation heapRel, Datum *values)
|
|||||||
Size itemsz;
|
Size itemsz;
|
||||||
BlockNumber insertPage = InvalidBlockNumber;
|
BlockNumber insertPage = InvalidBlockNumber;
|
||||||
ListInfo listInfo;
|
ListInfo listInfo;
|
||||||
bool newPage = false;
|
BlockNumber originalInsertPage;
|
||||||
|
|
||||||
/* Find the insert page - sets the page and list info */
|
/* Find the insert page - sets the page and list info */
|
||||||
FindInsertPage(rel, values, &insertPage, &listInfo);
|
FindInsertPage(rel, values, &insertPage, &listInfo);
|
||||||
Assert(BlockNumberIsValid(insertPage));
|
Assert(BlockNumberIsValid(insertPage));
|
||||||
|
originalInsertPage = insertPage;
|
||||||
|
|
||||||
itemsz = MAXALIGN(IndexTupleSize(itup));
|
itemsz = MAXALIGN(IndexTupleSize(itup));
|
||||||
Assert(itemsz <= BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(IvfflatPageOpaqueData)));
|
Assert(itemsz <= BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(IvfflatPageOpaqueData)));
|
||||||
@@ -107,7 +108,6 @@ InsertTuple(Relation rel, IndexTuple itup, Relation heapRel, Datum *values)
|
|||||||
IvfflatAppendPage(rel, &buf, &page, &state, MAIN_FORKNUM);
|
IvfflatAppendPage(rel, &buf, &page, &state, MAIN_FORKNUM);
|
||||||
|
|
||||||
insertPage = BufferGetBlockNumber(buf);
|
insertPage = BufferGetBlockNumber(buf);
|
||||||
newPage = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,8 +118,8 @@ InsertTuple(Relation rel, IndexTuple itup, Relation heapRel, Datum *values)
|
|||||||
IvfflatCommitBuffer(buf, state);
|
IvfflatCommitBuffer(buf, state);
|
||||||
|
|
||||||
/* Update the insert page */
|
/* Update the insert page */
|
||||||
if (newPage)
|
if (insertPage != originalInsertPage)
|
||||||
IvfflatUpdateList(rel, state, listInfo, insertPage, InvalidBlockNumber, MAIN_FORKNUM);
|
IvfflatUpdateList(rel, state, listInfo, insertPage, originalInsertPage, InvalidBlockNumber, MAIN_FORKNUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -153,11 +153,13 @@ IvfflatAppendPage(Relation index, Buffer *buf, Page *page, GenericXLogState **st
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
IvfflatUpdateList(Relation index, GenericXLogState *state, ListInfo listInfo,
|
IvfflatUpdateList(Relation index, GenericXLogState *state, ListInfo listInfo,
|
||||||
BlockNumber insertPage, BlockNumber startPage, ForkNumber forkNum)
|
BlockNumber insertPage, BlockNumber originalInsertPage,
|
||||||
|
BlockNumber startPage, ForkNumber forkNum)
|
||||||
{
|
{
|
||||||
Buffer buf;
|
Buffer buf;
|
||||||
Page page;
|
Page page;
|
||||||
IvfflatList list;
|
IvfflatList list;
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
buf = ReadBufferExtended(index, forkNum, listInfo.blkno, RBM_NORMAL, NULL);
|
buf = ReadBufferExtended(index, forkNum, listInfo.blkno, RBM_NORMAL, NULL);
|
||||||
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
|
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
|
||||||
@@ -165,12 +167,29 @@ IvfflatUpdateList(Relation index, GenericXLogState *state, ListInfo listInfo,
|
|||||||
page = GenericXLogRegisterBuffer(state, buf, 0);
|
page = GenericXLogRegisterBuffer(state, buf, 0);
|
||||||
list = (IvfflatList) PageGetItem(page, PageGetItemId(page, listInfo.offno));
|
list = (IvfflatList) PageGetItem(page, PageGetItemId(page, listInfo.offno));
|
||||||
|
|
||||||
if (BlockNumberIsValid(insertPage))
|
if (BlockNumberIsValid(insertPage) && insertPage != list->insertPage)
|
||||||
list->insertPage = insertPage;
|
{
|
||||||
|
/* Skip update if insert page is lower than original insert page */
|
||||||
|
/* This is needed to prevent insert from overwriting vacuum */
|
||||||
|
if (!BlockNumberIsValid(originalInsertPage) || insertPage >= originalInsertPage)
|
||||||
|
{
|
||||||
|
list->insertPage = insertPage;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (BlockNumberIsValid(startPage))
|
if (BlockNumberIsValid(startPage) && startPage != list->startPage)
|
||||||
|
{
|
||||||
list->startPage = startPage;
|
list->startPage = startPage;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Could only commit if changed, but extra complexity isn't needed */
|
/* Only commit if changed */
|
||||||
IvfflatCommitBuffer(buf, state);
|
if (changed)
|
||||||
|
IvfflatCommitBuffer(buf, state);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GenericXLogAbort(state);
|
||||||
|
UnlockReleaseBuffer(buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ ivfflatbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
|||||||
ItemPointer htup;
|
ItemPointer htup;
|
||||||
OffsetNumber deletable[MaxOffsetNumber];
|
OffsetNumber deletable[MaxOffsetNumber];
|
||||||
int ndeletable;
|
int ndeletable;
|
||||||
OffsetNumber startPages[MaxOffsetNumber];
|
BlockNumber startPages[MaxOffsetNumber];
|
||||||
BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO;
|
BlockNumber nextblkno = IVFFLAT_HEAD_BLKNO;
|
||||||
BlockNumber searchPage;
|
BlockNumber searchPage;
|
||||||
BlockNumber insertPage;
|
BlockNumber insertPage;
|
||||||
@@ -98,6 +98,11 @@ ivfflatbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
|||||||
stats->num_index_tuples++;
|
stats->num_index_tuples++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set to first free page */
|
||||||
|
/* Must be set before searchPage is updated */
|
||||||
|
if (!BlockNumberIsValid(insertPage) && ndeletable > 0)
|
||||||
|
insertPage = searchPage;
|
||||||
|
|
||||||
searchPage = IvfflatPageGetOpaque(page)->nextblkno;
|
searchPage = IvfflatPageGetOpaque(page)->nextblkno;
|
||||||
|
|
||||||
if (ndeletable > 0)
|
if (ndeletable > 0)
|
||||||
@@ -106,10 +111,6 @@ ivfflatbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
|||||||
PageIndexMultiDelete(page, deletable, ndeletable);
|
PageIndexMultiDelete(page, deletable, ndeletable);
|
||||||
MarkBufferDirty(buf);
|
MarkBufferDirty(buf);
|
||||||
GenericXLogFinish(state);
|
GenericXLogFinish(state);
|
||||||
|
|
||||||
/* Set to first free page */
|
|
||||||
if (!BlockNumberIsValid(insertPage))
|
|
||||||
insertPage = searchPage;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
GenericXLogAbort(state);
|
GenericXLogAbort(state);
|
||||||
@@ -123,10 +124,10 @@ ivfflatbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
|||||||
* We don't add or delete items from lists pages, so offset won't
|
* We don't add or delete items from lists pages, so offset won't
|
||||||
* change.
|
* change.
|
||||||
*/
|
*/
|
||||||
if (!BlockNumberIsValid(insertPage))
|
if (BlockNumberIsValid(insertPage))
|
||||||
{
|
{
|
||||||
listInfo.offno = coffno;
|
listInfo.offno = coffno;
|
||||||
IvfflatUpdateList(index, state, listInfo, insertPage, InvalidBlockNumber, MAIN_FORKNUM);
|
IvfflatUpdateList(index, state, listInfo, insertPage, InvalidBlockNumber, InvalidBlockNumber, MAIN_FORKNUM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user