diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-12-13 18:01:49 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-12-13 18:01:49 +0200 |
commit | 25b91c3f13affc1b58169240894b206ff34b1db3 (patch) | |
tree | 4042ba02c9777eabc030c80f376cd6e25114ac6d /storage | |
parent | dbcbee10176dde410867a3762385a9e5ee63e1d3 (diff) | |
parent | a8a5c8a1b8ac566241d43a85de90c11f5d1568d9 (diff) | |
download | mariadb-git-25b91c3f13affc1b58169240894b206ff34b1db3.tar.gz |
Merge 10.6 into 10.7
Diffstat (limited to 'storage')
33 files changed, 453 insertions, 99 deletions
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 6d180ac5441..1b901525b56 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1614,15 +1614,10 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf) pcf->Scale= 0; pcf->Opt= (fop) ? (int)fop->opt : 0; -// if (fp->field_length >= 0) { + if (fp->field_length >= 0) pcf->Length= fp->field_length; - - // length is bytes for Connect, not characters - if (!strnicmp(chset, "utf8", 4)) - pcf->Length /= 3; - -// } else -// pcf->Length= 256; // BLOB? + else + pcf->Length= 256; // BLOB? pcf->Precision= pcf->Length; diff --git a/storage/connect/mysql-test/connect/r/index.result b/storage/connect/mysql-test/connect/r/index.result index bffaaecc785..edeca2d1960 100644 --- a/storage/connect/mysql-test/connect/r/index.result +++ b/storage/connect/mysql-test/connect/r/index.result @@ -139,3 +139,39 @@ DELETE FROM t1; DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; +# +# MDEV-28299: Server crashes in +# XINDXS::Range/CntIndexRange (Connect engine) +# +CREATE TABLE t1 ( a int not null, KEY (a))engine=CONNECT; +Warnings: +Warning 1105 No table_type. Will be set to DOS +Warning 1105 No file name. Table will use t1.dos +SELECT * FROM t1 WHERE a=1; +a +INSERT INTO t1 values (1),(2),(1); +SELECT * FROM t1 WHERE a=1; +a +1 +1 +DROP TABLE t1; +CREATE TABLE t1 (a int, b int, pk int, PRIMARY KEY (pk)) engine=CONNECT; +Warnings: +Warning 1105 No table_type. Will be set to DOS +Warning 1105 No file name. Table will use t1.dos +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +a +INSERT INTO t1 values (1,2,1),(2,1,2),(1,2,3),(3,4,4); +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +a +INSERT INTO t1 values (1,2,5); +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +a +1 +DROP TABLE t1; diff --git a/storage/connect/mysql-test/connect/r/mysql.result b/storage/connect/mysql-test/connect/r/mysql.result index 918256ac395..d3c244b277a 100644 --- a/storage/connect/mysql-test/connect/r/mysql.result +++ b/storage/connect/mysql-test/connect/r/mysql.result @@ -326,5 +326,43 @@ id DROP TABLE t1; DROP TABLE t2; # +# MDEV-28489 / MDEV-26722 UTF8 bytes calculated incorrectly +# +CREATE TABLE t1 (name varchar(20)) CHARSET=utf8; +INSERT INTO t1 (name) VALUES ('Иванова'), ('Ivanova'); +CREATE TABLE t2 (name varchar(1)) ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='test' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=PORT' CHARSET=utf8; +SELECT hex(name) from t1; +hex(name) +C390CB9CC390C2B2C390C2B0C390C2BDC390C2BEC390C2B2C390C2B0 +4976616E6F7661 +SELECT hex(name) from t2; +hex(name) +C390 +49 +Warnings: +Warning 1105 Out of range value for column name at row 1 +Warning 1265 Data truncated for column 'name' at row 1 +Warning 1105 Out of range value Ð? for column 'name' at row 1 +Warning 1105 Out of range value for column name at row 2 +Warning 1265 Data truncated for column 'name' at row 2 +Warning 1105 Out of range value Iva for column 'name' at row 2 +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1 (col char(5)) CHARSET=utf8; +INSERT INTO t1 (col) VALUES ('glace'), ('glacé'); +Warnings: +Warning 1406 Data too long for column 'col' at row 2 +CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='test' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=PORT' CHARSET=utf8; +SELECT hex(col) from t1; +hex(col) +676C616365 +676C6163C383 +SELECT hex(col) from t2; +hex(col) +676C616365 +676C6163C383 +DROP TABLE t2; +DROP TABLE t1; +# # End of 10.3 tests # diff --git a/storage/connect/mysql-test/connect/t/index.test b/storage/connect/mysql-test/connect/t/index.test index 5e913582734..9dc6357074d 100644 --- a/storage/connect/mysql-test/connect/t/index.test +++ b/storage/connect/mysql-test/connect/t/index.test @@ -84,3 +84,29 @@ DROP TABLE t3; --remove_file $MYSQLD_DATADIR/test/emp.txt --remove_file $MYSQLD_DATADIR/test/sexe.csv --remove_file $MYSQLD_DATADIR/test/sitmat.csv + +--echo # +--echo # MDEV-28299: Server crashes in +--echo # XINDXS::Range/CntIndexRange (Connect engine) +--echo # + +CREATE TABLE t1 ( a int not null, KEY (a))engine=CONNECT; +SELECT * FROM t1 WHERE a=1; + +INSERT INTO t1 values (1),(2),(1); +SELECT * FROM t1 WHERE a=1; +DROP TABLE t1; + +CREATE TABLE t1 (a int, b int, pk int, PRIMARY KEY (pk)) engine=CONNECT; +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +INSERT INTO t1 values (1,2,1),(2,1,2),(1,2,3),(3,4,4); +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +INSERT INTO t1 values (1,2,5); +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +DROP TABLE t1; diff --git a/storage/connect/mysql-test/connect/t/mysql.test b/storage/connect/mysql-test/connect/t/mysql.test index ce76a4665d5..a50db4a6457 100644 --- a/storage/connect/mysql-test/connect/t/mysql.test +++ b/storage/connect/mysql-test/connect/t/mysql.test @@ -504,5 +504,35 @@ DROP TABLE t1; DROP TABLE t2; --echo # +--echo # MDEV-28489 / MDEV-26722 UTF8 bytes calculated incorrectly +--echo # + +CREATE TABLE t1 (name varchar(20)) CHARSET=utf8; +INSERT INTO t1 (name) VALUES ('Иванова'), ('Ivanova'); + +--replace_result $PORT PORT +--eval CREATE TABLE t2 (name varchar(1)) ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='test' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT' CHARSET=utf8 + +SELECT hex(name) from t1; +# This will warn as we are truncating data +SELECT hex(name) from t2; + +DROP TABLE t2; +DROP TABLE t1; + +CREATE TABLE t1 (col char(5)) CHARSET=utf8; +INSERT INTO t1 (col) VALUES ('glace'), ('glacé'); + +--replace_result $PORT PORT +--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='test' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT' CHARSET=utf8 + +SELECT hex(col) from t1; +SELECT hex(col) from t2; + +DROP TABLE t2; +DROP TABLE t1; + + +--echo # --echo # End of 10.3 tests --echo # diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index 7f0efb727a2..4bcbbfd4235 100644 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -2029,6 +2029,10 @@ int XINDXS::Range(PGLOBAL g, int limit, bool incl) PXCOL kp = To_KeyCol; OPVAL op = Op; +// In case single column index doesn't exist return + if (!kp) + return 0; + switch (limit) { case 1: Op = (incl) ? OP_GE : OP_GT; break; case 2: Op = (incl) ? OP_GT : OP_GE; break; diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 3c2e97666cb..b6cbab41919 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -833,7 +833,7 @@ static void btr_free_root(buf_block_t *block, const fil_space_t &space, MTR_MEMO_PAGE_SX_FIX)); ut_ad(mtr->is_named_space(&space)); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); if (btr_root_fseg_validate(PAGE_HEADER + PAGE_BTR_SEG_TOP, *block, space)) { @@ -1107,7 +1107,7 @@ dberr_t dict_index_t::clear(que_thr_t *thr) #ifdef BTR_CUR_HASH_ADAPT if (root_block->index) - btr_search_drop_page_hash_index(root_block); + btr_search_drop_page_hash_index(root_block, false); ut_ad(n_ahi_pages() == 0); #endif mtr.memset(root_block, PAGE_HEADER + PAGE_BTR_SEG_LEAF, @@ -1287,7 +1287,7 @@ static dberr_t btr_page_reorganize_low(page_cur_t *cursor, mtr_t *mtr) if (UNIV_UNLIKELY(pos == ULINT_UNDEFINED)) return DB_CORRUPTION; - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); buf_block_t *old= buf_block_alloc(); /* Copy the old page to temporary space */ @@ -1617,7 +1617,7 @@ btr_page_empty( || page_zip_validate(page_zip, block->page.frame, index)); #endif /* UNIV_ZIP_DEBUG */ - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); /* Recreate the page: note that global data on page (possible segment headers, next page-field, etc.) is preserved intact */ @@ -3421,7 +3421,7 @@ btr_lift_page_up( mem_heap_free(heap); } - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); /* Make the father empty */ btr_page_empty(father_block, father_page_zip, index, page_level, mtr); @@ -3742,7 +3742,7 @@ cannot_merge: goto err_exit; } - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); /* Remove the page from the level list */ err = btr_level_list_remove(*block, *index, mtr); @@ -3845,7 +3845,7 @@ cannot_merge: goto err_exit; } - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); if (merge_page_zip && left_page_no == FIL_NULL) { @@ -4045,7 +4045,7 @@ btr_discard_only_page_on_level( ut_ad(fil_page_index_page_check(page)); ut_ad(block->page.id().space() == index->table->space->id); ut_ad(mtr->memo_contains_flagged(block, MTR_MEMO_PAGE_X_FIX)); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); cursor.page_cur.index = index; cursor.page_cur.block = block; @@ -4229,7 +4229,7 @@ btr_discard_page( return DB_CORRUPTION; } - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); if (dict_index_is_spatial(index)) { rtr_node_ptr_delete(&parent_cursor, mtr); diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index 3009f04021f..76b173359da 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -415,7 +415,7 @@ btr_defragment_merge_pages( free it. */ lock_update_merge_left(*to_block, orig_pred, from_block->page.id()); - btr_search_drop_page_hash_index(from_block); + btr_search_drop_page_hash_index(from_block, false); if (btr_level_list_remove(*from_block, *index, mtr) != DB_SUCCESS || btr_cur_node_ptr_delete(&parent, mtr) != DB_SUCCESS diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index 140fac851de..fc890f9233b 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -706,7 +706,7 @@ btr_search_update_hash_ref( if (index != cursor->index()) { ut_ad(index->id == cursor->index()->id); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); return; } @@ -1423,7 +1423,7 @@ void btr_search_drop_page_hash_when_freed(const page_id_t page_id) dropping the table (preventing eviction). */ DBUG_ASSERT(block->index->table->get_ref_count() || dict_sys.locked()); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); } mtr_commit(&mtr); @@ -1491,7 +1491,7 @@ btr_search_build_page_hash_index( } if (rebuild) { - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); } /* Check that the values for hash index build are sensible */ @@ -1715,7 +1715,7 @@ btr_search_move_or_delete_hash_entries( if (new_block->index) { drop_exit: - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); return; } @@ -1789,7 +1789,7 @@ void btr_search_update_hash_on_delete(btr_cur_t *cursor) ut_ad(!cursor->index()->table->is_temporary()); if (index != cursor->index()) { - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); return; } @@ -1864,7 +1864,7 @@ void btr_search_update_hash_node_on_insert(btr_cur_t *cursor, if (index != cursor->index()) { ut_ad(index->id == cursor->index()->id); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); return; } @@ -1957,7 +1957,7 @@ void btr_search_update_hash_on_insert(btr_cur_t *cursor, if (index != cursor->index()) { ut_ad(index->id == cursor->index()->id); drop: - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); return; } diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index c6b14d2fc67..876eab89da8 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2122,7 +2122,7 @@ void buf_page_free(fil_space_t *space, uint32_t page, mtr_t *mtr) block->page.lock.x_lock(); #ifdef BTR_CUR_HASH_ADAPT if (block->index) - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); #endif /* BTR_CUR_HASH_ADAPT */ block->page.set_freed(block->page.state()); mtr->memo_push(block, MTR_MEMO_PAGE_X_MODIFY); @@ -3216,7 +3216,8 @@ retry: #ifdef BTR_CUR_HASH_ADAPT if (drop_hash_entry) - btr_search_drop_page_hash_index(reinterpret_cast<buf_block_t*>(bpage)); + btr_search_drop_page_hash_index(reinterpret_cast<buf_block_t*>(bpage), + false); #endif /* BTR_CUR_HASH_ADAPT */ if (ibuf_exist && !recv_recovery_is_on()) diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 81204043c84..ed638e254da 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -954,7 +954,7 @@ func_exit: order to avoid bogus Valgrind or MSAN warnings.*/ MEM_MAKE_DEFINED(block->page.frame, srv_page_size); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); MEM_UNDEFINED(block->page.frame, srv_page_size); mysql_mutex_lock(&buf_pool.mutex); } diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index ba277ca67e9..af4af76ed78 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -339,6 +339,8 @@ dict_table_schema_check( const dict_table_t* table= dict_sys.load_table(req_schema->table_name); if (!table) { + if (opt_bootstrap) + return DB_TABLE_NOT_FOUND; if (req_schema == &table_stats_schema) { if (innodb_table_stats_not_found_reported) { return DB_STATS_DO_NOT_EXIST; @@ -4133,7 +4135,8 @@ dict_stats_update( or is corrupted, calculate the transient stats */ if (innodb_table_stats_not_found == false && - table->stats_error_printed == false) { + table->stats_error_printed == false && + !opt_bootstrap) { ib::error() << "Fetch of persistent statistics" " requested for table " << table->name diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index 9e6b6abcf03..77108a552d2 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -29,6 +29,7 @@ Created 2013-7-26 by Kevin Lewis #include "os0file.h" #include "page0page.h" #include "srv0start.h" +#include "log.h" /** Release the resources. */ void @@ -305,10 +306,23 @@ Datafile::read_first_page(bool read_only_mode) if (!fil_space_t::is_valid_flags(m_flags, m_space_id)) { uint32_t cflags = fsp_flags_convert_from_101(m_flags); if (cflags == UINT32_MAX) { - ib::error() - << "Invalid flags " << ib::hex(m_flags) - << " in " << m_filepath; - return(DB_CORRUPTION); + switch (fsp_flags_is_incompatible_mysql(m_flags)) { + case 0: + sql_print_error("InnoDB: Invalid flags 0x%" PRIx32 " in %s", + m_flags, m_filepath); + return DB_CORRUPTION; + case 3: + case 2: + sql_print_error("InnoDB: MySQL-8.0 tablespace in %s", + m_filepath); + break; + case 1: + sql_print_error("InnoDB: MySQL Encrypted tablespace in %s", + m_filepath); + break; + } + sql_print_error("InnoDB: Restart in MySQL for migration/recovery."); + return DB_UNSUPPORTED; } else { m_flags = cflags; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 853a303e925..dfd2b0738a4 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5983,11 +5983,6 @@ ha_innobase::open(const char* name, int, uint) MONITOR_INC(MONITOR_TABLE_OPEN); if ((ib_table->flags2 & DICT_TF2_DISCARDED)) { - - ib_senderrf(thd, - IB_LOG_LEVEL_WARN, ER_TABLESPACE_DISCARDED, - table->s->table_name.str); - /* Allow an open because a proper DISCARD should have set all the flags and index root page numbers to FIL_NULL that should prevent any DML from running but it should allow DDL @@ -13851,6 +13846,10 @@ int ha_innobase::truncate() mem_heap_t *heap= mem_heap_create(1000); + if (!ib_table->space) + ib_senderrf(m_user_thd, IB_LOG_LEVEL_WARN, ER_TABLESPACE_DISCARDED, + table->s->table_name.str); + dict_get_and_save_data_dir_path(ib_table); info.data_file_name= ib_table->data_dir_path; const char *temp_name= @@ -18177,7 +18176,9 @@ innodb_enable_monitor_at_startup( /****************************************************************//** Callback function for accessing the InnoDB variables from MySQL: SHOW VARIABLES. */ -static int show_innodb_vars(THD*, SHOW_VAR* var, char*) +static int show_innodb_vars(THD*, SHOW_VAR* var, void *, + struct system_status_var *status_var, + enum enum_var_type var_type) { innodb_export_status(); var->type = SHOW_ARRAY; @@ -18573,7 +18574,7 @@ innodb_encrypt_tables_update(THD*, st_mysql_sys_var*, void*, const void* save) } static SHOW_VAR innodb_status_variables_export[]= { - {"Innodb", (char*) &show_innodb_vars, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Innodb", &show_innodb_vars), {NullS, NullS, SHOW_LONG} }; @@ -20057,17 +20058,13 @@ static TABLE* innodb_find_table_for_vc(THD* thd, dict_table_t* table) return mysql_table; } -/** Get the computed value by supplying the base column values. -@param[in,out] table table whose virtual column - template to be built */ +/** Only used by the purge thread +@param[in,out] table table whose virtual column template to be built */ TABLE* innobase_init_vc_templ(dict_table_t* table) { - if (table->vc_templ != NULL) { - return NULL; - } DBUG_ENTER("innobase_init_vc_templ"); - table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); + ut_ad(table->vc_templ == NULL); TABLE *mysql_table= innodb_find_table_for_vc(current_thd, table); @@ -20076,8 +20073,12 @@ TABLE* innobase_init_vc_templ(dict_table_t* table) DBUG_RETURN(NULL); } - innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, - false); + dict_vcol_templ_t* vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); + + dict_sys.lock(SRW_LOCK_CALL); + table->vc_templ = vc_templ; + innobase_build_v_templ(mysql_table, table, vc_templ, nullptr, true); + dict_sys.unlock(); DBUG_RETURN(mysql_table); } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 1e11265b5ce..1b05add4a0c 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2239,6 +2239,12 @@ ha_innobase::check_if_supported_inplace_alter( update_thd(); + if (!m_prebuilt->table->space) { + ib_senderrf(m_user_thd, IB_LOG_LEVEL_WARN, + ER_TABLESPACE_DISCARDED, + table->s->table_name.str); + } + if (is_read_only(!high_level_read_only && (ha_alter_info->handler_flags & ALTER_OPTIONS) && ha_alter_info->create_info->key_block_size == 0 @@ -5847,7 +5853,16 @@ static bool innobase_instant_try( const dict_col_t* old_cols = user_table->cols; DBUG_ASSERT(user_table->n_cols == ctx->old_n_cols); +#ifdef BTR_CUR_HASH_ADAPT + /* Acquire the ahi latch to avoid a race condition + between ahi access and instant alter table */ + srw_spin_lock* ahi_latch = btr_search_sys.get_latch(*index); + ahi_latch->wr_lock(SRW_LOCK_CALL); +#endif /* BTR_CUR_HASH_ADAPT */ const bool metadata_changed = ctx->instant_column(); +#ifdef BTR_CUR_HASH_ADAPT + ahi_latch->wr_unlock(); +#endif /* BTR_CUR_HASH_ADAPT */ DBUG_ASSERT(index->n_fields >= n_old_fields); /* The table may have been emptied and may have lost its diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h index 2b8c6c252e9..48e4fadab9b 100644 --- a/storage/innobase/include/btr0sea.h +++ b/storage/innobase/include/btr0sea.h @@ -97,7 +97,7 @@ btr_search_move_or_delete_hash_entries( @param[in] garbage_collect drop ahi only if the index is marked as freed */ void btr_search_drop_page_hash_index(buf_block_t* block, - bool garbage_collect= false); + bool garbage_collect); /** Drop possible adaptive hash index entries when a page is evicted from the buffer pool or freed in a file, or the index is being dropped. diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index 52334056353..26261554f9b 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -706,6 +706,20 @@ inline bool fsp_flags_match(uint32_t expected, uint32_t actual) return actual == expected || fsp_flags_convert_from_101(actual) == expected; } +/** Determine if FSP_SPACE_FLAGS are from an incompatible MySQL format. +@param flags the contents of FSP_SPACE_FLAGS +@return MySQL flags shifted. +@retval 0, if not a MySQL incompatible format. */ +MY_ATTRIBUTE((warn_unused_result, const)) +inline uint32_t fsp_flags_is_incompatible_mysql(uint32_t flags) +{ + /* + MySQL-8.0 SDI flag (bit 14), + or MySQL 5.7 Encyption flag (bit 13) + */ + return flags >> 13 & 3; +} + /** Determine the descriptor index within a descriptor page. @param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0 @param[in] offset page offset diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 4626957b55d..4facb6002b6 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -385,15 +385,15 @@ bool mtr_t::commit_file(fil_space_t &space, const char *name) if (name) { + char *new_name= mem_strdup(name); + mysql_mutex_lock(&fil_system.mutex); success= os_file_rename(innodb_data_file_key, old_name, name); - if (success) - { - mysql_mutex_lock(&fil_system.mutex); - space.chain.start->name= mem_strdup(name); - mysql_mutex_unlock(&fil_system.mutex); - ut_free(old_name); - } + space.chain.start->name= new_name; + else + old_name= new_name; + mysql_mutex_unlock(&fil_system.mutex); + ut_free(old_name); } else { @@ -1250,7 +1250,7 @@ void mtr_t::free(const fil_space_t &space, uint32_t offset) slot.type= MTR_MEMO_PAGE_X_MODIFY; #ifdef BTR_CUR_HASH_ADAPT if (block->index) - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); #endif /* BTR_CUR_HASH_ADAPT */ block->page.set_freed(block->page.state()); } diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 7b603bb876b..a7f38774cc8 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -4410,7 +4410,7 @@ page_zip_reorganize( mtr_log_t log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE); temp_block = buf_block_alloc(); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); temp_page = temp_block->page.frame; /* Copy the old page to temporary space */ diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 65c17a4e4b1..18a39a41a18 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -43,6 +43,7 @@ Created 2012-02-08 by Sunny Bains. #include "lock0lock.h" #include "lzo/lzo1x.h" #include "snappy-c.h" +#include "log.h" #include "scope.h" @@ -583,6 +584,18 @@ protected: uint32_t m_space_flags; }; +ATTRIBUTE_COLD static dberr_t invalid_space_flags(uint32_t flags) +{ + if (fsp_flags_is_incompatible_mysql(flags)) + { + sql_print_error("InnoDB: unsupported MySQL tablespace"); + return DB_UNSUPPORTED; + } + + sql_print_error("InnoDB: Invalid FSP_SPACE_FLAGS=0x%" PRIx32, flags); + return DB_CORRUPTION; +} + /** Determine the page size to use for traversing the tablespace @param file_size size of the tablespace file in bytes @param block contents of the first page in the tablespace file. @@ -598,7 +611,7 @@ AbstractCallback::init( if (!fil_space_t::is_valid_flags(m_space_flags, true)) { uint32_t cflags = fsp_flags_convert_from_101(m_space_flags); if (cflags == UINT32_MAX) { - return(DB_CORRUPTION); + return DB_CORRUPTION; } m_space_flags = cflags; } @@ -3078,7 +3091,7 @@ static dberr_t handle_instant_metadata(dict_table_t *table, if (!success) return DB_IO_ERROR; - if (os_file_get_size(file) < srv_page_size * 4) + if (os_file_get_size(file) < srv_page_size) return DB_CORRUPTION; SCOPE_EXIT([&file]() { os_file_close(file); }); @@ -3097,10 +3110,7 @@ static dberr_t handle_instant_metadata(dict_table_t *table, { auto cflags= fsp_flags_convert_from_101(space_flags); if (cflags == UINT32_MAX) - { - ib::error() << "Invalid FSP_SPACE_FLAGS=" << ib::hex(space_flags); - return DB_CORRUPTION; - } + return invalid_space_flags(space_flags); space_flags= static_cast<decltype(space_flags)>(cflags); } @@ -4394,7 +4404,7 @@ row_import_for_mysql( ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_INTERNAL_ERROR, - "Cannot reset LSNs in table %s : %s", + "Error importing tablespace for table %s : %s", table_name, ut_strerr(err)); } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 427fdedee60..dbf2b24dc80 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -899,11 +899,7 @@ row_ins_foreign_fill_virtual( &ext, update->heap); n_diff = update->n_fields; - if (index->table->vc_templ == NULL) { - /** This can occur when there is a cascading - delete or update after restart. */ - innobase_init_vc_templ(index->table); - } + ut_ad(index->table->vc_templ != NULL); ib_vcol_row vc(NULL); uchar *record = vc.record(thd, index, &mysql_table); diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 42e09ffd180..94d69d88fb5 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -2093,6 +2093,9 @@ func_exit_committed: index->set_modified(mtr); pcur.btr_cur.page_cur.index = index; + ut_free(pcur.old_rec_buf); + pcur.old_rec_buf = nullptr; + if (ROW_FOUND != row_search_index_entry( entry, BTR_MODIFY_TREE, &pcur, &mtr)) { ut_ad(0); diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 0d941feb0a1..a4d634f2d14 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -105,11 +105,17 @@ row_quiesce_write_indexes( FILE* file, /*!< in: file to write to */ THD* thd) /*!< in/out: session */ { + ulint n_indexes = 0; + for (const dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); + index; index = UT_LIST_GET_NEXT(indexes, index)) { + n_indexes += index->is_committed(); + } + { byte row[sizeof(ib_uint32_t)]; /* Write the number of indexes in the table. */ - mach_write_to_4(row, UT_LIST_GET_LEN(table->indexes)); + mach_write_to_4(row, n_indexes); DBUG_EXECUTE_IF("ib_export_io_write_failure_11", close(fileno(file));); @@ -131,6 +137,12 @@ row_quiesce_write_indexes( index != 0 && err == DB_SUCCESS; index = UT_LIST_GET_NEXT(indexes, index)) { + if (!index->is_committed()) { + continue; + } + + ut_ad(n_indexes); ut_d(n_indexes--); + byte* ptr; byte row[sizeof(index_id_t) + sizeof(ib_uint32_t) * 8]; @@ -201,6 +213,7 @@ row_quiesce_write_indexes( err = row_quiesce_write_index_fields(index, file, thd); } + ut_ad(!n_indexes); return(err); } diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index eb328a5d194..104897228e8 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -1489,6 +1489,7 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt) { param->db_name= table->s->db.str; param->table_name= table->alias.c_ptr(); + param->testflag= check_opt->flags; _ma_check_print_info(param, "Running zerofill on moved table"); return zerofill(thd, check_opt); } diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index 1168427a458..40d2d69754f 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -13146,7 +13146,9 @@ bool ha_rocksdb::commit_inplace_alter_table( #define SHOW_FNAME(name) rocksdb_show_##name #define DEF_SHOW_FUNC(name, key) \ - static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR * var, char *buff) { \ + static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR * var, void *buff, \ + struct system_status_var *status_var, \ + enum enum_var_type var_type) { \ rocksdb_status_counters.name = \ rocksdb_stats->getTickerCount(rocksdb::key); \ var->type = SHOW_LONGLONG; \ @@ -13155,7 +13157,7 @@ bool ha_rocksdb::commit_inplace_alter_table( } #define DEF_STATUS_VAR(name) \ - { "rocksdb_" #name, (char *)&SHOW_FNAME(name), SHOW_FUNC } + SHOW_FUNC_ENTRY( "rocksdb_" #name, &SHOW_FNAME(name)) #define DEF_STATUS_VAR_PTR(name, ptr, option) \ { "rocksdb_" name, (char *)ptr, option } @@ -13383,11 +13385,14 @@ static SHOW_VAR myrocks_status_variables[] = { {NullS, NullS, SHOW_LONG}}; -static void show_myrocks_vars(THD *thd, SHOW_VAR *var, char *buff) { +static int show_myrocks_vars(THD *thd, SHOW_VAR *var, void *buff, + struct system_status_var *, + enum enum_var_type) { myrocks_update_status(); myrocks_update_memory_status(); var->type = SHOW_ARRAY; var->value = reinterpret_cast<char *>(&myrocks_status_variables); + return 0; } static ulonglong io_stall_prop_value( @@ -13468,10 +13473,13 @@ static SHOW_VAR rocksdb_stall_status_variables[] = { // end of the array marker {NullS, NullS, SHOW_LONG}}; -static void show_rocksdb_stall_vars(THD *thd, SHOW_VAR *var, char *buff) { +static int show_rocksdb_stall_vars(THD *thd, SHOW_VAR *var, void *buff, + struct system_status_var *, + enum enum_var_type) { update_rocksdb_stall_status(); var->type = SHOW_ARRAY; var->value = reinterpret_cast<char *>(&rocksdb_stall_status_variables); + return 0; } static SHOW_VAR rocksdb_status_vars[] = { @@ -13576,9 +13584,8 @@ static SHOW_VAR rocksdb_status_vars[] = { // the variables generated by SHOW_FUNC are sorted only by prefix (first // arg in the tuple below), so make sure it is unique to make sorting // deterministic as quick sort is not stable - {"rocksdb", reinterpret_cast<char *>(&show_myrocks_vars), SHOW_FUNC}, - {"rocksdb_stall", reinterpret_cast<char *>(&show_rocksdb_stall_vars), - SHOW_FUNC}, + SHOW_FUNC_ENTRY("rocksdb", &show_myrocks_vars), + SHOW_FUNC_ENTRY("rocksdb_stall", &show_rocksdb_stall_vars), {NullS, NullS, SHOW_LONG}}; /* diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28996.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28996.result new file mode 100644 index 00000000000..f805e7ef3ad --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28996.result @@ -0,0 +1,34 @@ +# +# MDEV-28996 ASAN errors in String::q_append / spider_string::q_append / spider_db_mbase_util::open_item_func +# +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +a CHAR(8) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO tbl_a VALUES ('foo'),('bar'); +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +a CHAR(8) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; +SELECT MAX(BINARY a) FROM tbl_a; +MAX(BINARY a) +foo +DROP DATABASE auto_test_local; +connection child2_1; +DROP DATABASE auto_test_remote; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29855.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29855.result new file mode 100644 index 00000000000..4335d20f4c3 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29855.result @@ -0,0 +1,34 @@ +# +# MDEV-29855 Crash with SPIDER_DIRECT_SQL and spider_udf_ds_use_real_table=1 +# +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +a INT +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +a INT +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; +SET spider_udf_ds_use_real_table=1; +SELECT SPIDER_DIRECT_SQL('select 1 as 1', 'tbl_a', 'srv "s_2_1"'); +ERROR 3D000: No database selected +connection master_1; +DROP DATABASE IF EXISTS auto_test_local; +connection child2_1; +DROP DATABASE IF EXISTS auto_test_remote; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.test new file mode 100644 index 00000000000..8097fe7e607 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.test @@ -0,0 +1,40 @@ +--echo # +--echo # MDEV-28996 ASAN errors in String::q_append / spider_string::q_append / spider_db_mbase_util::open_item_func +--echo # + +--disable_query_log +--disable_result_log +--source ../t/test_init.inc +--enable_query_log +--enable_result_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +eval CREATE TABLE tbl_a ( + a CHAR(8) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +INSERT INTO tbl_a VALUES ('foo'),('bar'); + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; + +eval CREATE TABLE tbl_a ( + a CHAR(8) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; + +SELECT MAX(BINARY a) FROM tbl_a; + +DROP DATABASE auto_test_local; + +--connection child2_1 +DROP DATABASE auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_query_log +--enable_result_log diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.test new file mode 100644 index 00000000000..13cda064c72 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.test @@ -0,0 +1,40 @@ +--echo # +--echo # MDEV-29855 Crash with SPIDER_DIRECT_SQL and spider_udf_ds_use_real_table=1 +--echo # + + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +eval CREATE TABLE tbl_a ( + a INT +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; +eval CREATE TABLE tbl_a ( + a INT +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; + +SET spider_udf_ds_use_real_table=1; +--error ER_NO_DB_ERROR +SELECT SPIDER_DIRECT_SQL('select 1 as 1', 'tbl_a', 'srv "s_2_1"'); + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; + +--connection child2_1 +DROP DATABASE IF EXISTS auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_query_log +--enable_result_log diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 8d426f85118..a48b55206ea 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -5720,6 +5720,7 @@ int spider_db_mbase_util::open_item_func( int error_num; Item *item, **item_list = item_func->arguments(); Field *field; + spider_string tmp_str; uint roop_count, item_count = item_func->argument_count(), start_item = 0; LEX_CSTRING org_func_name= {SPIDER_SQL_NULL_CHAR_STR, SPIDER_SQL_NULL_CHAR_LEN}; @@ -6178,10 +6179,11 @@ int spider_db_mbase_util::open_item_func( if (str) { - char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; - spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); + char *tmp_ptr, *tmp_ptr2; + DBUG_ASSERT(tmp_str.length() == 0); + tmp_str.set_charset(str->charset()); tmp_str.init_calc_mem(123); - tmp_str.length(0); + tmp_str.reserve(MAX_FIELD_WIDTH); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) { @@ -6315,10 +6317,11 @@ int spider_db_mbase_util::open_item_func( if (str) { - char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; - spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); + char *tmp_ptr, *tmp_ptr2; + DBUG_ASSERT(tmp_str.length() == 0); + tmp_str.set_charset(str->charset()); tmp_str.init_calc_mem(124); - tmp_str.length(0); + tmp_str.reserve(MAX_FIELD_WIDTH); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) { @@ -6471,10 +6474,11 @@ int spider_db_mbase_util::open_item_func( if (str) { - char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; - spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); + char *tmp_ptr, *tmp_ptr2; + DBUG_ASSERT(tmp_str.length() == 0); + tmp_str.set_charset(str->charset()); tmp_str.init_calc_mem(125); - tmp_str.length(0); + tmp_str.reserve(MAX_FIELD_WIDTH); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) { diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc index 6db37de78ab..1d9098833f4 100644 --- a/storage/spider/spd_direct_sql.cc +++ b/storage/spider/spd_direct_sql.cc @@ -1956,17 +1956,6 @@ long long spider_direct_sql_body( #else } TABLE_LIST *tables = &direct_sql->table_list[roop_count]; -#ifdef SPIDER_use_LEX_CSTRING_for_database_tablename_alias - table_list.init_one_table( - &table_list.db, &table_list.table_name, 0, TL_WRITE); -#else - tables->init_one_table( - SPIDER_TABLE_LIST_db_str(&table_list), - SPIDER_TABLE_LIST_db_length(&table_list), - SPIDER_TABLE_LIST_table_name_str(&table_list), - SPIDER_TABLE_LIST_table_name_length(&table_list), - SPIDER_TABLE_LIST_table_name_str(&table_list), TL_WRITE); -#endif MDL_REQUEST_INIT(&tables->mdl_request, MDL_key::TABLE, SPIDER_TABLE_LIST_db_str(&table_list), SPIDER_TABLE_LIST_table_name_str(&table_list), |