diff --git a/mysql-test/main/vector_aria.result b/mysql-test/main/vector_aria.result index c6cd5fb5f3a..1a94098b364 100644 --- a/mysql-test/main/vector_aria.result +++ b/mysql-test/main/vector_aria.result @@ -8,3 +8,12 @@ check table t extended; Table Op Msg_type Msg_text test.t check status OK drop table t; +# +# MDEV-35267 Server crashes in _ma_reset_history upon altering on Aria table with vector key under lock +# +create table t (v vector(1) not null, vector(v)) engine=aria; +insert into t values (0x31313131); +lock table t write; +alter table t force; +unlock tables; +drop table t; diff --git a/mysql-test/main/vector_aria.test b/mysql-test/main/vector_aria.test index 1cf6ab99a24..cacb96863a5 100644 --- a/mysql-test/main/vector_aria.test +++ b/mysql-test/main/vector_aria.test @@ -6,3 +6,13 @@ insert into t values (1, 0x30303030),(2, 0x31313131); alter table t add vector(f); check table t extended; drop table t; + +--echo # +--echo # MDEV-35267 Server crashes in _ma_reset_history upon altering on Aria table with vector key under lock +--echo # +create table t (v vector(1) not null, vector(v)) engine=aria; +insert into t values (0x31313131); +lock table t write; +alter table t force; +unlock tables; +drop table t; diff --git a/sql/handler.cc b/sql/handler.cc index 9084fe82210..b8b6e961557 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5369,7 +5369,7 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt) for (uint i= table->s->keys; i < table->s->total_keys; i++) { DBUG_ASSERT(table->s->hlindexes() == 1); - if (table->hlindex_open(i)) + if (table->hlindex_open(i) || table->hlindex_lock(i)) return HA_ADMIN_FAILED; if ((error= table->hlindex->file->check(thd, check_opt))) return error; @@ -5502,9 +5502,10 @@ handler::ha_truncate() mark_trx_read_write(); int err= truncate(); - if (!err && table->s->hlindexes()) + for (uint i= table->s->keys; !err && i < table->s->total_keys; i++) { - if (!(err= table->hlindex_open(table->s->keys))) + DBUG_ASSERT(table->s->hlindexes() == 1); + if (!(err= table->hlindex_open(i)) && !(err= table->hlindex_lock(i))) err= table->hlindexes_on_delete_all(true); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 6b0b996fa62..2e85e63fa99 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9891,8 +9891,17 @@ int TABLE::hlindex_open(uint nr) db_stat, EXTRA_RECORD, in_use->open_options, table, 0)) return 1; hlindex= table; + hlindex->in_use= NULL; } - else if (hlindex->in_use == in_use) + return 0; +} + +int TABLE::hlindex_lock(uint nr) +{ + DBUG_ASSERT(s->hlindexes() == 1); + DBUG_ASSERT(nr == s->keys); + DBUG_ASSERT(hlindex); + if (hlindex->in_use == in_use) return 0; hlindex->in_use= in_use; // mark in use for this query hlindex->use_all_columns(); @@ -9920,7 +9929,7 @@ int TABLE::open_hlindexes_for_write() { DBUG_ASSERT(s->hlindexes() <= 1); for (uint i= s->keys; i < s->total_keys; i++) - if (hlindex_open(i)) + if (hlindex_open(i) || hlindex_lock(i)) return 1; return 0; } @@ -9983,7 +9992,7 @@ int TABLE::hlindex_read_first(uint nr, Item *item, ulonglong limit) DBUG_ASSERT(s->hlindexes() == 1); DBUG_ASSERT(nr == s->keys); - if (hlindex_open(nr)) + if (hlindex_open(nr) || hlindex_lock(nr)) return HA_ERR_CRASHED; DBUG_ASSERT(hlindex->in_use == in_use); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 09f15bead6d..6d69051af65 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -11555,9 +11555,14 @@ alter_copy: new_table= thd->create_and_open_tmp_table(&frm, alter_ctx.get_tmp_path(), alter_ctx.new_db, alter_ctx.new_name, true); - if (!new_table || new_table->open_hlindexes_for_write()) + if (!new_table) goto err_new_table_cleanup; + DBUG_ASSERT(new_table->s->hlindexes() <= 1); + for (uint i= new_table->s->keys; i < new_table->s->total_keys; i++) + if (new_table->hlindex_open(i)) + goto err_new_table_cleanup; + if (table->s->tmp_table != NO_TMP_TABLE) { /* in case of alter temp table send the tracker in OK packet */ diff --git a/sql/table.h b/sql/table.h index 7253428908c..a30dfbe7a5e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1797,6 +1797,7 @@ public: inline ha_rows stat_records() { return used_stat_records; } int hlindex_open(uint nr); + int hlindex_lock(uint nr); int hlindex_read_first(uint nr, Item *item, ulonglong limit); int hlindex_read_next(); int hlindex_read_end();