From a1ec7ac4f44d1cabfa730195c47dcdcbd7e246fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Apr 2019 15:56:28 +0300 Subject: [PATCH 01/10] Clean up table_name_t row_is_mysql_tmp_table_name(): Replaced with dict_table_t::is_temporary_name() and table_name_t::is_temporary(). table_name_t: Add constructors. --- storage/innobase/dict/dict0load.cc | 45 ++++++++--------------- storage/innobase/handler/ha_innodb.cc | 6 +-- storage/innobase/handler/handler0alter.cc | 8 ++-- storage/innobase/include/dict0crea.ic | 14 +------ storage/innobase/include/dict0mem.h | 20 ++++++++++ storage/innobase/include/row0mysql.h | 13 +------ storage/innobase/row/row0mysql.cc | 21 ++--------- 7 files changed, 46 insertions(+), 81 deletions(-) diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 2fe34886df2..8b0a0fa1030 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2018, MariaDB Corporation. +Copyright (c) 2016, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -81,7 +81,7 @@ file_unreadable flag in the table object we return */ static dict_table_t* dict_load_table_one( - table_name_t& name, + const table_name_t& name, bool cached, dict_err_ignore_t ignore_err, dict_names_t& fk_tables); @@ -93,9 +93,8 @@ Do not load any columns or indexes. @param[out,own] table table, or NULL @return error message @retval NULL on success */ -static -const char* -dict_load_table_low(table_name_t& name, const rec_t* rec, dict_table_t** table) +static const char* dict_load_table_low(const table_name_t& name, + const rec_t* rec, dict_table_t** table) MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Load an index definition from a SYS_INDEXES record to dict_index_t. @@ -392,7 +391,6 @@ dict_process_sys_tables_rec_and_mtr_commit( ulint len; const char* field; const char* err_msg = NULL; - table_name_t table_name; field = (const char*) rec_get_nth_field_old( rec, DICT_FLD__SYS_TABLES__NAME, &len); @@ -402,7 +400,7 @@ dict_process_sys_tables_rec_and_mtr_commit( ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX)); /* Get the table name */ - table_name.m_name = mem_heap_strdupl(heap, field, len); + table_name_t table_name(mem_heap_strdupl(heap, field, len)); /* If DICT_TABLE_LOAD_FROM_CACHE is set, first check whether there is cached dict_table_t struct */ @@ -1397,7 +1395,6 @@ dict_check_sys_tables( rec = dict_getnext_system(&pcur, &mtr)) { const byte* field; ulint len; - table_name_t table_name; table_id_t table_id; ulint space_id; ulint n_cols; @@ -1413,7 +1410,8 @@ dict_check_sys_tables( /* Copy the table name from rec */ field = rec_get_nth_field_old( rec, DICT_FLD__SYS_TABLES__NAME, &len); - table_name.m_name = mem_strdupl((char*) field, len); + + table_name_t table_name(mem_strdupl((char*) field, len)); DBUG_PRINT("dict_check_sys_tables", ("name: %p, '%s'", table_name.m_name, table_name.m_name)); @@ -2660,9 +2658,8 @@ Do not load any columns or indexes. @param[out,own] table table, or NULL @return error message @retval NULL on success */ -static -const char* -dict_load_table_low(table_name_t& name, const rec_t* rec, dict_table_t** table) +static const char* dict_load_table_low(const table_name_t& name, + const rec_t* rec, dict_table_t** table) { table_id_t table_id; ulint space_id; @@ -2792,32 +2789,22 @@ dict_load_table( dict_names_t fk_list; dict_table_t* result; dict_names_t::iterator i; - table_name_t table_name; DBUG_ENTER("dict_load_table"); DBUG_PRINT("dict_load_table", ("loading table: '%s'", name)); ut_ad(mutex_own(&dict_sys->mutex)); - table_name.m_name = const_cast(name); - result = dict_table_check_if_in_cache_low(name); if (!result) { - result = dict_load_table_one(table_name, cached, ignore_err, - fk_list); + result = dict_load_table_one(const_cast(name), + cached, ignore_err, fk_list); while (!fk_list.empty()) { - table_name_t fk_table_name; - dict_table_t* fk_table; - - fk_table_name.m_name = - const_cast(fk_list.front()); - fk_table = dict_table_check_if_in_cache_low( - fk_table_name.m_name); - if (!fk_table) { - dict_load_table_one(fk_table_name, cached, - ignore_err, fk_list); - } + if (!dict_table_check_if_in_cache_low(fk_list.front())) + dict_load_table_one( + const_cast(fk_list.front()), + cached, ignore_err, fk_list); fk_list.pop_front(); } } @@ -2917,7 +2904,7 @@ file_unreadable flag in the table object we return */ static dict_table_t* dict_load_table_one( - table_name_t& name, + const table_name_t& name, bool cached, dict_err_ignore_t ignore_err, dict_names_t& fk_tables) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b448f71d6d0..f7de3e39259 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -13208,10 +13208,8 @@ inline int ha_innobase::delete_table(const char* name, enum_sql_command sqlcom) err = row_drop_database_for_mysql(norm_name, trx, &num_partitions); norm_name[len] = 0; - if (num_partitions == 0 - && !row_is_mysql_tmp_table_name(norm_name)) { - table_name_t tbl_name; - tbl_name.m_name = norm_name; + table_name_t tbl_name(norm_name); + if (num_partitions == 0 && !tbl_name.is_temporary()) { ib::error() << "Table " << tbl_name << " does not exist in the InnoDB" " internal data dictionary though MariaDB is" diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 2adcaeabd5e..a3b03a45eb3 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -7449,13 +7449,11 @@ innobase_update_foreign_cache( fk_tables.front(), true, DICT_ERR_IGNORE_NONE); if (table == NULL) { - table_name_t table_name; - table_name.m_name = const_cast( - fk_tables.front()); - err = DB_TABLE_NOT_FOUND; ib::error() - << "Failed to load table '" << table_name + << "Failed to load table '" + << table_name_t(const_cast + (fk_tables.front())) << "' which has a foreign key constraint with" << " table '" << user_table->name << "'."; break; diff --git a/storage/innobase/include/dict0crea.ic b/storage/innobase/include/dict0crea.ic index 00e4e54115a..a9c4fa7b010 100644 --- a/storage/innobase/include/dict0crea.ic +++ b/storage/innobase/include/dict0crea.ic @@ -28,18 +28,6 @@ Created 1/8/1996 Heikki Tuuri #include "mem0mem.h" -/*********************************************************************//** -Checks if a table name contains the string "/#sql" which denotes temporary -tables in MySQL. -@return true if temporary table */ -bool -row_is_mysql_tmp_table_name( -/*========================*/ - const char* name) MY_ATTRIBUTE((warn_unused_result)); - /*!< in: table name in the form - 'database/tablename' */ - - /********************************************************************//** Generate a foreign key constraint name when it was not named by the user. A generated constraint has a name of the format dbname/tablename_ibfk_NUMBER, @@ -63,7 +51,7 @@ dict_create_add_foreign_id( mem_heap_alloc(foreign->heap, namelen + 20)); - if (row_is_mysql_tmp_table_name(name)) { + if (dict_table_t::is_temporary_name(name)) { /* no overflow if number < 1e13 */ sprintf(id, "%s_ibfk_%lu", name, diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index f59ff6fcd7f..7bbbf8372e4 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -559,6 +559,11 @@ struct table_name_t /** The name in internal representation */ char* m_name; + /** Default constructor */ + table_name_t() {} + /** Constructor */ + table_name_t(char* name) : m_name(name) {} + /** @return the end of the schema name */ const char* dbend() const { @@ -581,6 +586,9 @@ struct table_name_t @return the partition name @retval NULL if the table is not partitioned */ const char* part() const { return strstr(basename(), part_suffix); } + + /** @return whether this is a temporary or intermediate table name */ + inline bool is_temporary() const; }; /** Data structure for a column in a table */ @@ -1401,6 +1409,13 @@ struct dict_table_t { return(UNIV_LIKELY(!file_unreadable)); } + /** Check if a table name contains the string "/#sql" + which denotes temporary or intermediate tables in MariaDB. */ + static bool is_temporary_name(const char* name) + { + return strstr(name, "/" TEMP_FILE_PREFIX) != NULL; + } + /** Id of the table. */ table_id_t id; /** Hash chain node. */ @@ -1770,6 +1785,11 @@ public: dict_vcol_templ_t* vc_templ; }; +inline bool table_name_t::is_temporary() const +{ + return dict_table_t::is_temporary_name(m_name); +} + inline bool dict_index_t::is_readable() const { return(UNIV_LIKELY(!table->file_unreadable)); diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 9c799c57d37..5dd34f5679b 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -275,17 +275,6 @@ row_unlock_for_mysql( row_prebuilt_t* prebuilt, ibool has_latches_on_recs); -/*********************************************************************//** -Checks if a table name contains the string "/#sql" which denotes temporary -tables in MySQL. -@return true if temporary table */ -bool -row_is_mysql_tmp_table_name( -/*========================*/ - const char* name) MY_ATTRIBUTE((warn_unused_result)); - /*!< in: table name in the form - 'database/tablename' */ - /*********************************************************************//** Creates an query graph node of 'update' type to be used in the MySQL interface. diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 19c67b69c2b..6c3049d0cf3 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -3966,7 +3966,7 @@ loop: } - if (!row_is_mysql_tmp_table_name(table->name.m_name)) { + if (!table->name.is_temporary()) { /* There could be orphan temp tables left from interrupted alter table. Leave them, and handle the rest.*/ @@ -4060,21 +4060,6 @@ loop: DBUG_RETURN(err); } -/*********************************************************************//** -Checks if a table name contains the string "/#sql" which denotes temporary -tables in MySQL. -@return true if temporary table */ -MY_ATTRIBUTE((warn_unused_result)) -bool -row_is_mysql_tmp_table_name( -/*========================*/ - const char* name) /*!< in: table name in the form - 'database/tablename' */ -{ - return(strstr(name, "/" TEMP_FILE_PREFIX) != NULL); - /* return(strstr(name, "/@0023sql") != NULL); */ -} - /****************************************************************//** Delete a single constraint. @return error code or DB_SUCCESS */ @@ -4174,8 +4159,8 @@ row_rename_table_for_mysql( trx->op_info = "renaming table"; - old_is_tmp = row_is_mysql_tmp_table_name(old_name); - new_is_tmp = row_is_mysql_tmp_table_name(new_name); + old_is_tmp = dict_table_t::is_temporary_name(old_name); + new_is_tmp = dict_table_t::is_temporary_name(new_name); dict_locked = trx->dict_operation_lock_mode == RW_X_LATCH; From fa147843018ba14136c0a65a2cfcf53af2938958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Apr 2019 19:21:54 +0300 Subject: [PATCH 02/10] Fix more -Wnonnull-compare For some reason, GCC 8 did not issue warnings for all such comparisons. --- storage/innobase/trx/trx0rec.cc | 1 - storage/xtradb/trx/trx0rec.cc | 1 - 2 files changed, 2 deletions(-) diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index c21b5d6772c..f70f8a61388 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -1087,7 +1087,6 @@ trx_undo_rec_get_partial_row( const byte* end_ptr; ulint row_len; - ut_ad(ptr); ut_ad(dict_index_is_clust(index)); row_len = dict_table_get_n_cols(index->table); diff --git a/storage/xtradb/trx/trx0rec.cc b/storage/xtradb/trx/trx0rec.cc index e4a8d1b2d82..351f65bb943 100644 --- a/storage/xtradb/trx/trx0rec.cc +++ b/storage/xtradb/trx/trx0rec.cc @@ -1087,7 +1087,6 @@ trx_undo_rec_get_partial_row( const byte* end_ptr; ulint row_len; - ut_ad(ptr); ut_ad(dict_index_is_clust(index)); row_len = dict_table_get_n_cols(index->table); From 1f3bcff1f2d7ba50fc8e8cb2b608b8eaaec3d583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Apr 2019 19:46:34 +0300 Subject: [PATCH 03/10] Remove unused declarations --- mysys/thr_lock.c | 11 ---------- sql/sql_signal.cc | 14 ------------- sql/wsrep_sst.cc | 2 -- storage/federated/ha_federated.cc | 1 - storage/federated/ha_federated.h | 1 - storage/federatedx/federatedx_io.cc | 2 -- storage/federatedx/ha_federatedx.cc | 1 - storage/federatedx/ha_federatedx.h | 1 - strings/ctype-utf8.c | 31 +---------------------------- 9 files changed, 1 insertion(+), 63 deletions(-) diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 45376f7c5fc..5c3437382a5 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -497,17 +497,6 @@ has_old_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner) return 0; } -static inline my_bool have_specific_lock(THR_LOCK_DATA *data, - enum thr_lock_type type) -{ - for ( ; data ; data=data->next) - { - if (data->type == type) - return 1; - } - return 0; -} - static void wake_up_waiters(THR_LOCK *lock); diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc index 5f4862f173c..1b7edbee54a 100644 --- a/sql/sql_signal.cc +++ b/sql/sql_signal.cc @@ -63,20 +63,6 @@ const LEX_STRING Diag_condition_item_names[]= { C_STRING_WITH_LEN("TRIGGER_SCHEMA") } }; -const LEX_STRING Diag_statement_item_names[]= -{ - { C_STRING_WITH_LEN("NUMBER") }, - { C_STRING_WITH_LEN("MORE") }, - { C_STRING_WITH_LEN("COMMAND_FUNCTION") }, - { C_STRING_WITH_LEN("COMMAND_FUNCTION_CODE") }, - { C_STRING_WITH_LEN("DYNAMIC_FUNCTION") }, - { C_STRING_WITH_LEN("DYNAMIC_FUNCTION_CODE") }, - { C_STRING_WITH_LEN("ROW_COUNT") }, - { C_STRING_WITH_LEN("TRANSACTIONS_COMMITTED") }, - { C_STRING_WITH_LEN("TRANSACTIONS_ROLLED_BACK") }, - { C_STRING_WITH_LEN("TRANSACTION_ACTIVE") } -}; - Set_signal_information::Set_signal_information( const Set_signal_information& set) diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index addbfeb99f6..a54b96a4aa2 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -184,8 +184,6 @@ bool wsrep_sst_donor_update (sys_var *self, THD* thd, enum_var_type type) return 0; } -static wsrep_uuid_t cluster_uuid = WSREP_UUID_UNDEFINED; - bool wsrep_before_SE() { return (wsrep_provider != NULL diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index d234aa03eda..a0b2cb1ab3a 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -408,7 +408,6 @@ static const int bulk_padding= 64; // bytes "overhead" in packet /* Variables used when chopping off trailing characters */ static const uint sizeof_trailing_comma= sizeof(", ") - 1; -static const uint sizeof_trailing_closeparen= sizeof(") ") - 1; static const uint sizeof_trailing_and= sizeof(" AND ") - 1; static const uint sizeof_trailing_where= sizeof(" WHERE ") - 1; diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h index a23375cbe58..78f959634da 100644 --- a/storage/federated/ha_federated.h +++ b/storage/federated/ha_federated.h @@ -89,7 +89,6 @@ class ha_federated: public handler */ DYNAMIC_ARRAY results; bool position_called, table_will_be_deleted; - uint fetch_num; // stores the fetch num MYSQL_ROW_OFFSET current_position; // Current position used by ::position() int remote_error_number; char remote_error_buf[FEDERATED_QUERY_BUFFER_SIZE]; diff --git a/storage/federatedx/federatedx_io.cc b/storage/federatedx/federatedx_io.cc index 1e0348e3bf8..5baec617cda 100644 --- a/storage/federatedx/federatedx_io.cc +++ b/storage/federatedx/federatedx_io.cc @@ -54,8 +54,6 @@ static const io_schemes_st federated_io_schemes[] = { "null", instantiate_io_null } /* must be last element */ }; -const uint federated_io_schemes_count= array_elements(federated_io_schemes); - federatedx_io::federatedx_io(FEDERATEDX_SERVER *aserver) : server(aserver), owner_ptr(0), txn_next(0), idle_next(0), active(FALSE), busy(FALSE), readonly(TRUE) diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index 50be6575a83..0c3d39c1ab5 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -337,7 +337,6 @@ static const int bulk_padding= 64; // bytes "overhead" in packet /* Variables used when chopping off trailing characters */ static const uint sizeof_trailing_comma= sizeof(", ") - 1; -static const uint sizeof_trailing_closeparen= sizeof(") ") - 1; static const uint sizeof_trailing_and= sizeof(" AND ") - 1; static const uint sizeof_trailing_where= sizeof(" WHERE ") - 1; diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h index f3af7258623..56c34d9ef37 100644 --- a/storage/federatedx/ha_federatedx.h +++ b/storage/federatedx/ha_federatedx.h @@ -270,7 +270,6 @@ class ha_federatedx: public handler */ DYNAMIC_ARRAY results; bool position_called; - uint fetch_num; // stores the fetch num int remote_error_number; char remote_error_buf[FEDERATEDX_QUERY_BUFFER_SIZE]; bool ignore_duplicates, replace_duplicates; diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index efd862f5a1c..e2e3d96386e 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, MariaDB + Copyright (c) 2009, 2019, MariaDB This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -4887,16 +4887,6 @@ static const uchar to_upper_utf8[] = { 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 }; -static inline int bincmp(const uchar *s, const uchar *se, - const uchar *t, const uchar *te) -{ - int slen= (int) (se-s), tlen= (int) (te-t); - int len=MY_MIN(slen,tlen); - int cmp= memcmp(s,t,len); - return cmp ? cmp : slen-tlen; -} - - static int my_utf8_uni(CHARSET_INFO *cs __attribute__((unused)), my_wc_t * pwc, const uchar *s, const uchar *e) { @@ -5059,14 +5049,6 @@ my_toupper_utf8mb3(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) } -static inline void -my_tosort_utf8mb3(MY_UNICASE_INFO *uni_plane, my_wc_t *wc) -{ - MY_UNICASE_CHARACTER *page; - if ((page= uni_plane->page[(*wc >> 8) & 0xFF])) - *wc= page[*wc & 0xFF].sort; -} - static size_t my_caseup_utf8(CHARSET_INFO *cs, const char *src, size_t srclen, char *dst, size_t dstlen) { @@ -7306,17 +7288,6 @@ static uchar to_upper_utf8mb4[]= }; -static inline int -bincmp_utf8mb4(const uchar *s, const uchar *se, - const uchar *t, const uchar *te) -{ - int slen= (int) (se - s), tlen= (int) (te - t); - int len= MY_MIN(slen, tlen); - int cmp= memcmp(s, t, len); - return cmp ? cmp : slen - tlen; -} - - static int my_mb_wc_utf8mb4(CHARSET_INFO *cs __attribute__((unused)), my_wc_t * pwc, const uchar *s, const uchar *e) From 6a9b2163011938d813ebe4edf9264a0e35b1c6bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Apr 2019 19:50:51 +0300 Subject: [PATCH 04/10] Fix clang -Wunused-private-field --- sql/item_func.h | 1 - sql/sql_class.h | 1 - sql/sql_load.cc | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/sql/item_func.h b/sql/item_func.h index c387c56f3b4..9700429d543 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1737,7 +1737,6 @@ class Item_func_set_user_var :public Item_func_user_var user variable it the first connection context). */ my_thread_id entry_thread_id; - char buffer[MAX_FIELD_WIDTH]; String value; my_decimal decimal_buff; bool null_item; diff --git a/sql/sql_class.h b/sql/sql_class.h index de52cec0f38..6640e02147a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -4565,7 +4565,6 @@ class select_insert :public select_result_interceptor { class select_create: public select_insert { - ORDER *group; TABLE_LIST *create_table; Table_specification_st *create_info; TABLE_LIST *select_tables; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index d75d911815a..85ab43df0ec 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -68,15 +68,13 @@ class READ_INFO { File file; uchar *buffer, /* Buffer for read text */ *end_of_buff; /* Data in bufferts ends here */ - uint buff_length, /* Length of buffert */ - max_length; /* Max length of row */ + uint buff_length; /* Length of buffert */ const uchar *field_term_ptr,*line_term_ptr; const char *line_start_ptr,*line_start_end; uint field_term_length,line_term_length,enclosed_length; int field_term_char,line_term_char,enclosed_char,escape_char; int *stack,*stack_pos; bool found_end_of_line,start_of_line,eof; - NET *io_net; int level; /* for load xml */ From 7984ea80de75fa626e8c2f947aee828bdef1771f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Apr 2019 17:10:54 +0300 Subject: [PATCH 05/10] Remove a useless CHECK TABLE printout for debug builds --- storage/innobase/btr/btr0btr.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index a40e39624e2..d143f98dda1 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -4908,13 +4908,6 @@ btr_validate_level( block = btr_root_block_get(index, RW_SX_LATCH, &mtr); page = buf_block_get_frame(block); -#ifdef UNIV_DEBUG - if (dict_index_is_spatial(index)) { - fprintf(stderr, "Root page no: %lu\n", - (ulong) page_get_page_no(page)); - } -#endif - fil_space_t* space = fil_space_get(index->space); const page_size_t table_page_size( dict_table_page_size(index->table)); From cad56fbabaea7b5dab0ccfbabb98d0a9c61f3dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Apr 2019 16:10:20 +0300 Subject: [PATCH 06/10] MDEV-18733 MariaDB slow start after crash recovery If InnoDB crash recovery was needed, the InnoDB function srv_start() would invoke extra validation, reading something from every InnoDB data file. This should be unnecessary now that MDEV-14717 made RENAME operations crash-safe inside InnoDB (which can be disabled in MariaDB 10.2 by setting innodb_safe_truncate=OFF). dict_check_sys_tables(): Skip tables that would be dropped by row_mysql_drop_garbage_tables(). Perform extra validation only if innodb_safe_truncate=OFF, innodb_force_recovery=0 and crash recovery was needed. dict_load_table_one(): Validate the root page of the table. In this way, we can deny access to corrupted or mismatching tables not only after crash recovery, but also after a clean shutdown. --- .../encryption/r/innodb-bad-key-change.result | 31 ++++---- .../r/innodb-bad-key-change2.result | 37 +++++----- .../r/innodb-bad-key-change4.result | 12 ++-- .../r/innodb-compressed-blob.result | 5 +- .../r/innodb-encryption-disable.result | 5 +- .../encryption/r/innodb-force-corrupt.result | 5 +- .../encryption/r/innodb-missing-key.result | 7 +- .../encryption/t/innodb-bad-key-change.test | 22 +++--- .../encryption/t/innodb-bad-key-change2.test | 28 ++++---- .../encryption/t/innodb-bad-key-change4.test | 1 + .../encryption/t/innodb-compressed-blob.test | 5 +- .../t/innodb-encryption-disable.test | 5 +- .../encryption/t/innodb-force-corrupt.test | 5 +- .../encryption/t/innodb-missing-key.test | 7 +- mysql-test/suite/innodb/r/alter_kill.result | 30 ++------ mysql-test/suite/innodb/t/alter_kill.test | 72 +++++++++---------- storage/innobase/buf/buf0buf.cc | 4 +- storage/innobase/dict/dict0load.cc | 57 +++++++++++---- storage/innobase/include/dict0load.h | 9 +-- storage/innobase/srv/srv0start.cc | 15 +--- 20 files changed, 179 insertions(+), 183 deletions(-) diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change.result b/mysql-test/suite/encryption/r/innodb-bad-key-change.result index 51dcc5166ec..7d6d2000cb7 100644 --- a/mysql-test/suite/encryption/r/innodb-bad-key-change.result +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change.result @@ -3,6 +3,7 @@ call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[12]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted; key_version=1"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found"); # Start server with keys2.txt SET GLOBAL innodb_file_per_table = ON; @@ -27,7 +28,7 @@ foobar 2 # Restart server with keysbad3.txt SELECT * FROM t1; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t1' doesn't exist in engine DROP TABLE t1; # Start server with keys3.txt SET GLOBAL innodb_default_encryption_key_id=5; @@ -36,33 +37,31 @@ INSERT INTO t2 VALUES ('foobar',1,2); # Restart server with keys2.txt SELECT * FROM t2; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t2' doesn't exist in engine SELECT * FROM t2 where id = 1; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t2' doesn't exist in engine SELECT * FROM t2 where b = 1; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t2' doesn't exist in engine INSERT INTO t2 VALUES ('tmp',3,3); -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t2' doesn't exist in engine DELETE FROM t2 where b = 3; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t2' doesn't exist in engine DELETE FROM t2 where id = 3; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t2' doesn't exist in engine UPDATE t2 set b = b +1; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t2' doesn't exist in engine OPTIMIZE TABLE t2; Table Op Msg_type Msg_text -test.t2 optimize Warning Table t2 in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table. -test.t2 optimize Error Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB -test.t2 optimize error Corrupt +test.t2 optimize Error Table 'test.t2' doesn't exist in engine +test.t2 optimize status Operation failed ALTER TABLE t2 ADD COLUMN d INT; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t2' doesn't exist in engine ANALYZE TABLE t2; Table Op Msg_type Msg_text -test.t2 analyze Warning Table t2 in file ./test/t2.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table. -test.t2 analyze Error Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB -test.t2 analyze error Corrupt +test.t2 analyze Error Table 'test.t2' doesn't exist in engine +test.t2 analyze status Operation failed TRUNCATE TABLE t2; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t2' doesn't exist in engine DROP TABLE t2; # Start server with keys2.txt diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result index bd765671a0f..e181a4ee5e1 100644 --- a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result @@ -2,48 +2,42 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page n call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as discarded\\."); +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); SET GLOBAL innodb_file_per_table = ON; CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); SELECT * FROM t1; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t1' doesn't exist in engine SHOW WARNINGS; Level Code Message -Warning 192 Table test/t1 in tablespace is encrypted but encryption service or used key_id is not available. Can't continue reading table. -Warning 192 Table t1 in file ./test/t1.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table. -Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +Error 1932 Table 'test.t1' doesn't exist in engine ALTER TABLE t1 ENGINE=InnoDB; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t1' doesn't exist in engine SHOW WARNINGS; Level Code Message -Warning 192 Table t1 in file ./test/t1.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table. -Error 1296 Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +Error 1932 Table 'test.t1' doesn't exist in engine OPTIMIZE TABLE t1; Table Op Msg_type Msg_text -test.t1 optimize Warning Table t1 in file ./test/t1.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table. -test.t1 optimize Error Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB -test.t1 optimize error Corrupt +test.t1 optimize Error Table 'test.t1' doesn't exist in engine +test.t1 optimize status Operation failed SHOW WARNINGS; Level Code Message CHECK TABLE t1; Table Op Msg_type Msg_text -test.t1 check Warning Table t1 in file ./test/t1.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table. -test.t1 check Error Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB -test.t1 check error Corrupt +test.t1 check Error Table 'test.t1' doesn't exist in engine +test.t1 check status Operation failed SHOW WARNINGS; Level Code Message FLUSH TABLES t1 FOR EXPORT; backup: t1 UNLOCK TABLES; ALTER TABLE t1 DISCARD TABLESPACE; -Warnings: -Warning 192 Table test/t1 in tablespace is encrypted but encryption service or used key_id is not available. Can't continue reading table. -Warning 1812 Tablespace is missing for table 'test/t1' +ERROR 42S02: Table 'test.t1' doesn't exist in engine +restore: t1 .ibd and .cfg files +ALTER TABLE t1 DISCARD TABLESPACE; restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; -Warnings: -Warning 1814 Tablespace has been discarded for table `t1` SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -52,6 +46,7 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`pk`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 `ENCRYPTED`=YES `ENCRYPTION_KEY_ID`=4 RENAME TABLE t1 TO t1new; -ALTER TABLE t1new RENAME TO t2new; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB -DROP TABLE t1new; +ERROR HY000: Error on rename of './test/t1' to './test/t1new' (errno: 155 "The table does not exist in the storage engine") +ALTER TABLE t1 RENAME TO t1new; +ERROR 42S02: Table 'test.t1' doesn't exist in engine +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change4.result b/mysql-test/suite/encryption/r/innodb-bad-key-change4.result index 001720be9c6..a535e591773 100644 --- a/mysql-test/suite/encryption/r/innodb-bad-key-change4.result +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change4.result @@ -1,23 +1,21 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t1\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); SET GLOBAL innodb_file_per_table = ON; CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); OPTIMIZE TABLE t1; Table Op Msg_type Msg_text -test.t1 optimize Warning Table test/t1 in tablespace is encrypted but encryption service or used key_id is not available. Can't continue reading table. -test.t1 optimize Warning Table t1 in file ./test/t1.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table. -test.t1 optimize Error Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB -test.t1 optimize error Corrupt +test.t1 optimize Error Table 'test.t1' doesn't exist in engine +test.t1 optimize status Operation failed SHOW WARNINGS; Level Code Message CHECK TABLE t1; Table Op Msg_type Msg_text -test.t1 check Warning Table t1 in file ./test/t1.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table. -test.t1 check Error Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB -test.t1 check error Corrupt +test.t1 check Error Table 'test.t1' doesn't exist in engine +test.t1 check status Operation failed SHOW WARNINGS; Level Code Message DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/innodb-compressed-blob.result b/mysql-test/suite/encryption/r/innodb-compressed-blob.result index f163f6141dd..ef49c9a6541 100644 --- a/mysql-test/suite/encryption/r/innodb-compressed-blob.result +++ b/mysql-test/suite/encryption/r/innodb-compressed-blob.result @@ -1,6 +1,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("InnoDB: Unable to decompress ..test.t[1-3]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); # Restart mysqld --file-key-management-filename=keys2.txt SET GLOBAL innodb_file_per_table = ON; set GLOBAL innodb_default_encryption_key_id=4; @@ -14,9 +15,9 @@ insert into t2 values (1, repeat('secret',6000)); insert into t3 values (1, repeat('secret',6000)); # Restart mysqld --file-key-management-filename=keys3.txt select count(*) from t1 FORCE INDEX (b) where b like 'secret%'; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t1' doesn't exist in engine select count(*) from t2 FORCE INDEX (b) where b like 'secret%'; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t2' doesn't exist in engine select count(*) from t3 FORCE INDEX (b) where b like 'secret%'; count(*) 1 diff --git a/mysql-test/suite/encryption/r/innodb-encryption-disable.result b/mysql-test/suite/encryption/r/innodb-encryption-disable.result index 3b3d6712817..e6ec74e22d4 100644 --- a/mysql-test/suite/encryption/r/innodb-encryption-disable.result +++ b/mysql-test/suite/encryption/r/innodb-encryption-disable.result @@ -1,6 +1,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[15]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[15].ibd looks corrupted; key_version=1"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` is corrupted"); call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); create table t5 ( `intcol1` int(32) DEFAULT NULL, @@ -20,8 +21,8 @@ CREATE TABLE `t1` ( insert into t1 values (1,2,'maria','db','encryption'); alter table t1 encrypted='yes' `encryption_key_id`=1; select * from t1; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t1' doesn't exist in engine select * from t5; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t5' doesn't exist in engine drop table t1; drop table t5; diff --git a/mysql-test/suite/encryption/r/innodb-force-corrupt.result b/mysql-test/suite/encryption/r/innodb-force-corrupt.result index 6216142d112..b525eba38a3 100644 --- a/mysql-test/suite/encryption/r/innodb-force-corrupt.result +++ b/mysql-test/suite/encryption/r/innodb-force-corrupt.result @@ -1,4 +1,5 @@ call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version=3221342974"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` is corrupted"); SET GLOBAL innodb_file_per_table = ON; set global innodb_compression_algorithm = 1; # Create and populate tables to be corrupted @@ -14,10 +15,10 @@ COMMIT; # Backup tables before corrupting # Corrupt tables SELECT * FROM t1; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t1' doesn't exist in engine SELECT * FROM t2; ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB SELECT * FROM t3; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t3' doesn't exist in engine # Restore the original tables DROP TABLE t1,t2,t3; diff --git a/mysql-test/suite/encryption/r/innodb-missing-key.result b/mysql-test/suite/encryption/r/innodb-missing-key.result index 631eeea9ee8..302bd28ee02 100644 --- a/mysql-test/suite/encryption/r/innodb-missing-key.result +++ b/mysql-test/suite/encryption/r/innodb-missing-key.result @@ -1,6 +1,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file .*test.t[12].ibd looks corrupted; key_version=1"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); # Start server with keys2.txt CREATE TABLE t1(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=19; CREATE TABLE t2(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=1; @@ -34,11 +35,11 @@ SELECT COUNT(1) FROM t2; COUNT(1) 2048 SELECT COUNT(1) FROM t2,t1 where t2.a = t1.a; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t1' doesn't exist in engine SELECT COUNT(1) FROM t1 where b = 'ab'; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t1' doesn't exist in engine SELECT COUNT(1) FROM t1; -ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +ERROR 42S02: Table 'test.t1' doesn't exist in engine # Start server with keys2.txt SELECT COUNT(1) FROM t1; diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.test b/mysql-test/suite/encryption/t/innodb-bad-key-change.test index a7df715445a..a8222e6411e 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change.test +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.test @@ -13,6 +13,7 @@ call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[12]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted; key_version=1"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found"); --echo # Start server with keys2.txt @@ -39,7 +40,7 @@ SELECT * FROM t1; -- source include/restart_mysqld.inc --disable_warnings ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t1; --enable_warnings @@ -70,36 +71,35 @@ INSERT INTO t2 VALUES ('foobar',1,2); -- source include/restart_mysqld.inc --disable_warnings ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t2; ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t2 where id = 1; ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t2 where b = 1; ---replace_regex /tablespace [0-9]*/tablespace / ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE INSERT INTO t2 VALUES ('tmp',3,3); ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE DELETE FROM t2 where b = 3; ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE DELETE FROM t2 where id = 3; ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE UPDATE t2 set b = b +1; OPTIMIZE TABLE t2; ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE ALTER TABLE t2 ADD COLUMN d INT; ANALYZE TABLE t2; ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE TRUNCATE TABLE t2; DROP TABLE t2; diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change2.test b/mysql-test/suite/encryption/t/innodb-bad-key-change2.test index 1b742882765..07400872f4a 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change2.test +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change2.test @@ -13,6 +13,7 @@ call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9] # Suppression for builds where file_key_management plugin is linked statically call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as discarded\\."); +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); --let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt --source include/restart_mysqld.inc @@ -26,11 +27,11 @@ INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); --let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt --source include/restart_mysqld.inc ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t1; --replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 / SHOW WARNINGS; ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE ALTER TABLE t1 ENGINE=InnoDB; --replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 / SHOW WARNINGS; @@ -57,8 +58,7 @@ UNLOCK TABLES; --let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt --source include/restart_mysqld.inc -# Discard should pass even with incorrect keys ---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 / +--error ER_NO_SUCH_TABLE_IN_ENGINE ALTER TABLE t1 DISCARD TABLESPACE; perl; @@ -71,19 +71,23 @@ EOF --let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt --source include/restart_mysqld.inc +ALTER TABLE t1 DISCARD TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + ALTER TABLE t1 IMPORT TABLESPACE; SHOW CREATE TABLE t1; --let $restart_parameters= --innodb-encrypt-tables --plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt --source include/restart_mysqld.inc -# Rename table should pass even with incorrect keys +--error ER_ERROR_ON_RENAME RENAME TABLE t1 TO t1new; ---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 / - -# Alter table rename is not allowed with incorrect keys ---error ER_GET_ERRMSG -ALTER TABLE t1new RENAME TO t2new; +--error ER_NO_SUCH_TABLE_IN_ENGINE +ALTER TABLE t1 RENAME TO t1new; # Drop should pass even with incorrect keys ---replace_regex /(tablespace|key_id) [1-9][0-9]*/\1 / -DROP TABLE t1new; +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change4.test b/mysql-test/suite/encryption/t/innodb-bad-key-change4.test index 982c57d90f0..404e5b50426 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change4.test +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change4.test @@ -11,6 +11,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page n call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); # Suppression for builds where file_key_management plugin is linked statically call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); --let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt --source include/restart_mysqld.inc diff --git a/mysql-test/suite/encryption/t/innodb-compressed-blob.test b/mysql-test/suite/encryption/t/innodb-compressed-blob.test index 695864db123..261fdd73aa1 100644 --- a/mysql-test/suite/encryption/t/innodb-compressed-blob.test +++ b/mysql-test/suite/encryption/t/innodb-compressed-blob.test @@ -7,6 +7,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("InnoDB: Unable to decompress ..test.t[1-3]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); --echo # Restart mysqld --file-key-management-filename=keys2.txt -- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt @@ -27,9 +28,9 @@ insert into t3 values (1, repeat('secret',6000)); -- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt -- source include/restart_mysqld.inc ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE select count(*) from t1 FORCE INDEX (b) where b like 'secret%'; ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE select count(*) from t2 FORCE INDEX (b) where b like 'secret%'; select count(*) from t3 FORCE INDEX (b) where b like 'secret%'; diff --git a/mysql-test/suite/encryption/t/innodb-encryption-disable.test b/mysql-test/suite/encryption/t/innodb-encryption-disable.test index 8d870376d99..26ceea9e986 100644 --- a/mysql-test/suite/encryption/t/innodb-encryption-disable.test +++ b/mysql-test/suite/encryption/t/innodb-encryption-disable.test @@ -10,6 +10,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[15]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[15].ibd looks corrupted; key_version=1"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` is corrupted"); # Suppression for builds where file_key_management plugin is linked statically call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); @@ -41,9 +42,9 @@ alter table t1 encrypted='yes' `encryption_key_id`=1; --let $restart_parameters=--innodb-encrypt-tables=OFF --source include/restart_mysqld.inc ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE select * from t1; ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE select * from t5; --let $restart_parameters=--innodb-encrypt-tables=ON --plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt diff --git a/mysql-test/suite/encryption/t/innodb-force-corrupt.test b/mysql-test/suite/encryption/t/innodb-force-corrupt.test index a573be56d62..4bed3e75997 100644 --- a/mysql-test/suite/encryption/t/innodb-force-corrupt.test +++ b/mysql-test/suite/encryption/t/innodb-force-corrupt.test @@ -8,6 +8,7 @@ -- source include/not_embedded.inc call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version=3221342974"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` is corrupted"); SET GLOBAL innodb_file_per_table = ON; set global innodb_compression_algorithm = 1; @@ -65,11 +66,11 @@ EOF --source include/start_mysqld.inc ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t1; --error ER_GET_ERRMSG SELECT * FROM t2; ---error ER_GET_ERRMSG +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT * FROM t3; --source include/shutdown_mysqld.inc diff --git a/mysql-test/suite/encryption/t/innodb-missing-key.test b/mysql-test/suite/encryption/t/innodb-missing-key.test index c101ff97358..f86640b617c 100644 --- a/mysql-test/suite/encryption/t/innodb-missing-key.test +++ b/mysql-test/suite/encryption/t/innodb-missing-key.test @@ -10,6 +10,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\."); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file .*test.t[12].ibd looks corrupted; key_version=1"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); --echo # Start server with keys2.txt -- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt @@ -44,11 +45,11 @@ CREATE TABLE t4(a int not null primary key auto_increment, b varchar(128)) engin SELECT SLEEP(5); SELECT COUNT(1) FROM t3; SELECT COUNT(1) FROM t2; ---error 1296 +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT COUNT(1) FROM t2,t1 where t2.a = t1.a; ---error 1296 +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT COUNT(1) FROM t1 where b = 'ab'; ---error 1296 +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT COUNT(1) FROM t1; --echo diff --git a/mysql-test/suite/innodb/r/alter_kill.result b/mysql-test/suite/innodb/r/alter_kill.result index 9b24fddf9ef..f0f5b1c003f 100644 --- a/mysql-test/suite/innodb/r/alter_kill.result +++ b/mysql-test/suite/innodb/r/alter_kill.result @@ -10,39 +10,19 @@ connection default; # Cleanly shutdown mysqld disconnect con1; # Corrupt FIL_PAGE_OFFSET in bug16720368.ibd, -# and update the checksum to the "don't care" value. +# and recompute innodb_checksum_algorithm=crc32 # Restart mysqld -# This will succeed after a clean shutdown, due to -# fil_open_single_table_tablespace(check_space_id=FALSE). SELECT COUNT(*) FROM bug16720368; -COUNT(*) -8 +ERROR 42S02: Table 'test.bug16720368' doesn't exist in engine +INSERT INTO bug16720368 VALUES(1); +ERROR 42S02: Table 'test.bug16720368' doesn't exist in engine INSERT INTO bug16720368_1 VALUES(1); -# The table is unaccessible, because after a crash we will -# validate the tablespace header. -SELECT COUNT(*) FROM bug16720368; -ERROR 42S02: Table 'test.bug16720368' doesn't exist in engine -INSERT INTO bug16720368 VALUES(0,1); -ERROR 42S02: Table 'test.bug16720368' doesn't exist in engine -# The table is readable thanks to innodb-force-recovery. -SELECT COUNT(*) FROM bug16720368; -COUNT(*) -8 -INSERT INTO bug16720368 VALUES(0,1); -# Shut down the server cleanly to hide the corruption. -# The table is accessible, because after a clean shutdown we will -# NOT validate the tablespace header. -# We can modify the existing pages, but we cannot allocate or free -# any pages, because that would hit the corruption on page 0. -SELECT COUNT(*) FROM bug16720368; -COUNT(*) -9 # Shut down the server to uncorrupt the data. # Restart the server after uncorrupting the file. INSERT INTO bug16720368 VALUES(9,1); SELECT COUNT(*) FROM bug16720368; COUNT(*) -10 +9 DROP TABLE bug16720368, bug16720368_1; # # Bug#16735660 ASSERT TABLE2 == NULL, ROLLBACK OF RESURRECTED TXNS, diff --git a/mysql-test/suite/innodb/t/alter_kill.test b/mysql-test/suite/innodb/t/alter_kill.test index e0d785e412a..aec1c5f92b2 100644 --- a/mysql-test/suite/innodb/t/alter_kill.test +++ b/mysql-test/suite/innodb/t/alter_kill.test @@ -18,6 +18,7 @@ call mtr.add_suppression("InnoDB: Set innodb_force_recovery=1 to ignore this and call mtr.add_suppression("InnoDB: Plugin initialization aborted*"); call mtr.add_suppression("Plugin 'InnoDB' init function returned error."); call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); +call mtr.add_suppression("InnoDB: Table `test`\\.`bug16720368` is corrupted"); -- enable_query_log -- echo # @@ -40,67 +41,62 @@ connection default; disconnect con1; -- echo # Corrupt FIL_PAGE_OFFSET in bug16720368.ibd, --- echo # and update the checksum to the "don't care" value. +-- echo # and recompute innodb_checksum_algorithm=crc32 perl; +do "$ENV{MTR_SUITE_DIR}/include/crc32.pl"; my $file = "$ENV{MYSQLD_DATADIR}/test/bug16720368.ibd"; open(FILE, "+<$file") || die "Unable to open $file"; -print FILE pack("H*","deadbeefc001cafe") || die "Unable to write $file"; -seek(FILE, $ENV{PAGE_SIZE}-8, 0) || die "Unable to seek $file"; -print FILE pack("H*","deadbeef") || die "Unable to write $file"; +binmode FILE; +my $ps= $ENV{PAGE_SIZE}; +my $page; +sysseek(FILE, 3*$ps, 0) || die "Unable to seek $file\n"; +die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; +substr($page,4,4)=pack("N",0xc001cafe); +my $polynomial = 0x82f63b78; # CRC-32C +my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^ + mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial)); +substr($page,0,4)=$ck; +substr($page,$ps-8,4)=$ck; +sysseek(FILE, 3*$ps, 0) || die "Unable to rewind $file\n"; +syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n"; close(FILE) || die "Unable to close $file"; EOF -- echo # Restart mysqld -- source include/start_mysqld.inc --- echo # This will succeed after a clean shutdown, due to --- echo # fil_open_single_table_tablespace(check_space_id=FALSE). +--error ER_NO_SUCH_TABLE_IN_ENGINE SELECT COUNT(*) FROM bug16720368; - +--error ER_NO_SUCH_TABLE_IN_ENGINE +INSERT INTO bug16720368 VALUES(1); INSERT INTO bug16720368_1 VALUES(1); ---let $shutdown_timeout= 0 ---source include/restart_mysqld.inc - --- echo # The table is unaccessible, because after a crash we will --- echo # validate the tablespace header. ---error ER_NO_SUCH_TABLE_IN_ENGINE -SELECT COUNT(*) FROM bug16720368; ---error ER_NO_SUCH_TABLE_IN_ENGINE -INSERT INTO bug16720368 VALUES(0,1); - -let $restart_parameters = --innodb-force-recovery=3; ---let $shutdown_timeout= 0 ---source include/restart_mysqld.inc - --- echo # The table is readable thanks to innodb-force-recovery. -SELECT COUNT(*) FROM bug16720368; -INSERT INTO bug16720368 VALUES(0,1); - --- echo # Shut down the server cleanly to hide the corruption. -let $shutdown_timeout=; -let $restart_parameters =; --- source include/restart_mysqld.inc - --- echo # The table is accessible, because after a clean shutdown we will --- echo # NOT validate the tablespace header. --- echo # We can modify the existing pages, but we cannot allocate or free --- echo # any pages, because that would hit the corruption on page 0. -SELECT COUNT(*) FROM bug16720368; - -- echo # Shut down the server to uncorrupt the data. -- source include/shutdown_mysqld.inc # Uncorrupt the FIL_PAGE_OFFSET. perl; +do "$ENV{MTR_SUITE_DIR}/include/crc32.pl"; my $file = "$ENV{MYSQLD_DATADIR}/test/bug16720368.ibd"; open(FILE, "+<$file") || die "Unable to open $file"; -# Uncorrupt FIL_PAGE_OFFSET. -print FILE pack("H*","deadbeef00000000") || die "Unable to write $file"; +binmode FILE; +my $ps= $ENV{PAGE_SIZE}; +my $page; +sysseek(FILE, 3*$ps, 0) || die "Unable to seek $file\n"; +die "Unable to read $file" unless sysread(FILE, $page, $ps) == $ps; +substr($page,4,4)=pack("N",3); +my $polynomial = 0x82f63b78; # CRC-32C +my $ck= pack("N",mycrc32(substr($page, 4, 22), 0, $polynomial) ^ + mycrc32(substr($page, 38, $ps - 38 - 8), 0, $polynomial)); +substr($page,0,4)=$ck; +substr($page,$ps-8,4)=$ck; +sysseek(FILE, 3*$ps, 0) || die "Unable to rewind $file\n"; +syswrite(FILE, $page, $ps)==$ps || die "Unable to write $file\n"; close(FILE) || die "Unable to close $file"; EOF -- echo # Restart the server after uncorrupting the file. + -- source include/start_mysqld.inc INSERT INTO bug16720368 VALUES(9,1); diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index ca0a52a3e90..9a3ee7de275 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -4622,7 +4622,9 @@ evict_from_pool: buf_pool_mutex_exit(buf_pool); rw_lock_x_unlock(&fix_block->lock); - *err = DB_PAGE_CORRUPTED; + if (err) { + *err = DB_PAGE_CORRUPTED; + } return NULL; } } diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 8b0a0fa1030..304a536505c 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -1360,14 +1360,9 @@ dict_sys_tables_rec_read( /** Load and check each non-predefined tablespace mentioned in SYS_TABLES. Search SYS_TABLES and check each tablespace mentioned that has not already been added to the fil_system. If it is valid, add it to the -file_system list. Perform extra validation on the table if recovery from -the REDO log occurred. -@param[in] validate Whether to do validation on the table. +file_system list. @return the highest space ID found. */ -UNIV_INLINE -ulint -dict_check_sys_tables( - bool validate) +static ulint dict_check_sys_tables() { ulint max_space_id = 0; btr_pcur_t pcur; @@ -1390,6 +1385,10 @@ dict_check_sys_tables( sys_datafiles = dict_table_get_low("SYS_DATAFILES"); ut_a(sys_datafiles != NULL); + const bool validate = recv_needed_recovery + && !srv_safe_truncate + && !srv_force_recovery; + for (rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES); rec != NULL; rec = dict_getnext_system(&pcur, &mtr)) { @@ -1420,15 +1419,23 @@ dict_check_sys_tables( &table_id, &space_id, &n_cols, &flags, &flags2) || space_id == TRX_SYS_SPACE) { +next: ut_free(table_name.m_name); continue; } + if (srv_safe_truncate + && strstr(table_name.m_name, "/" TEMP_FILE_PREFIX "-")) { + /* This table will be dropped by + row_mysql_drop_garbage_tables(). + We do not care if the file exists. */ + goto next; + } + if (flags2 & DICT_TF2_DISCARDED) { ib::info() << "Ignoring tablespace for " << table_name << " because the DISCARD flag is set ."; - ut_free(table_name.m_name); - continue; + goto next; } /* For tables or partitions using .ibd files, the flag @@ -1503,11 +1510,8 @@ space_id information in the data dictionary to what we find in the tablespace file. In addition, more validation will be done if recovery was needed and force_recovery is not set. -We also scan the biggest space id, and store it to fil_system. -@param[in] validate true if recovery was needed */ -void -dict_check_tablespaces_and_store_max_id( - bool validate) +We also scan the biggest space id, and store it to fil_system. */ +void dict_check_tablespaces_and_store_max_id() { mtr_t mtr; @@ -1528,7 +1532,7 @@ dict_check_tablespaces_and_store_max_id( /* Open all tablespaces referenced in SYS_TABLES. This will update SYS_TABLESPACES and SYS_DATAFILES if it finds any file-per-table tablespaces not already there. */ - max_space_id = dict_check_sys_tables(validate); + max_space_id = dict_check_sys_tables(); fil_set_max_space_id_if_bigger(max_space_id); mutex_exit(&dict_sys->mutex); @@ -3063,8 +3067,31 @@ err_exit: if (table->space && !fil_space_get_size(table->space)) { +corrupted: table->corrupted = true; table->file_unreadable = true; + } else { + const page_id_t page_id( + table->space, + dict_table_get_first_index(table) + ->page); + mtr.start(); + buf_block_t* block = buf_page_get( + page_id, + dict_table_page_size(table), + RW_S_LATCH, &mtr); + const bool corrupted = !block + || page_get_space_id(block->frame) + != page_id.space() + || page_get_page_no(block->frame) + != page_id.page_no() + || mach_read_from_2(FIL_PAGE_TYPE + + block->frame) + != FIL_PAGE_INDEX; + mtr.commit(); + if (corrupted) { + goto corrupted; + } } } } else { diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index b35add02d9d..b58f0e72038 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -76,11 +76,8 @@ space_id information in the data dictionary to what we find in the tablespace file. In addition, more validation will be done if recovery was needed and force_recovery is not set. -We also scan the biggest space id, and store it to fil_system. -@param[in] validate true if recovery was needed */ -void -dict_check_tablespaces_and_store_max_id( - bool validate); +We also scan the biggest space id, and store it to fil_system. */ +void dict_check_tablespaces_and_store_max_id(); /********************************************************************//** Finds the first table name in the given database. diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index b12e6a6fb18..5973e635b0f 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -2486,19 +2486,8 @@ files_checked: every table in the InnoDB data dictionary that has an .ibd file. - We also determine the maximum tablespace id used. - - The 'validate' flag indicates that when a tablespace - is opened, we also read the header page and validate - the contents to the data dictionary. This is time - consuming, especially for databases with lots of ibd - files. So only do it after a crash and not forcing - recovery. Open rw transactions at this point is not - a good reason to validate. */ - bool validate = recv_needed_recovery - && srv_force_recovery == 0; - - dict_check_tablespaces_and_store_max_id(validate); + We also determine the maximum tablespace id used. */ + dict_check_tablespaces_and_store_max_id(); } /* Fix-up truncate of table if server crashed while truncate From c676de169241c2e1f3b622ce4f209157f4478f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Apr 2019 21:00:13 +0300 Subject: [PATCH 07/10] Fix the non-debug build --- storage/innobase/include/dict0dict.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 6c1f089ac44..72dc5d26db7 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -879,11 +879,11 @@ dict_table_get_sys_col( ulint sys) /*!< in: DATA_ROW_ID, ... */ MY_ATTRIBUTE((nonnull, warn_unused_result)); #else /* UNIV_DEBUG */ -#define dict_table_get_nth_col(table, pos) &(table)->cols[pos] +#define dict_table_get_nth_col(table, pos) (&(table)->cols[pos]) #define dict_table_get_sys_col(table, sys) \ &(table)->cols[(table)->n_cols + (sys) - DATA_N_SYS_COLS] /* Get nth virtual columns */ -#define dict_table_get_nth_v_col(table, pos) &(table)->v_cols[pos] +#define dict_table_get_nth_v_col(table, pos) (&(table)->v_cols[pos]) #endif /* UNIV_DEBUG */ /********************************************************************//** Gets the given system column number of a table. From b718ec055d41e45cbbca0bb0c9fdf86310ce9e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 3 Apr 2019 21:41:19 +0300 Subject: [PATCH 08/10] MDEV-18836: Adjust a suppression Normally, InnoDB will create temporary table names of the form #sql-ibNNNN, and with innodb_safe_truncate=OFF, #sql-ibNNNN-MMMM. --- mysql-test/include/check-testcase.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test index 4ca53989d06..a21acee624b 100644 --- a/mysql-test/include/check-testcase.test +++ b/mysql-test/include/check-testcase.test @@ -83,7 +83,7 @@ call mtr.check_testcase(); let $datadir=`select @@datadir`; list_files $datadir mysql_upgrade_info; list_files_write_file $datadir.tempfiles.txt $datadir/test #sql*; ---replace_regex /#sql-ib[0-9a-f]+-[0-9a-f]+\.ibd\n// +--replace_regex /#sql-ib[0-9a-f-]+\.ibd\n// cat_file $datadir.tempfiles.txt; remove_file $datadir.tempfiles.txt; list_files $datadir/mysql #sql*; From f6023857765701da780969b2628963738599865c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 4 Apr 2019 08:57:53 +0300 Subject: [PATCH 09/10] Do not pass table_name_t to printf-like functions --- storage/innobase/btr/btr0btr.cc | 2 +- storage/innobase/btr/btr0cur.cc | 12 ++++++------ storage/innobase/handler/ha_innodb.cc | 2 +- storage/innobase/row/row0ins.cc | 2 +- storage/innobase/row/row0mysql.cc | 4 ++-- storage/innobase/row/row0sel.cc | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index d143f98dda1..afd8f678235 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -236,7 +236,7 @@ btr_root_block_get( "Table %s in tablespace %lu is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - index->table->name, space); + index->table->name.m_name, space); } return NULL; diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index f849ebb0546..36165a5b247 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -1254,7 +1254,7 @@ retry_page_get: "Table %s is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - index->table->name); + index->table->name.m_name); index->table->file_unreadable = true; } @@ -1367,7 +1367,7 @@ retry_page_get: "Table %s is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - index->table->name); + index->table->name.m_name); index->table->file_unreadable = true; } @@ -1396,7 +1396,7 @@ retry_page_get: "Table %s is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - index->table->name); + index->table->name.m_name); index->table->file_unreadable = true; } @@ -2294,7 +2294,7 @@ btr_cur_open_at_index_side_func( "Table %s is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - index->table->name); + index->table->name.m_name); index->table->file_unreadable = true; } @@ -2654,7 +2654,7 @@ btr_cur_open_at_rnd_pos_func( "Table %s is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - index->table->name); + index->table->name.m_name); index->table->file_unreadable = true; } @@ -5585,7 +5585,7 @@ btr_estimate_n_rows_in_range_on_level( "Table %s is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - index->table->name); + index->table->name.m_name); index->table->file_unreadable = true; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index f7de3e39259..adcb845c031 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -14701,7 +14701,7 @@ ha_innobase::optimize( push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, err, "InnoDB: Cannot defragment table %s: returned error code %d\n", - m_prebuilt->table->name, err); + m_prebuilt->table->name.m_name, err); if(err == ER_SP_ALREADY_EXISTS) { try_alter = false; diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 2ecc464d414..03665ccdc3c 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -2932,7 +2932,7 @@ row_ins_sec_index_entry_low( "Table %s is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - index->table->name); + index->table->name.m_name); index->table->file_unreadable = true; } goto func_exit; diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 6c3049d0cf3..29fc79a7d3e 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1307,7 +1307,7 @@ row_mysql_get_table_status( "Table %s in tablespace %lu encrypted." "However key management plugin or used key_id is not found or" " used encryption algorithm or method does not match.", - table->name, table->space); + table->name.m_name, table->space); } err = DB_DECRYPTION_FAILED; @@ -1315,7 +1315,7 @@ row_mysql_get_table_status( if (push_warning) { ib_push_warning(trx, DB_CORRUPTION, "Table %s in tablespace %lu corrupted.", - table->name, table->space); + table->name.m_name, table->space); } err = DB_CORRUPTION; diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 4a82a345a1d..6f9e903623c 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4738,7 +4738,7 @@ wait_table_again: "Table %s is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - prebuilt->table->name); + prebuilt->table->name.m_name); index->table->file_unreadable = true; } rec = NULL; From 71a2e6a3c66bc1e84809e0e91ffaef1cadc87642 Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 1 Apr 2019 19:42:26 +0300 Subject: [PATCH 10/10] index_merge_innodb did sometimes give wrong results Fixed by adding more rows to a table Other things: - Speed up index_merge tests 20% by adding begin/commit around loops that generated rows. --- mysql-test/include/index_merge1.inc | 4 ++++ mysql-test/include/index_merge2.inc | 8 ++++++++ mysql-test/include/index_merge_2sweeps.inc | 2 ++ mysql-test/include/index_merge_ror.inc | 8 ++++++++ mysql-test/include/index_merge_ror_cpk.inc | 4 ++-- mysql-test/r/index_merge_innodb.result | 5 +++++ mysql-test/r/index_merge_myisam.result | 3 +++ mysql-test/t/index_merge_innodb.test | 2 ++ 8 files changed, 34 insertions(+), 2 deletions(-) diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc index 88dd4c31910..7880091ac10 100644 --- a/mysql-test/include/index_merge1.inc +++ b/mysql-test/include/index_merge1.inc @@ -37,12 +37,14 @@ insert into t0 values (1),(2),(3),(4),(5),(6),(7),(8); let $1=7; set @d=8; +begin; while ($1) { eval insert into t0 select key1+@d from t0; eval set @d=@d*2; dec $1; } +commit; --enable_query_log alter table t0 add key2 int not null, add index i2(key2); @@ -360,6 +362,7 @@ INSERT INTO t1 VALUES ('foo','bar', 'ZZ'),('fuz','baz', 'ZZ'); --disable_query_log let $1=9; +begin; while ($1) { eval INSERT INTO t1 SELECT * from t1 WHERE cola = 'foo'; @@ -372,6 +375,7 @@ while ($1) eval INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; dec $1; } +commit; --enable_query_log diff --git a/mysql-test/include/index_merge2.inc b/mysql-test/include/index_merge2.inc index 03afa49d323..ae9adac882f 100644 --- a/mysql-test/include/index_merge2.inc +++ b/mysql-test/include/index_merge2.inc @@ -34,11 +34,13 @@ create table t1 --disable_query_log let $1=200; +begin; while ($1) { eval insert into t1 values (200-$1, $1); dec $1; } +commit; --enable_query_log # No primary key @@ -80,11 +82,13 @@ create table t1 ( show warnings; --disable_query_log let $1=30; +begin; while ($1) { eval insert into t1 (key1, key2, filler) values ($1/4, $1/8, 'filler-data'); dec $1; } +commit; --enable_query_log explain select pk from t1 where key1 = 1 and key2 = 1; select pk from t1 where key2 = 1 and key1 = 1; @@ -331,16 +335,20 @@ insert into t1(key1) values (1),(2),(3),(4),(5),(6),(7),(8); let $1=7; set @d=8; +begin; while ($1) { eval insert into t1 (key1) select key1+@d from t1; eval set @d=@d*2; dec $1; } +commit; alter table t1 add index i2(key2); alter table t1 add index i3(key3); update t1 set key2=key1,key3=key1; + +insert into t1 select 10000+key1, 10000+key2,10000+key3 from t1; analyze table t1; # to test the bug, the following must use "sort_union": diff --git a/mysql-test/include/index_merge_2sweeps.inc b/mysql-test/include/index_merge_2sweeps.inc index 3ae7e5b3c09..ef356e12969 100644 --- a/mysql-test/include/index_merge_2sweeps.inc +++ b/mysql-test/include/index_merge_2sweeps.inc @@ -32,12 +32,14 @@ create table t1 ( --disable_query_log +begin; let $1=1000; while ($1) { eval insert into t1 values($1, $1, $1, 'filler-data','filler-data-2'); dec $1; } +commit; --enable_query_log select * from t1 where (key1 >= 2 and key1 <= 10) or (pk >= 4 and pk <=8 ); diff --git a/mysql-test/include/index_merge_ror.inc b/mysql-test/include/index_merge_ror.inc index fdb966e6885..3ec6e342994 100644 --- a/mysql-test/include/index_merge_ror.inc +++ b/mysql-test/include/index_merge_ror.inc @@ -67,18 +67,21 @@ create table t1 create table t0 as select * from t1; --disable_query_log --echo # Printing of many insert into t0 values (....) disabled. +begin; let $cnt=1000; while ($cnt) { eval insert into t0 values (1, 2, 3, 1, 2, 3, 0, 0, 0, 0, 'data1', 'data2', 'data3', 'data4', 'data5', 'data6'); dec $cnt; } +commit; --enable_query_log alter table t1 disable keys; --disable_query_log --echo # Printing of many insert into t1 select .... from t0 disabled. let $1=4; +begin; while ($1) { let $2=4; @@ -94,6 +97,7 @@ while ($1) } dec $1; } +commit; --echo # Printing of many insert into t1 (...) values (....) disabled. # Row retrieval tests @@ -101,6 +105,7 @@ while ($1) # insert enough rows for index intersection to be used for (key1,key2) insert into t1 (key1, key2, key3, key4, filler1) values (100, 100, 100, 100,'key1-key2-key3-key4'); let $cnt=400; +begin; while ($cnt) { eval insert into t1 (key1, key2, key3, key4, filler1) values (100, -1, 100, -1,'key1-key3'); @@ -112,6 +117,7 @@ while ($cnt) eval insert into t1 (key1, key2, key3, key4, filler1) values (-1, 100, -1, 100,'key2-key4'); dec $cnt; } +commit; --enable_query_log alter table t1 enable keys; select count(*) from t1; @@ -249,6 +255,7 @@ create table t2 ( --disable_query_log let $1=8; +begin; while ($1) { eval insert into t2 values (repeat(char($1+64), 8),repeat(char($1+64), 8),'filler1', 'filler2'); @@ -256,6 +263,7 @@ while ($1) } insert into t2 select * from t2; insert into t2 select * from t2; +commit; --enable_query_log # The table row buffer is reused. Fill it with rows that don't match. diff --git a/mysql-test/include/index_merge_ror_cpk.inc b/mysql-test/include/index_merge_ror_cpk.inc index df42745b4fc..0a307aa4fdb 100644 --- a/mysql-test/include/index_merge_ror_cpk.inc +++ b/mysql-test/include/index_merge_ror_cpk.inc @@ -56,14 +56,14 @@ create table t1 ); --disable_query_log -set autocommit=0; +begin; let $1=10000; while ($1) { eval insert into t1 values ($1 div 10,$1 mod 100, $1/100,$1/100, $1/100,$1/100,$1/100,$1/100,$1/100, $1 mod 100, $1/1000,'filler-data-$1','filler2'); dec $1; } -set autocommit=1; +commit; --enable_query_log # Verify that range scan on CPK is ROR diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index b3007408368..7e2a13128bb 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -294,6 +294,7 @@ key3 int not null default 0 ); insert into t1(key1) values (1),(2),(3),(4),(5),(6),(7),(8); set @d=8; +begin; insert into t1 (key1) select key1+@d from t1; set @d=@d*2; insert into t1 (key1) select key1+@d from t1; @@ -308,9 +309,11 @@ insert into t1 (key1) select key1+@d from t1; set @d=@d*2; insert into t1 (key1) select key1+@d from t1; set @d=@d*2; +commit; alter table t1 add index i2(key2); alter table t1 add index i3(key3); update t1 set key2=key1,key3=key1; +insert into t1 select 10000+key1, 10000+key2,10000+key3 from t1; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK @@ -672,6 +675,7 @@ a int, b int, INDEX idx(a)) ENGINE=INNODB; +begin; INSERT INTO t1(a,b) VALUES (11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500), (3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800), @@ -691,6 +695,7 @@ INSERT INTO t1(a,b) SELECT a,b FROM t1; INSERT INTO t1(a,b) SELECT a,b FROM t1; INSERT INTO t1(a,b) SELECT a,b FROM t1; INSERT INTO t1 VALUES (1000000, 0, 0); +commit; SET SESSION sort_buffer_size = 1024*36; set @tmp_optimizer_switch=@@optimizer_switch; set optimizer_switch='derived_merge=off,derived_with_keys=off'; diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index fb795c6941e..c0823d41b14 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -1129,6 +1129,7 @@ key3 int not null default 0 ); insert into t1(key1) values (1),(2),(3),(4),(5),(6),(7),(8); set @d=8; +begin; insert into t1 (key1) select key1+@d from t1; set @d=@d*2; insert into t1 (key1) select key1+@d from t1; @@ -1143,9 +1144,11 @@ insert into t1 (key1) select key1+@d from t1; set @d=@d*2; insert into t1 (key1) select key1+@d from t1; set @d=@d*2; +commit; alter table t1 add index i2(key2); alter table t1 add index i3(key3); update t1 set key2=key1,key3=key1; +insert into t1 select 10000+key1, 10000+key2,10000+key3 from t1; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test index fb56e44b5ae..b7b2e60f20b 100644 --- a/mysql-test/t/index_merge_innodb.test +++ b/mysql-test/t/index_merge_innodb.test @@ -46,6 +46,7 @@ CREATE TABLE t1 ( INDEX idx(a)) ENGINE=INNODB; +begin; INSERT INTO t1(a,b) VALUES (11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500), (3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800), @@ -65,6 +66,7 @@ INSERT INTO t1(a,b) SELECT a,b FROM t1; INSERT INTO t1(a,b) SELECT a,b FROM t1; INSERT INTO t1(a,b) SELECT a,b FROM t1; INSERT INTO t1 VALUES (1000000, 0, 0); +commit; SET SESSION sort_buffer_size = 1024*36; set @tmp_optimizer_switch=@@optimizer_switch;