summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-01-17 16:33:40 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2018-01-17 16:33:40 +0200
commit4ef2e43080989cfb5ce62f5816505d17759c3f7c (patch)
tree0d43fde597c04f7cf253a60eb96206755e068adc
parent8f102b584d4e8f02da924f9be094014136eb453f (diff)
parentc6cd64f3cb4202fdadeb470fe28f6c50e337f460 (diff)
downloadmariadb-git-4ef2e43080989cfb5ce62f5816505d17759c3f7c.tar.gz
Merge bb-10.2-ext into 10.3
-rw-r--r--mysql-test/suite/innodb/r/rename_table_debug.result31
-rw-r--r--mysql-test/suite/innodb/t/rename_table_debug.test39
-rw-r--r--mysys/my_alloc.c4
-rw-r--r--sql/sp_head.cc8
-rw-r--r--sql/sql_class.cc14
-rw-r--r--sql/sql_class.h37
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_prepare.cc8
-rw-r--r--storage/innobase/btr/btr0cur.cc2
-rw-r--r--storage/innobase/row/row0mysql.cc4
-rw-r--r--storage/innobase/srv/srv0start.cc30
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/disabled.def3
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