InnoDB support for hlindexes and mhnsw
* mhnsw: * use primary key, innodb loves and (and the index cannot have dupes anyway) * MyISAM is ok with that, performance-wise * must be ha_rnd_init(0) because we aren't going to scan * MyISAM resets the position on ha_rnd_init(0) so query it before * oh, and use the correct handler, just in case * HA_ERR_RECORD_IS_THE_SAME is no error * innodb: * return ref_length on create * don't assume table->pos_in_table_list is set * ok, assume away, but only for system versioned tables * set alter_info on create (InnoDB needs to check for FKs) * pair external_lock/external_unlock correctly
This commit is contained in:
parent
2efd9b17ba
commit
25b4000290
6
mysql-test/main/vector.combinations
Normal file
6
mysql-test/main/vector.combinations
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[innodb]
|
||||||
|
innodb
|
||||||
|
default-storage-engine=innodb
|
||||||
|
|
||||||
|
[myisam]
|
||||||
|
default-storage-engine=myisam
|
@ -1,3 +1,4 @@
|
|||||||
|
replace_result InnoDB MyISAM;
|
||||||
error ER_NO_INDEX_ON_TEMPORARY;
|
error ER_NO_INDEX_ON_TEMPORARY;
|
||||||
create temporary table t1 (id int auto_increment primary key, v blob not null, vector index (v));
|
create temporary table t1 (id int auto_increment primary key, v blob not null, vector index (v));
|
||||||
|
|
||||||
@ -7,6 +8,7 @@ create table t1 (id int auto_increment primary key,
|
|||||||
v blob not null, vector index (v));
|
v blob not null, vector index (v));
|
||||||
|
|
||||||
create table t1 (id int auto_increment primary key, v blob not null, vector index (v));
|
create table t1 (id int auto_increment primary key, v blob not null, vector index (v));
|
||||||
|
replace_result InnoDB MyISAM;
|
||||||
show create table t1;
|
show create table t1;
|
||||||
show keys from t1;
|
show keys from t1;
|
||||||
query_vertical select * from information_schema.statistics where table_name='t1';
|
query_vertical select * from information_schema.statistics where table_name='t1';
|
||||||
|
@ -6416,9 +6416,12 @@ int ha_create_table(THD *thd, const char *path, const char *db,
|
|||||||
DBUG_ASSERT(share.key_info[share.keys].algorithm == HA_KEY_ALG_VECTOR);
|
DBUG_ASSERT(share.key_info[share.keys].algorithm == HA_KEY_ALG_VECTOR);
|
||||||
TABLE_SHARE index_share;
|
TABLE_SHARE index_share;
|
||||||
char file_name[FN_REFLEN+1];
|
char file_name[FN_REFLEN+1];
|
||||||
|
Alter_info index_ainfo;
|
||||||
HA_CREATE_INFO index_cinfo;
|
HA_CREATE_INFO index_cinfo;
|
||||||
char *path_end= strmov(file_name, path);
|
char *path_end= strmov(file_name, path);
|
||||||
|
|
||||||
|
index_cinfo.alter_info= &index_ainfo;
|
||||||
|
|
||||||
if ((error= share.path.length > sizeof(file_name) - HLINDEX_BUF_LEN))
|
if ((error= share.path.length > sizeof(file_name) - HLINDEX_BUF_LEN))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -9900,8 +9900,6 @@ int TABLE::open_hlindexes_for_write()
|
|||||||
for (uint i= s->keys; i < s->total_keys; i++)
|
for (uint i= s->keys; i < s->total_keys; i++)
|
||||||
{
|
{
|
||||||
KEY *key= s->key_info + i;
|
KEY *key= s->key_info + i;
|
||||||
if (hlindex)
|
|
||||||
hlindex->in_use= 0;
|
|
||||||
for (uint j=0; j < key->usable_key_parts; j++)
|
for (uint j=0; j < key->usable_key_parts; j++)
|
||||||
if (bitmap_is_set(write_set, key->key_part[j].fieldnr - 1))
|
if (bitmap_is_set(write_set, key->key_part[j].fieldnr - 1))
|
||||||
{
|
{
|
||||||
@ -9915,8 +9913,11 @@ int TABLE::open_hlindexes_for_write()
|
|||||||
|
|
||||||
int TABLE::reset_hlindexes()
|
int TABLE::reset_hlindexes()
|
||||||
{
|
{
|
||||||
if (hlindex)
|
if (hlindex && hlindex->in_use)
|
||||||
|
{
|
||||||
hlindex->file->ha_external_unlock(in_use);
|
hlindex->file->ha_external_unlock(in_use);
|
||||||
|
hlindex->in_use= 0;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,8 +283,11 @@ static int write_neighbors(MHNSW_Context *ctx, size_t layer,
|
|||||||
err= graph->file->ha_index_read_map(graph->record[1], key,
|
err= graph->file->ha_index_read_map(graph->record[1], key,
|
||||||
HA_WHOLE_KEY, HA_READ_KEY_EXACT);
|
HA_WHOLE_KEY, HA_READ_KEY_EXACT);
|
||||||
if (!err)
|
if (!err)
|
||||||
|
{
|
||||||
err= graph->file->ha_update_row(graph->record[1], graph->record[0]);
|
err= graph->file->ha_update_row(graph->record[1], graph->record[0]);
|
||||||
|
if (err == HA_ERR_RECORD_IS_THE_SAME)
|
||||||
|
err= 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
my_safe_afree(neighbor_array_bytes, total_size);
|
my_safe_afree(neighbor_array_bytes, total_size);
|
||||||
return err;
|
return err;
|
||||||
@ -426,7 +429,9 @@ int mhnsw_insert(TABLE *table, KEY *keyinfo)
|
|||||||
|
|
||||||
const double NORMALIZATION_FACTOR= 1 / std::log(thd->variables.hnsw_max_connection_per_layer);
|
const double NORMALIZATION_FACTOR= 1 / std::log(thd->variables.hnsw_max_connection_per_layer);
|
||||||
|
|
||||||
if (int err= h->ha_rnd_init(1))
|
table->file->position(table->record[0]);
|
||||||
|
|
||||||
|
if (int err= h->ha_rnd_init(0))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
SCOPE_EXIT([h](){ h->ha_rnd_end(); });
|
SCOPE_EXIT([h](){ h->ha_rnd_end(); });
|
||||||
@ -436,15 +441,13 @@ int mhnsw_insert(TABLE *table, KEY *keyinfo)
|
|||||||
|
|
||||||
SCOPE_EXIT([graph](){ graph->file->ha_index_end(); });
|
SCOPE_EXIT([graph](){ graph->file->ha_index_end(); });
|
||||||
|
|
||||||
h->position(table->record[0]);
|
|
||||||
|
|
||||||
if (int err= graph->file->ha_index_last(graph->record[0]))
|
if (int err= graph->file->ha_index_last(graph->record[0]))
|
||||||
{
|
{
|
||||||
if (err != HA_ERR_END_OF_FILE)
|
if (err != HA_ERR_END_OF_FILE)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
// First insert!
|
// First insert!
|
||||||
FVectorNode target(&ctx, h->ref);
|
FVectorNode target(&ctx, table->file->ref);
|
||||||
ctx.target= ⌖
|
ctx.target= ⌖
|
||||||
return write_neighbors(&ctx, 0, target);
|
return write_neighbors(&ctx, 0, target);
|
||||||
}
|
}
|
||||||
@ -465,7 +468,7 @@ int mhnsw_insert(TABLE *table, KEY *keyinfo)
|
|||||||
if (ctx.vec_len * sizeof(float) != res->length())
|
if (ctx.vec_len * sizeof(float) != res->length())
|
||||||
return bad_value_on_insert(vec_field);
|
return bad_value_on_insert(vec_field);
|
||||||
|
|
||||||
FVectorNode target(&ctx, h->ref, res->ptr());
|
FVectorNode target(&ctx, table->file->ref, res->ptr());
|
||||||
ctx.target= ⌖
|
ctx.target= ⌖
|
||||||
|
|
||||||
double new_num= my_rnd(&thd->rand);
|
double new_num= my_rnd(&thd->rand);
|
||||||
@ -612,7 +615,7 @@ const LEX_CSTRING mhnsw_hlindex_table_def(THD *thd, uint ref_length)
|
|||||||
" layer int not null, "
|
" layer int not null, "
|
||||||
" src varbinary(%u) not null, "
|
" src varbinary(%u) not null, "
|
||||||
" neighbors varbinary(%u) not null,"
|
" neighbors varbinary(%u) not null,"
|
||||||
" index (layer, src)) ";
|
" primary key (layer, src)) ";
|
||||||
size_t len= sizeof(templ) + 32;
|
size_t len= sizeof(templ) + 32;
|
||||||
char *s= thd->alloc(len);
|
char *s= thd->alloc(len);
|
||||||
len= my_snprintf(s, len, templ, ref_length, 2 * ref_length *
|
len= my_snprintf(s, len, templ, ref_length, 2 * ref_length *
|
||||||
|
@ -8291,13 +8291,15 @@ calc_row_difference(
|
|||||||
|
|
||||||
ut_a(buf <= (byte*) original_upd_buff + buff_len);
|
ut_a(buf <= (byte*) original_upd_buff + buff_len);
|
||||||
|
|
||||||
const TABLE_LIST *tl= table->pos_in_table_list;
|
if (const TABLE_LIST *tl= table->pos_in_table_list)
|
||||||
|
{
|
||||||
const uint8 op_map= tl->trg_event_map | tl->slave_fk_event_map;
|
const uint8 op_map= tl->trg_event_map | tl->slave_fk_event_map;
|
||||||
/* Used to avoid reading history in FK check on DELETE (see MDEV-16210). */
|
/* Used to avoid reading history in FK check on DELETE (see MDEV-16210). */
|
||||||
prebuilt->upd_node->is_delete =
|
prebuilt->upd_node->is_delete =
|
||||||
(op_map & trg2bit(TRG_EVENT_DELETE)
|
(op_map & trg2bit(TRG_EVENT_DELETE)
|
||||||
&& table->versioned(VERS_TIMESTAMP))
|
&& table->versioned(VERS_TIMESTAMP))
|
||||||
? VERSIONED_DELETE : NO_DELETE;
|
? VERSIONED_DELETE : NO_DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
if (prebuilt->versioned_write) {
|
if (prebuilt->versioned_write) {
|
||||||
/* Guaranteed by CREATE TABLE, but anyway we make sure we
|
/* Guaranteed by CREATE TABLE, but anyway we make sure we
|
||||||
@ -13170,6 +13172,11 @@ ha_innobase::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info,
|
|||||||
else if (!error && m_prebuilt)
|
else if (!error && m_prebuilt)
|
||||||
m_prebuilt->table= info.table();
|
m_prebuilt->table= info.table();
|
||||||
|
|
||||||
|
if (form->s->primary_key >= MAX_KEY)
|
||||||
|
ref_length = DATA_ROW_ID_LEN;
|
||||||
|
else
|
||||||
|
ref_length = form->key_info[form->s->primary_key].key_length;
|
||||||
|
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user