Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions sql/vector_mhnsw.cc
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ class FVectorNode
const FVector *vec= nullptr;
Neighborhood *neighbors= nullptr;
uint8_t max_layer;
bool stored:1, deleted:1;
bool stored:1, deleted:1, dirty:1;

FVectorNode(MHNSW_Share *ctx_, const void *gref_);
FVectorNode(MHNSW_Share *ctx_, const void *tref_, uint8_t layer,
Expand Down Expand Up @@ -790,10 +790,13 @@ int MHNSW_Trx::do_commit(THD *thd, bool all)
{
// consider copying nodes from trx to shared cache when it makes
// sense. for ann_benchmarks it does not.
// also, consider flushing only changed nodes (a flag in the node)
for (FVectorNode &from : trx->get_cache())
{
if (!from.dirty)
continue;
if (FVectorNode *node= ctx->find_node(from.gref()))
node->vec= nullptr;
}
ctx->start= nullptr;
}
ctx->release(true, share);
Expand Down Expand Up @@ -927,14 +930,14 @@ const FVector *FVectorNode::make_vec(const void *v)
}

FVectorNode::FVectorNode(MHNSW_Share *ctx_, const void *gref_)
: ctx(ctx_), stored(true), deleted(false)
: ctx(ctx_), stored(true), deleted(false), dirty(false)
{
memcpy(gref(), gref_, gref_len());
}

FVectorNode::FVectorNode(MHNSW_Share *ctx_, const void *tref_, uint8_t layer,
const void *vec_)
: ctx(ctx_), stored(false), deleted(false)
: ctx(ctx_), stored(false), deleted(false), dirty(false)
{
DBUG_ASSERT(tref_);
memset(gref(), 0xff, gref_len()); // important: larger than any real gref
Expand Down Expand Up @@ -1204,6 +1207,14 @@ int FVectorNode::save(TABLE *graph)
DBUG_ASSERT(vec);
DBUG_ASSERT(neighbors);

// Mark as dirty BEFORE touching disk: any path that calls save()
// is mutating this node. do_commit's partial invalidation
// uses this flag to skip read-only trx-cache entries and only
// invalidate the share-cache copies that are now actually stale.
// Set even on save() error paths so a partially-written node still
// forces share to reload.
dirty= true;

restore_record(graph, s->default_values);
graph->field[FIELD_LAYER]->store(max_layer, false);
if (deleted)
Expand Down Expand Up @@ -1697,6 +1708,7 @@ int mhnsw_invalidate(TABLE *table, const uchar *rec, KEY *keyinfo)
graph->file->position(graph->record[0]);
FVectorNode *node= ctx->get_node(graph->file->ref);
node->deleted= true;
node->dirty= true; // forces share-cache invalidation on commit

return 0;
}
Expand Down