Commit 4ef2e430 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge bb-10.2-ext into 10.3

parents 8f102b58 c6cd64f3
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;
......@@ -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
......@@ -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
/*
......
......@@ -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
......
......@@ -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;
......
......@@ -1321,7 +1321,21 @@ class Security_context {
*/
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 @@ class THD :public Statement,
#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 @@ class THD :public Statement,
*/
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
......
......@@ -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
{
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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 @@ innobase_start_or_create_for_mysql()
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
......
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment