diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-01-17 16:33:40 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-01-17 16:33:40 +0200 |
commit | 4ef2e43080989cfb5ce62f5816505d17759c3f7c (patch) | |
tree | 0d43fde597c04f7cf253a60eb96206755e068adc | |
parent | 8f102b584d4e8f02da924f9be094014136eb453f (diff) | |
parent | c6cd64f3cb4202fdadeb470fe28f6c50e337f460 (diff) | |
download | mariadb-git-4ef2e43080989cfb5ce62f5816505d17759c3f7c.tar.gz |
Merge bb-10.2-ext into 10.3
-rw-r--r-- | mysql-test/suite/innodb/r/rename_table_debug.result | 31 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/rename_table_debug.test | 39 | ||||
-rw-r--r-- | mysys/my_alloc.c | 4 | ||||
-rw-r--r-- | sql/sp_head.cc | 8 | ||||
-rw-r--r-- | sql/sql_class.cc | 14 | ||||
-rw-r--r-- | sql/sql_class.h | 37 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 8 | ||||
-rw-r--r-- | storage/innobase/btr/btr0cur.cc | 2 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 4 | ||||
-rw-r--r-- | storage/innobase/srv/srv0start.cc | 30 | ||||
-rw-r--r-- | storage/rocksdb/mysql-test/rocksdb/t/disabled.def | 3 |
12 files changed, 135 insertions, 47 deletions
diff --git a/mysql-test/suite/innodb/r/rename_table_debug.result b/mysql-test/suite/innodb/r/rename_table_debug.result index 912ed9de48b..7c9b961dee5 100644 --- a/mysql-test/suite/innodb/r/rename_table_debug.result +++ b/mysql-test/suite/innodb/r/rename_table_debug.result @@ -1,5 +1,5 @@ -CREATE TABLE t1 (a INT UNSIGNED PRIMARY KEY) ENGINE=InnoDB; -INSERT INTO t1 VALUES(42); +CREATE TABLE t1 (a SERIAL, b INT, c INT, d INT) ENGINE=InnoDB; +INSERT INTO t1 () VALUES (); connect con1,localhost,root,,test; SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever'; RENAME TABLE t1 TO t2; @@ -7,6 +7,29 @@ connection default; SET DEBUG_SYNC='now WAIT_FOR renamed'; disconnect con1; SELECT * FROM t1; -a -42 +a b c d +1 NULL NULL NULL +BEGIN; +COMMIT; +UPDATE t1 SET b=a%7, c=a%11, d=a%13; +SET DEBUG_DBUG='+d,crash_commit_before'; +ALTER TABLE t1 +ADD INDEX(b,c,d,a),ADD INDEX(b,c,a,d),ADD INDEX(b,a,c,d),ADD INDEX(b,a,d,c), +ADD INDEX(b,d,a,c),ADD INDEX(b,d,c,a),ADD INDEX(a,b,c,d),ADD INDEX(a,b,d,c), +ADD INDEX(a,c,b,d),ADD INDEX(a,c,d,b),ADD INDEX(a,d,b,c),ADD INDEX(a,d,c,b), +ADD INDEX(c,a,b,d),ADD INDEX(c,a,d,b),ADD INDEX(c,b,a,d),ADD INDEX(c,b,d,a), +ADD INDEX(c,d,a,b),ADD INDEX(c,d,b,a),ADD INDEX(d,a,b,c),ADD INDEX(d,a,c,b), +ADD INDEX(d,b,a,c),ADD INDEX(d,b,c,a),ADD INDEX(d,c,a,b),ADD INDEX(d,c,b,a), +ADD INDEX(a,b,c), ADD INDEX(a,c,b), ADD INDEX(a,c,d), ADD INDEX(a,d,c), +ADD INDEX(a,b,d), ADD INDEX(a,d,b), ADD INDEX(b,c,d), ADD INDEX(b,d,c), +ALGORITHM=COPY; +ERROR HY000: Lost connection to MySQL server during query +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +1000 DROP TABLE t1; +SET GLOBAL innodb_background_drop_list_empty= +@@GLOBAL.innodb_background_drop_list_empty; diff --git a/mysql-test/suite/innodb/t/rename_table_debug.test b/mysql-test/suite/innodb/t/rename_table_debug.test index 4620f7bef22..20af12dc15c 100644 --- a/mysql-test/suite/innodb/t/rename_table_debug.test +++ b/mysql-test/suite/innodb/t/rename_table_debug.test @@ -3,8 +3,10 @@ --source include/have_debug_sync.inc --source include/not_embedded.inc -CREATE TABLE t1 (a INT UNSIGNED PRIMARY KEY) ENGINE=InnoDB; -INSERT INTO t1 VALUES(42); +LET $datadir= `SELECT @@datadir`; + +CREATE TABLE t1 (a SERIAL, b INT, c INT, d INT) ENGINE=InnoDB; +INSERT INTO t1 () VALUES (); --connect (con1,localhost,root,,test) SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever'; @@ -16,4 +18,37 @@ SET DEBUG_SYNC='now WAIT_FOR renamed'; --source include/restart_mysqld.inc --disconnect con1 SELECT * FROM t1; + +let $c = 999; +BEGIN; +--disable_query_log +while ($c) { +INSERT INTO t1() VALUES(); +dec $c; +} +--enable_query_log +COMMIT; +UPDATE t1 SET b=a%7, c=a%11, d=a%13; + +--source include/expect_crash.inc +SET DEBUG_DBUG='+d,crash_commit_before'; +--error 2013 +ALTER TABLE t1 +ADD INDEX(b,c,d,a),ADD INDEX(b,c,a,d),ADD INDEX(b,a,c,d),ADD INDEX(b,a,d,c), +ADD INDEX(b,d,a,c),ADD INDEX(b,d,c,a),ADD INDEX(a,b,c,d),ADD INDEX(a,b,d,c), +ADD INDEX(a,c,b,d),ADD INDEX(a,c,d,b),ADD INDEX(a,d,b,c),ADD INDEX(a,d,c,b), +ADD INDEX(c,a,b,d),ADD INDEX(c,a,d,b),ADD INDEX(c,b,a,d),ADD INDEX(c,b,d,a), +ADD INDEX(c,d,a,b),ADD INDEX(c,d,b,a),ADD INDEX(d,a,b,c),ADD INDEX(d,a,c,b), +ADD INDEX(d,b,a,c),ADD INDEX(d,b,c,a),ADD INDEX(d,c,a,b),ADD INDEX(d,c,b,a), +ADD INDEX(a,b,c), ADD INDEX(a,c,b), ADD INDEX(a,c,d), ADD INDEX(a,d,c), +ADD INDEX(a,b,d), ADD INDEX(a,d,b), ADD INDEX(b,c,d), ADD INDEX(b,d,c), +ALGORITHM=COPY; +--source include/start_mysqld.inc +CHECK TABLE t1; +SELECT COUNT(*) FROM t1; DROP TABLE t1; +# MDEV-11415 TODO: remove the following +SET GLOBAL innodb_background_drop_list_empty= +@@GLOBAL.innodb_background_drop_list_empty; +# Work around missing crash recovery at the SQL layer. +--remove_files_wildcard $datadir/test #sql-*.frm diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 3df73127998..b2a1264bd2b 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -325,7 +325,8 @@ void *multi_alloc_root(MEM_ROOT *root, ...) #define TRASH_MEM(X) TRASH(((char*)(X) + ((X)->size-(X)->left)), (X)->left) -/* Mark all data in blocks free for reusage */ +#if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG)) +/** Mark all data in blocks free for reusage */ static inline void mark_blocks_free(MEM_ROOT* root) { @@ -355,6 +356,7 @@ static inline void mark_blocks_free(MEM_ROOT* root) root->first_block_usage= 0; root->block_num= 4; } +#endif /* diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 07e760f4438..e86a35f4b27 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1133,7 +1133,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) We should also save Item tree change list to avoid rollback something too early in the calling query. */ - thd->change_list.move_elements_to(&old_change_list); + thd->Item_change_list::move_elements_to(&old_change_list); /* Cursors will use thd->packet, so they may corrupt data which was prepared for sending by upper level. OTOH cursors in the same routine can share this @@ -1279,8 +1279,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success) thd->spcont->instr_ptr= ip; thd->server_status= (thd->server_status & ~status_backup_mask) | old_server_status; old_packet.swap(thd->packet); - DBUG_ASSERT(thd->change_list.is_empty()); - old_change_list.move_elements_to(&thd->change_list); + DBUG_ASSERT(thd->Item_change_list::is_empty()); + old_change_list.move_elements_to(thd); thd->lex= old_lex; thd->set_query_id(old_query_id); DBUG_ASSERT(!thd->derived_tables); @@ -3071,7 +3071,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, bool parent_modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table; thd->transaction.stmt.modified_non_trans_table= FALSE; DBUG_ASSERT(!thd->derived_tables); - DBUG_ASSERT(thd->change_list.is_empty()); + DBUG_ASSERT(thd->Item_change_list::is_empty()); /* Use our own lex. We should not save old value since it is saved/restored in diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9f6ff7cde34..372f2cc9ebb 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2748,8 +2748,10 @@ struct Item_change_record: public ilink thd->mem_root (due to possible set_n_backup_active_arena called for thd). */ -void THD::nocheck_register_item_tree_change(Item **place, Item *old_value, - MEM_ROOT *runtime_memroot) +void +Item_change_list::nocheck_register_item_tree_change(Item **place, + Item *old_value, + MEM_ROOT *runtime_memroot) { Item_change_record *change; DBUG_ENTER("THD::nocheck_register_item_tree_change"); @@ -2790,8 +2792,10 @@ void THD::nocheck_register_item_tree_change(Item **place, Item *old_value, changes to substitute the same reference at both locations L1 and L2. */ -void THD::check_and_register_item_tree_change(Item **place, Item **new_value, - MEM_ROOT *runtime_memroot) +void +Item_change_list::check_and_register_item_tree_change(Item **place, + Item **new_value, + MEM_ROOT *runtime_memroot) { Item_change_record *change; I_List_iterator<Item_change_record> it(change_list); @@ -2806,7 +2810,7 @@ void THD::check_and_register_item_tree_change(Item **place, Item **new_value, } -void THD::rollback_item_tree_changes() +void Item_change_list::rollback_item_tree_changes() { I_List_iterator<Item_change_record> it(change_list); Item_change_record *change; diff --git a/sql/sql_class.h b/sql/sql_class.h index 28c603dd6b3..9a1c666292a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1321,7 +1321,21 @@ public: */ struct Item_change_record; -typedef I_List<Item_change_record> Item_change_list; +class Item_change_list +{ + I_List<Item_change_record> change_list; +public: + void nocheck_register_item_tree_change(Item **place, Item *old_value, + MEM_ROOT *runtime_memroot); + void check_and_register_item_tree_change(Item **place, Item **new_value, + MEM_ROOT *runtime_memroot); + void rollback_item_tree_changes(); + void move_elements_to(Item_change_list *to) + { + change_list.move_elements_to(&to->change_list); + } + bool is_empty() { return change_list.is_empty(); } +}; /** @@ -2105,6 +2119,14 @@ extern "C" void my_message_sql(uint error, const char *str, myf MyFlags); */ class THD :public Statement, + /* + This is to track items changed during execution of a prepared + statement/stored procedure. It's created by + nocheck_register_item_tree_change() in memory root of THD, + and freed in rollback_item_tree_changes(). + For conventional execution it's always empty. + */ + public Item_change_list, public MDL_context_owner, public Open_tables_state, public QUERY_START_TIME_INFO @@ -2586,14 +2608,6 @@ public: #ifdef SIGNAL_WITH_VIO_CLOSE Vio* active_vio; #endif - /* - This is to track items changed during execution of a prepared - statement/stored procedure. It's created by - nocheck_register_item_tree_change() in memory root of THD, and freed in - rollback_item_tree_changes(). For conventional execution it's always - empty. - */ - Item_change_list change_list; /* A permanent memory area of the statement. For conventional @@ -3785,11 +3799,6 @@ public: */ memcpy((char*) place, new_value, sizeof(*new_value)); } - void nocheck_register_item_tree_change(Item **place, Item *old_value, - MEM_ROOT *runtime_memroot); - void check_and_register_item_tree_change(Item **place, Item **new_value, - MEM_ROOT *runtime_memroot); - void rollback_item_tree_changes(); /* Cleanup statement parse state (parse tree, lex) and execution diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 44c8236023c..9884d2db8d6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -8000,7 +8000,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, sp_cache_enforce_limit(thd->sp_func_cache, stored_program_cache_size); thd->end_statement(); thd->cleanup_after_query(); - DBUG_ASSERT(thd->change_list.is_empty()); + DBUG_ASSERT(thd->Item_change_list::is_empty()); } else { diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 80ac2b22a86..aa0f081418d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3876,7 +3876,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) If called from a stored procedure, ensure that we won't rollback external changes when cleaning up after validation. */ - DBUG_ASSERT(thd->change_list.is_empty()); + DBUG_ASSERT(thd->Item_change_list::is_empty()); /* Marker used to release metadata locks acquired while the prepared @@ -4353,7 +4353,7 @@ Prepared_statement::execute_server_runnable(Server_runnable *server_runnable) bool error; Query_arena *save_stmt_arena= thd->stmt_arena; Item_change_list save_change_list; - thd->change_list.move_elements_to(&save_change_list); + thd->Item_change_list::move_elements_to(&save_change_list); state= STMT_CONVENTIONAL_EXECUTION; @@ -4372,7 +4372,7 @@ Prepared_statement::execute_server_runnable(Server_runnable *server_runnable) thd->restore_backup_statement(this, &stmt_backup); thd->stmt_arena= save_stmt_arena; - save_change_list.move_elements_to(&thd->change_list); + save_change_list.move_elements_to(thd); /* Items and memory will freed in destructor */ @@ -4600,7 +4600,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) If the free_list is not empty, we'll wrongly free some externally allocated items when cleaning up after execution of this statement. */ - DBUG_ASSERT(thd->change_list.is_empty()); + DBUG_ASSERT(thd->Item_change_list::is_empty()); /* The only case where we should have items in the thd->free_list is diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index cda0636146f..078375e1b28 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -3929,7 +3929,7 @@ btr_cur_update_in_place( #ifdef BTR_CUR_HASH_ADAPT { rw_lock_t* ahi_latch = block->index - ? btr_get_search_latch(block->index) : NULL; + ? btr_get_search_latch(index) : NULL; if (ahi_latch) { /* TO DO: Can we skip this if none of the fields index->search_info->curr_n_fields diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 15659431a7e..5bf0a3dcfc6 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -3816,7 +3816,7 @@ row_drop_table_for_mysql( if (table->n_foreign_key_checks_running > 0) { defer: - if (!strstr(table->name.m_name, "/" TEMP_FILE_PREFIX_INNODB)) { + if (!strstr(table->name.m_name, "/" TEMP_FILE_PREFIX)) { heap = mem_heap_create(FN_REFLEN); const char* tmp_name = dict_mem_create_temporary_tablename( @@ -4580,7 +4580,7 @@ row_rename_table_for_mysql( goto funct_exit; - } else if (new_is_tmp) { + } else if (!old_is_tmp && new_is_tmp) { /* MySQL is doing an ALTER TABLE command and it renames the original table to a temporary table name. We want to preserve the original foreign key constraint definitions despite the diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 9297dbefbae..5b0bdc5f605 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1438,6 +1438,7 @@ srv_prepare_to_delete_redo_log_files( << " bytes; LSN=" << flushed_lsn; } + srv_start_lsn = flushed_lsn; /* Flush the old log files. */ log_mutex_exit(); @@ -2217,17 +2218,32 @@ files_checked: recv_sys->dblwr.pages.clear(); - if (err == DB_SUCCESS) { - /* Initialize the change buffer. */ - err = dict_boot(); - } - if (err != DB_SUCCESS) { return(srv_init_abort(err)); } - /* This must precede recv_apply_hashed_log_recs(true). */ - trx_sys_init_at_db_start(); + switch (srv_operation) { + case SRV_OPERATION_NORMAL: + case SRV_OPERATION_RESTORE_EXPORT: + /* Initialize the change buffer. */ + err = dict_boot(); + if (err != DB_SUCCESS) { + return(srv_init_abort(err)); + } + /* This must precede + recv_apply_hashed_log_recs(true). */ + trx_sys_init_at_db_start(); + break; + case SRV_OPERATION_RESTORE_DELTA: + case SRV_OPERATION_BACKUP: + ut_ad(!"wrong mariabackup mode"); + /* fall through */ + case SRV_OPERATION_RESTORE: + /* mariabackup --prepare only deals with + the redo log and the data files, not with + transactions or the data dictionary. */ + break; + } if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) { /* Apply the hashed log records to the diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def index 8d0b5693a5b..3b9726986f0 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def +++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def @@ -59,7 +59,7 @@ bytes_written: Needs I_S.TABLE_STATISTICS.IO_WRITE_BYTES trx_info_rpl : MariaRocks: @@rpl_skip_tx_api doesn't work, yet. rpl_read_free: MDEV-10976 lock_wait_timeout_stats: MDEV-13404 - +rpl_row_triggers : Requires read-free slave. ## ## Test failures (in buildbot or else where) @@ -76,5 +76,4 @@ information_schema: MDEV-14372: unstable testcase ## mysqlbinlog_gtid_skip_empty_trans_rocksdb : MariaRocks: requires GTIDs -rpl_row_triggers : MariaRocks: requires GTIDs |