diff --git a/mysql-test/main/myisam_repair.result b/mysql-test/main/myisam_repair.result new file mode 100644 index 00000000000..50a9695c8c7 --- /dev/null +++ b/mysql-test/main/myisam_repair.result @@ -0,0 +1,51 @@ +# +# MDEV-23318 Assertion `cache_empty(keycache)' failed in +# prepare_resize_simple_key_cache +# +SET @buffer_size.save= @@key_buffer_size; +SET GLOBAL key_buffer_size= 134217728; +SET myisam_repair_threads= 6; +CREATE TABLE t1 ( +pk INT AUTO_INCREMENT, +a INTEGER, +b DATE, +c VARCHAR(1), +d BLOB, +PRIMARY KEY (pk), +KEY (a), +KEY (b), +KEY (c, a), +UNIQUE (d) +) ENGINE=MyISAM; +INSERT INTO t1 (a,b,c) SELECT seq, '2020-12-12', 'x' FROM seq_1_to_20; +ALTER TABLE t1 DISABLE KEYS; +SET GLOBAL c.key_buffer_size= 13700864; +Warnings: +Warning 1292 Truncated incorrect key_buffer_size value: '13700864' +INSERT INTO t1 SELECT 1; +ERROR 21S01: Column count doesn't match value count at row 1 +SET GLOBAL c.key_buffer_size= 0; +DROP TABLE t1; +SET GLOBAL key_buffer_size= 134217728; +CREATE TABLE t1 ( +pk INT AUTO_INCREMENT, +a INTEGER, +b DATE, +c VARCHAR(1), +d VARBINARY(40982), +PRIMARY KEY (pk), +KEY (a), +KEY (b), +KEY (c, a), +UNIQUE (d) +) ENGINE=MyISAM; +INSERT INTO t1 (a,b,c) SELECT seq, '2020-12-12', 'x' FROM seq_1_to_20; +ALTER TABLE t1 DISABLE KEYS; +SET GLOBAL c.key_buffer_size= 13700864; +Warnings: +Warning 1292 Truncated incorrect key_buffer_size value: '13700864' +INSERT INTO t1 SELECT 1; +ERROR 21S01: Column count doesn't match value count at row 1 +SET GLOBAL c.key_buffer_size= 0; +DROP TABLE t1; +SET GLOBAL key_buffer_size= @buffer_size.save; diff --git a/mysql-test/main/myisam_repair.test b/mysql-test/main/myisam_repair.test new file mode 100644 index 00000000000..bcb69d59e2c --- /dev/null +++ b/mysql-test/main/myisam_repair.test @@ -0,0 +1,57 @@ +--source include/have_sequence.inc + + +--echo # +--echo # MDEV-23318 Assertion `cache_empty(keycache)' failed in +--echo # prepare_resize_simple_key_cache +--echo # + +SET @buffer_size.save= @@key_buffer_size; +SET GLOBAL key_buffer_size= 134217728; +SET myisam_repair_threads= 6; + +CREATE TABLE t1 ( + pk INT AUTO_INCREMENT, + a INTEGER, + b DATE, + c VARCHAR(1), + d BLOB, + PRIMARY KEY (pk), + KEY (a), + KEY (b), + KEY (c, a), + UNIQUE (d) +) ENGINE=MyISAM; + +INSERT INTO t1 (a,b,c) SELECT seq, '2020-12-12', 'x' FROM seq_1_to_20; + +ALTER TABLE t1 DISABLE KEYS; +SET GLOBAL c.key_buffer_size= 13700864; +--error ER_WRONG_VALUE_COUNT_ON_ROW +INSERT INTO t1 SELECT 1; +SET GLOBAL c.key_buffer_size= 0; +DROP TABLE t1; + +SET GLOBAL key_buffer_size= 134217728; + +CREATE TABLE t1 ( + pk INT AUTO_INCREMENT, + a INTEGER, + b DATE, + c VARCHAR(1), + d VARBINARY(40982), + PRIMARY KEY (pk), + KEY (a), + KEY (b), + KEY (c, a), + UNIQUE (d) +) ENGINE=MyISAM; +INSERT INTO t1 (a,b,c) SELECT seq, '2020-12-12', 'x' FROM seq_1_to_20; +ALTER TABLE t1 DISABLE KEYS; +SET GLOBAL c.key_buffer_size= 13700864; +--error ER_WRONG_VALUE_COUNT_ON_ROW +INSERT INTO t1 SELECT 1; +SET GLOBAL c.key_buffer_size= 0; + +DROP TABLE t1; +SET GLOBAL key_buffer_size= @buffer_size.save; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 1cc396fe2cd..1b994210ddf 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -688,6 +688,8 @@ my_bool mi_killed_in_mariadb(MI_INFO *info) static int compute_vcols(MI_INFO *info, uchar *record, int keynum) { + /* This mutex is needed for parallel repair */ + mysql_mutex_lock(&info->s->intern_lock); TABLE *table= (TABLE*)(info->external_ref); table->move_fields(table->field, record, table->field[0]->record_ptr()); if (keynum == -1) // update all vcols @@ -695,6 +697,7 @@ static int compute_vcols(MI_INFO *info, uchar *record, int keynum) int error= table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ); if (table->update_virtual_fields(table->file, VCOL_UPDATE_INDEXED)) error= 1; + mysql_mutex_unlock(&info->s->intern_lock); return error; } // update only one key @@ -703,9 +706,10 @@ static int compute_vcols(MI_INFO *info, uchar *record, int keynum) for (; kp < end; kp++) { Field *f= table->field[kp->fieldnr - 1]; - if (f->vcol_info) + if (f->vcol_info && !f->vcol_info->stored_in_db) table->update_virtual_field(f); } + mysql_mutex_unlock(&info->s->intern_lock); return 0; } @@ -956,7 +960,7 @@ void ha_myisam::setup_vcols_for_repair(HA_CHECK *param) if (!table->vfield) return; - if (file->s->base.reclength == file->s->vreclength) + if (file->s->base.reclength == file->s->vreclength) { bool indexed_vcols= false; ulong new_vreclength= file->s->vreclength; @@ -964,7 +968,8 @@ void ha_myisam::setup_vcols_for_repair(HA_CHECK *param) { if (!(*vf)->stored_in_db()) { - uint vf_end= (*vf)->offset(table->record[0]) + (*vf)->pack_length_in_rec(); + uint vf_end= ((*vf)->offset(table->record[0]) + + (*vf)->pack_length_in_rec()); set_if_bigger(new_vreclength, vf_end); indexed_vcols|= ((*vf)->flags & PART_KEY_FLAG) != 0; } @@ -982,7 +987,8 @@ void ha_myisam::restore_vcos_after_repair() { if (file->s->base.reclength < file->s->vreclength) { - table->move_fields(table->field, table->record[0], table->field[0]->record_ptr()); + table->move_fields(table->field, table->record[0], + table->field[0]->record_ptr()); table->default_column_bitmaps(); } }