diff options
24 files changed, 125 insertions, 80 deletions
diff --git a/extra/wolfssl/wolfssl b/extra/wolfssl/wolfssl -Subproject add4a68465bcdad238bcf3e5f2771d8da05e628 +Subproject 723ed009ae5dc68acc14cd7664f93503d64cd51 diff --git a/mysql-test/suite/funcs_1/r/is_triggers.result b/mysql-test/suite/funcs_1/r/is_triggers.result index d29200980a0..c6485e58f44 100644 --- a/mysql-test/suite/funcs_1/r/is_triggers.result +++ b/mysql-test/suite/funcs_1/r/is_triggers.result @@ -110,16 +110,6 @@ ORDER BY trigger_schema, trigger_name; TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION def mtr gs_insert INSERT def mtr global_suppressions 1 NULL BEGIN DECLARE dummy INT; SELECT "" REGEXP NEW.pattern INTO dummy; END ROW BEFORE NULL NULL OLD NEW # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci def mtr ts_insert INSERT def mtr test_suppressions 1 NULL BEGIN DECLARE dummy INT; SELECT "" REGEXP NEW.pattern INTO dummy; END ROW BEFORE NULL NULL OLD NEW # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -def sys sys_config_insert_set_user INSERT def sys sys_config 1 NULL BEGIN - IF @sys.ignore_sys_config_triggers != true AND NEW.set_by IS NULL THEN - SET NEW.set_by = USER(); - END IF; -END ROW BEFORE NULL NULL OLD NEW # root@localhost utf8mb3 utf8mb3_general_ci utf8mb3_general_ci -def sys sys_config_update_set_user UPDATE def sys sys_config 1 NULL BEGIN - IF @sys.ignore_sys_config_triggers != true AND NEW.set_by IS NULL THEN - SET NEW.set_by = USER(); - END IF; -END ROW BEFORE NULL NULL OLD NEW # root@localhost utf8mb3 utf8mb3_general_ci utf8mb3_general_ci ################################################################################## # Testcase 3.2.18.2 + 3.2.18.3: INFORMATION_SCHEMA.TRIGGERS accessible information ################################################################################## diff --git a/mysql-test/suite/funcs_1/r/is_triggers_embedded.result b/mysql-test/suite/funcs_1/r/is_triggers_embedded.result index 248738da4e2..5a681db49b6 100644 --- a/mysql-test/suite/funcs_1/r/is_triggers_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_triggers_embedded.result @@ -110,16 +110,6 @@ ORDER BY trigger_schema, trigger_name; TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION def mtr gs_insert INSERT def mtr global_suppressions 1 NULL BEGIN DECLARE dummy INT; SELECT "" REGEXP NEW.pattern INTO dummy; END ROW BEFORE NULL NULL OLD NEW # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci def mtr ts_insert INSERT def mtr test_suppressions 1 NULL BEGIN DECLARE dummy INT; SELECT "" REGEXP NEW.pattern INTO dummy; END ROW BEFORE NULL NULL OLD NEW # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -def sys sys_config_insert_set_user INSERT def sys sys_config 1 NULL BEGIN - IF @sys.ignore_sys_config_triggers != true AND NEW.set_by IS NULL THEN - SET NEW.set_by = USER(); - END IF; -END ROW BEFORE NULL NULL OLD NEW # root@localhost utf8mb3 utf8mb3_general_ci utf8mb3_general_ci -def sys sys_config_update_set_user UPDATE def sys sys_config 1 NULL BEGIN - IF @sys.ignore_sys_config_triggers != true AND NEW.set_by IS NULL THEN - SET NEW.set_by = USER(); - END IF; -END ROW BEFORE NULL NULL OLD NEW # root@localhost utf8mb3 utf8mb3_general_ci utf8mb3_general_ci ################################################################################## # Testcase 3.2.18.2 + 3.2.18.3: INFORMATION_SCHEMA.TRIGGERS accessible information ################################################################################## diff --git a/mysql-test/suite/innodb/r/alter_crash.result b/mysql-test/suite/innodb/r/alter_crash.result index 7572c911581..46ea85d3e1e 100644 --- a/mysql-test/suite/innodb/r/alter_crash.result +++ b/mysql-test/suite/innodb/r/alter_crash.result @@ -189,3 +189,36 @@ disconnect con1; DROP TABLE t1; SET DEBUG_SYNC = 'RESET'; SET SQL_MODE=DEFAULT; +# +# MDEV-26936 Recovery crash on rolling back DELETE FROM SYS_INDEXES +# +CREATE TABLE t1(a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1,1); +connect ddl, localhost, root; +SET DEBUG_SYNC = 'row_merge_after_scan SIGNAL scanned WAIT_FOR commit'; +SET DEBUG_SYNC = 'before_commit_rollback_inplace SIGNAL c WAIT_FOR ever'; +ALTER TABLE t1 ADD UNIQUE INDEX(b), ALGORITHM=INPLACE; +connection default; +SET DEBUG_SYNC = 'now WAIT_FOR scanned'; +BEGIN; +INSERT INTO t1 VALUES(2,1); +SET DEBUG_SYNC = 'now SIGNAL commit'; +SET DEBUG_SYNC = 'now WAIT_FOR c'; +SET GLOBAL innodb_fil_make_page_dirty_debug=0; +# Kill the server +disconnect ddl; +# restart +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * FROM t1; +a b +1 1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/alter_crash.test b/mysql-test/suite/innodb/t/alter_crash.test index ea2716b9111..1049efd3e12 100644 --- a/mysql-test/suite/innodb/t/alter_crash.test +++ b/mysql-test/suite/innodb/t/alter_crash.test @@ -4,6 +4,7 @@ --source include/not_embedded.inc --source include/have_innodb.inc --source include/have_debug.inc +--source include/have_debug_sync.inc --source include/not_crashrep.inc --disable_query_log @@ -195,3 +196,33 @@ disconnect con1; DROP TABLE t1; SET DEBUG_SYNC = 'RESET'; SET SQL_MODE=DEFAULT; + +--echo # +--echo # MDEV-26936 Recovery crash on rolling back DELETE FROM SYS_INDEXES +--echo # + +CREATE TABLE t1(a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1,1); + +connect ddl, localhost, root; +SET DEBUG_SYNC = 'row_merge_after_scan SIGNAL scanned WAIT_FOR commit'; +SET DEBUG_SYNC = 'before_commit_rollback_inplace SIGNAL c WAIT_FOR ever'; +send ALTER TABLE t1 ADD UNIQUE INDEX(b), ALGORITHM=INPLACE; + +connection default; +SET DEBUG_SYNC = 'now WAIT_FOR scanned'; +BEGIN; +INSERT INTO t1 VALUES(2,1); +SET DEBUG_SYNC = 'now SIGNAL commit'; +SET DEBUG_SYNC = 'now WAIT_FOR c'; +# Make all pending changes durable for recovery. +SET GLOBAL innodb_fil_make_page_dirty_debug=0; + +--source include/kill_mysqld.inc +disconnect ddl; +--source include/start_mysqld.inc + +CHECK TABLE t1; +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/sysschema/r/all_sys_objects_exist.result b/mysql-test/suite/sysschema/r/all_sys_objects_exist.result index d89890f1747..6dddd8a186c 100644 --- a/mysql-test/suite/sysschema/r/all_sys_objects_exist.result +++ b/mysql-test/suite/sysschema/r/all_sys_objects_exist.result @@ -154,8 +154,6 @@ statement_performance_analyzer PROCEDURE table_exists PROCEDURE SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA = 'sys' ORDER BY TRIGGER_NAME; TRIGGER_NAME -sys_config_insert_set_user -sys_config_update_set_user SELECT sys_version FROM sys.version; sys_version 1.5.1 diff --git a/scripts/sys_schema/README.md b/scripts/sys_schema/README.md index d5f792059c3..feaf9ff5ee8 100644 --- a/scripts/sys_schema/README.md +++ b/scripts/sys_schema/README.md @@ -12,9 +12,7 @@ There are install files available for 5.6 and 5.7 respectively. To load these, y ##### Description -Holds configuration options for the sys schema. This is a persistent table (using the `InnoDB` storage engine), with the configuration persisting across upgrades (new options are added with `INSERT IGNORE`). - -The table also has two related triggers, which maintain the user that `INSERTs` or `UPDATEs` the configuration - `sys_config_insert_set_user` and `sys_config_update_set_user` respectively. +Holds configuration options for the sys schema. This is a persistent table, with the configuration persisting across upgrades (new options are added with `INSERT IGNORE`). Its structure is as follows: diff --git a/scripts/sys_schema/triggers/sys_config_insert_set_user.sql b/scripts/sys_schema/triggers/sys_config_insert_set_user.sql index 3c5e7dbf060..3d608ace862 100644 --- a/scripts/sys_schema/triggers/sys_config_insert_set_user.sql +++ b/scripts/sys_schema/triggers/sys_config_insert_set_user.sql @@ -22,14 +22,3 @@ DROP TRIGGER IF EXISTS sys_config_insert_set_user; -DELIMITER $$ - -CREATE DEFINER='root'@'localhost' TRIGGER sys_config_insert_set_user BEFORE INSERT on sys_config - FOR EACH ROW -BEGIN - IF @sys.ignore_sys_config_triggers != true AND NEW.set_by IS NULL THEN - SET NEW.set_by = USER(); - END IF; -END$$ - -DELIMITER ; diff --git a/scripts/sys_schema/triggers/sys_config_update_set_user.sql b/scripts/sys_schema/triggers/sys_config_update_set_user.sql index 55b6ff27cf1..8b956da78ab 100644 --- a/scripts/sys_schema/triggers/sys_config_update_set_user.sql +++ b/scripts/sys_schema/triggers/sys_config_update_set_user.sql @@ -22,15 +22,3 @@ DROP TRIGGER IF EXISTS sys_config_update_set_user; - -DELIMITER $$ - -CREATE DEFINER='root'@'localhost' TRIGGER sys_config_update_set_user BEFORE UPDATE on sys_config - FOR EACH ROW -BEGIN - IF @sys.ignore_sys_config_triggers != true AND NEW.set_by IS NULL THEN - SET NEW.set_by = USER(); - END IF; -END$$ - -DELIMITER ; diff --git a/sql/sql_cursor.h b/sql/sql_cursor.h index 00b9cd4e67a..b9d0b41ea19 100644 --- a/sql/sql_cursor.h +++ b/sql/sql_cursor.h @@ -39,7 +39,7 @@ class JOIN; its base class. */ -class Server_side_cursor: protected Query_arena, public Sql_alloc +class Server_side_cursor: protected Query_arena { protected: /** Row destination used for fetch */ @@ -61,6 +61,8 @@ public: } virtual ~Server_side_cursor(); + static void *operator new(size_t size, MEM_ROOT *mem_root) + { return alloc_root(mem_root, size); } static void operator delete(void *ptr, size_t size); static void operator delete(void *, MEM_ROOT *){} }; diff --git a/sql/sql_prepare.h b/sql/sql_prepare.h index d4a03c433b2..1a96df85a19 100644 --- a/sql/sql_prepare.h +++ b/sql/sql_prepare.h @@ -115,7 +115,7 @@ class Ed_row; automatic type conversion. */ -class Ed_result_set: public Sql_alloc +class Ed_result_set { public: operator List<Ed_row>&() { return *m_rows; } @@ -129,6 +129,8 @@ public: size_t get_field_count() const { return m_column_count; } + static void *operator new(size_t size, MEM_ROOT *mem_root) + { return alloc_root(mem_root, size); } static void operator delete(void *ptr, size_t size) throw (); static void operator delete(void *, MEM_ROOT *){} private: diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc index c265bc9de8a..eb08441a4d5 100644 --- a/sql/threadpool_generic.cc +++ b/sql/threadpool_generic.cc @@ -1746,9 +1746,9 @@ static void print_pool_blocked_message(bool max_threads_reached) if (now > pool_block_start + BLOCK_MSG_DELAY && !msg_written) { if (max_threads_reached) - sql_print_error(MAX_THREADS_REACHED_MSG); + sql_print_warning(MAX_THREADS_REACHED_MSG); else - sql_print_error(CREATE_THREAD_ERROR_MSG, my_errno); + sql_print_warning(CREATE_THREAD_ERROR_MSG, my_errno); sql_print_information("Threadpool has been blocked for %u seconds\n", (uint)((now- pool_block_start)/1000000)); diff --git a/storage/connect/colblk.h b/storage/connect/colblk.h index 7f1af8b8368..c9712f516b5 100644 --- a/storage/connect/colblk.h +++ b/storage/connect/colblk.h @@ -1,7 +1,7 @@ /*************** Colblk H Declares Source Code File (.H) ***************/ /* Name: COLBLK.H Version 1.7 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2005-2019 */ /* */ /* This file contains the COLBLK and derived classes declares. */ /***********************************************************************/ diff --git a/storage/connect/mysql-test/connect/t/mongo.inc b/storage/connect/mysql-test/connect/t/mongo.inc index fab2ca84139..25c3f207696 100644 --- a/storage/connect/mysql-test/connect/t/mongo.inc +++ b/storage/connect/mysql-test/connect/t/mongo.inc @@ -1,3 +1,11 @@ -let $MONGO= C:/Applic/MongoDB/Server/3.6/bin/mongo; -let $MONGOIMPORT= C:/Applic/MongoDB/Server/3.6/bin/mongoimport; +#let $MONGO= C:/Applic/MongoDB/Server/3.6/bin/mongo; +#let $MONGOIMPORT= C:/Applic/MongoDB/Server/3.6/bin/mongoimport; +let $MONGO= mongo; +let $MONGOIMPORT= mongoimport; + + + + + + diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index c7843dfe245..50069b7433b 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -1,7 +1,7 @@ /***********************************************************************/ -/* Name: ODBCONN.CPP Version 2.3 */ +/* Name: ODBCONN.CPP Version 2.4 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */ +/* (C) Copyright to the author Olivier BERTRAND 1998-2021 */ /* */ /* This file contains the ODBC connection classes functions. */ /***********************************************************************/ @@ -1509,7 +1509,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) ThrowDBX(MSG(COL_NUM_MISM)); // Now bind the column buffers - for (n = 1, colp = tocols; colp; colp = (PODBCCOL)colp->GetNext()) + for (colp = tocols; colp; colp = (PODBCCOL)colp->GetNext()) if (!colp->IsSpecial()) { buffer = colp->GetBuffer(m_RowsetSize); len = colp->GetBuflen(); @@ -1525,12 +1525,11 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) htrc("Binding col=%u type=%d buf=%p len=%d slen=%p\n", n, tp, buffer, len, colp->GetStrLen()); - rc = SQLBindCol(hstmt, n, tp, buffer, len, colp->GetStrLen()); + rc = SQLBindCol(hstmt, colp->GetIndex(), tp, buffer, len, colp->GetStrLen()); if (!Check(rc)) ThrowDBX(rc, "SQLBindCol", hstmt); - n++; } // endif pcol } catch(DBX *x) { diff --git a/storage/connect/tabbson.cpp b/storage/connect/tabbson.cpp index de272798e7c..871a54c8c94 100644 --- a/storage/connect/tabbson.cpp +++ b/storage/connect/tabbson.cpp @@ -376,7 +376,7 @@ int BSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt) } // endswitch ReadDB } else - jsp = bp->GetArrayValue(bdp, i); + jsp = bp->GetNext(jsp); if (!(row = (jsp) ? bp->GetObject(jsp) : NULL)) break; @@ -2187,7 +2187,9 @@ void BSONCOL::WriteColumn(PGLOBAL g) TDBBSON::TDBBSON(PGLOBAL g, PBDEF tdp, PTXF txfp) : TDBBSN(g, tdp, txfp) { Docp = NULL; + Docrow = NULL; Multiple = tdp->Multiple; + Docsize = 0; Done = Changed = false; Bp->SetPretty(2); } // end of TDBBSON standard constructor @@ -2195,7 +2197,9 @@ TDBBSON::TDBBSON(PGLOBAL g, PBDEF tdp, PTXF txfp) : TDBBSN(g, tdp, txfp) TDBBSON::TDBBSON(PBTDB tdbp) : TDBBSN(tdbp) { Docp = tdbp->Docp; + Docrow = tdbp->Docrow; Multiple = tdbp->Multiple; + Docsize = tdbp->Docsize; Done = tdbp->Done; Changed = tdbp->Changed; } // end of TDBBSON copy constructor @@ -2376,6 +2380,7 @@ int TDBBSON::MakeDocument(PGLOBAL g) } // endif jsp + Docsize = Bp->GetSize(Docp); Done = true; return RC_OK; } // end of MakeDocument @@ -2390,7 +2395,7 @@ int TDBBSON::Cardinality(PGLOBAL g) else if (Cardinal < 0) { if (!Multiple) { if (MakeDocument(g) == RC_OK) - Cardinal = Bp->GetSize(Docp); + Cardinal = Docsize; } else return 10; @@ -2419,6 +2424,7 @@ void TDBBSON::ResetSize(void) MaxSize = Cardinal = -1; Fpos = -1; N = 0; + Docrow = NULL; Done = false; } // end of ResetSize @@ -2477,6 +2483,7 @@ bool TDBBSON::SetRecpos(PGLOBAL, int recpos) #endif // 0 Fpos = recpos - 1; + Docrow = NULL; return false; } // end of SetRecpos @@ -2492,6 +2499,7 @@ bool TDBBSON::OpenDB(PGLOBAL g) Fpos = -1; NextSame = false; SameRow = 0; + Docrow = NULL; return false; } // endif use @@ -2532,12 +2540,9 @@ int TDBBSON::ReadDB(PGLOBAL) NextSame = false; M++; rc = RC_OK; - } else if (++Fpos < (signed)Bp->GetSize(Docp)) { - Row = Bp->GetArrayValue(Docp, Fpos); - - if (Row->Type == TYPE_JVAL) - Row = Bp->GetBson(Row); - + } else if (++Fpos < Docsize) { + Docrow = (Docrow) ? Bp->GetNext(Docrow) : Bp->GetArrayValue(Docp, Fpos); + Row = (Docrow->Type == TYPE_JVAL) ? Bp->GetBson(Docrow) : Docrow; SameRow = 0; M = 1; rc = RC_OK; diff --git a/storage/connect/tabbson.h b/storage/connect/tabbson.h index 7f41bba6bd9..1696f4dfdbc 100644 --- a/storage/connect/tabbson.h +++ b/storage/connect/tabbson.h @@ -318,7 +318,9 @@ protected: // Members PBVAL Docp; // The document array + PBVAL Docrow; // Document row int Multiple; // 0: No 1: DIR 2: Section 3: filelist + int Docsize; // The document size bool Done; // True when document parsing is done bool Changed; // After Update, Insert or Delete }; // end of class TDBBSON diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 00ac6ab7a9e..a8b37549cc8 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -3812,7 +3812,7 @@ dict_stats_update( if (!table->is_readable()) { return (dict_stats_report_error(table)); - } else if (srv_force_recovery > SRV_FORCE_NO_IBUF_MERGE) { + } else if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) { /* If we have set a high innodb_force_recovery level, do not calculate statistics, as a badly corrupted index can cause a crash in it. */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 948e7406af4..2a2e01d7598 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5831,7 +5831,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field) table->persistent_autoinc without autoinc_mutex protection, and there might be multiple ha_innobase::open() executing concurrently. */ - } else if (srv_force_recovery > SRV_FORCE_NO_IBUF_MERGE) { + } else if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) { /* If the recovery level is set so high that writes are disabled we force the AUTOINC counter to 0 value effectively disabling writes to the table. @@ -14858,7 +14858,7 @@ ha_innobase::info_low( } } - if (srv_force_recovery > SRV_FORCE_NO_IBUF_MERGE) { + if (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) { goto func_exit; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index cee63c227d4..ea8bd5316e7 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -8764,6 +8764,7 @@ inline bool rollback_inplace_alter_table(Alter_inplace_info *ha_alter_info, ut_d(dict_table_check_for_dup_indexes(ctx->old_table, CHECK_ABORTED_OK)); } + DEBUG_SYNC(ctx->trx->mysql_thd, "before_commit_rollback_inplace"); commit_unlock_and_unlink(ctx->trx); if (fts_exist) purge_sys.resume_FTS(); diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index df939afd314..6dbcfa7c54d 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -562,11 +562,9 @@ enum { SRV_FORCE_NO_BACKGROUND = 2, /*!< prevent the main thread from running: if a crash would occur in purge, this prevents it */ - SRV_FORCE_NO_TRX_UNDO = 3, /*!< do not run trx rollback after + SRV_FORCE_NO_TRX_UNDO = 3, /*!< do not run DML rollback after recovery */ - SRV_FORCE_NO_IBUF_MERGE = 4, /*!< prevent also ibuf operations: - if they would cause a crash, better - not do them */ + SRV_FORCE_NO_DDL_UNDO = 4, /*!< prevent also DDL rollback */ SRV_FORCE_NO_UNDO_LOG_SCAN = 5, /*!< do not look at undo logs when starting the database: InnoDB will treat even incomplete transactions diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index 751c4e73401..5b8ec4c50ad 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -173,6 +173,16 @@ row_undo_mod_clust_low( case DICT_INDEXES_ID: if (node->trx != trx_roll_crash_recv_trx) { break; + } else if (node->rec_type == TRX_UNDO_DEL_MARK_REC + && btr_cur_get_rec(btr_cur) + [8 + 8 + DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN] + == static_cast<byte>(*TEMP_INDEX_PREFIX_STR)) { + /* We are rolling back the DELETE of metadata + for a failed ADD INDEX operation. This does + not affect any cached table definition, + because we are filtering out such indexes in + dict_load_indexes(). */ + break; } /* fall through */ case DICT_COLUMNS_ID: diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index cb5709f8863..a1ba8130ba1 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1066,7 +1066,7 @@ dberr_t srv_start(bool create_new_db) } high_level_read_only = srv_read_only_mode - || srv_force_recovery > SRV_FORCE_NO_IBUF_MERGE + || srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN || srv_sys_space.created_new_raw(); srv_started_redo = false; @@ -1706,7 +1706,7 @@ file_checked: if (!create_new_db) { ut_ad(high_level_read_only - || srv_force_recovery <= SRV_FORCE_NO_IBUF_MERGE); + || srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN); /* Validate a few system page types that were left uninitialized before MySQL or MariaDB 5.5. */ @@ -1747,7 +1747,7 @@ file_checked: should guarantee that there is at most one data dictionary transaction active at a time. */ if (!high_level_read_only - && srv_force_recovery < SRV_FORCE_NO_TRX_UNDO) { + && srv_force_recovery <= SRV_FORCE_NO_TRX_UNDO) { /* If the following call is ever removed, the first-time ha_innobase::open() must hold (or acquire and release) a table lock that @@ -1761,7 +1761,7 @@ file_checked: trx_rollback_recovered(false); } - if (srv_force_recovery <= SRV_FORCE_NO_IBUF_MERGE) { + if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) { /* The following call is necessary for the insert buffer to work with multiple tablespaces. We must know the mapping between space id's and .ibd file diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index a0582413d07..8fd9f93909c 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -709,7 +709,8 @@ void trx_rollback_recovered(bool all) { std::vector<trx_t*> trx_list; - ut_a(srv_force_recovery < SRV_FORCE_NO_TRX_UNDO); + ut_a(srv_force_recovery < + ulong(all ? SRV_FORCE_NO_TRX_UNDO : SRV_FORCE_NO_DDL_UNDO)); /* Collect list of recovered ACTIVE transaction ids first. Once collected, no |