Commit adc998c7 authored by Sergei Golubchik's avatar Sergei Golubchik

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
parent 54c0e937
[innodb]
innodb
default-storage-engine=innodb
[myisam]
default-storage-engine=myisam
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, ...@@ -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';
......
...@@ -6413,9 +6413,12 @@ int ha_create_table(THD *thd, const char *path, const char *db, ...@@ -6413,9 +6413,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;
......
...@@ -9893,8 +9893,6 @@ int TABLE::open_hlindexes_for_write() ...@@ -9893,8 +9893,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))
{ {
...@@ -9908,8 +9906,11 @@ int TABLE::open_hlindexes_for_write() ...@@ -9908,8 +9906,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, ...@@ -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) ...@@ -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) ...@@ -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= &target; ctx.target= &target;
return write_neighbors(&ctx, 0, target); return write_neighbors(&ctx, 0, target);
} }
...@@ -465,7 +468,7 @@ int mhnsw_insert(TABLE *table, KEY *keyinfo) ...@@ -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= &target; ctx.target= &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) ...@@ -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 *
......
...@@ -8322,13 +8322,15 @@ calc_row_difference( ...@@ -8322,13 +8322,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; {
/* Used to avoid reading history in FK check on DELETE (see MDEV-16210). */ const uint8 op_map= tl->trg_event_map | tl->slave_fk_event_map;
prebuilt->upd_node->is_delete = /* Used to avoid reading history in FK check on DELETE (see MDEV-16210). */
(op_map & trg2bit(TRG_EVENT_DELETE) prebuilt->upd_node->is_delete =
&& table->versioned(VERS_TIMESTAMP)) (op_map & trg2bit(TRG_EVENT_DELETE)
? VERSIONED_DELETE : NO_DELETE; && table->versioned(VERS_TIMESTAMP))
? 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
...@@ -13201,6 +13203,11 @@ ha_innobase::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info, ...@@ -13201,6 +13203,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);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment