Skip to content

Commit

Permalink
Merge bb-10.2-ext into 10.3
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-m committed Dec 20, 2017
2 parents b4e5d5e + 0bc3675 commit 2534b5c
Show file tree
Hide file tree
Showing 15 changed files with 250 additions and 86 deletions.
12 changes: 12 additions & 0 deletions mysql-test/suite/innodb/r/rename_table_debug.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CREATE TABLE t1 (a INT UNSIGNED PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES(42);
connect con1,localhost,root,,test;
SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever';
RENAME TABLE t1 TO t2;
connection default;
SET DEBUG_SYNC='now WAIT_FOR renamed';
disconnect con1;
SELECT * FROM t1;
a
42
DROP TABLE t1;
19 changes: 19 additions & 0 deletions mysql-test/suite/innodb/t/rename_table_debug.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--source include/have_innodb.inc
--source include/have_debug.inc
--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);

--connect (con1,localhost,root,,test)
SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever';
--send
RENAME TABLE t1 TO t2;
--connection default
SET DEBUG_SYNC='now WAIT_FOR renamed';
--let $shutdown_timeout=0
--source include/restart_mysqld.inc
--disconnect con1
SELECT * FROM t1;
DROP TABLE t1;
2 changes: 2 additions & 0 deletions storage/innobase/dict/dict0dict.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1673,6 +1673,8 @@ dict_table_rename_in_cache(
return(err);
}

fil_name_write_rename(table->space, old_path, new_path);

bool success = fil_rename_tablespace(
table->space, old_path, new_name, new_path);

Expand Down
5 changes: 2 additions & 3 deletions storage/innobase/dict/dict0load.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1444,7 +1444,7 @@ dict_check_sys_tables(
look to see if it is already in the tablespace cache. */
if (fil_space_for_table_exists_in_mem(
space_id, table_name.m_name,
false, true, NULL, 0, flags)) {
false, NULL, flags)) {
/* Recovery can open a datafile that does not
match SYS_DATAFILES. If they don't match, update
SYS_DATAFILES. */
Expand Down Expand Up @@ -2852,8 +2852,7 @@ dict_load_tablespace(

/* The tablespace may already be open. */
if (fil_space_for_table_exists_in_mem(
table->space, space_name, false,
true, heap, table->id, table->flags)) {
table->space, space_name, false, heap, table->flags)) {
return;
}

Expand Down
69 changes: 21 additions & 48 deletions storage/innobase/fil/fil0fil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2331,7 +2331,7 @@ fil_op_write_log(
@param[in,out] mtr mini-transaction */
static
void
fil_name_write_rename(
fil_name_write_rename_low(
ulint space_id,
ulint first_page_no,
const char* old_name,
Expand All @@ -2345,6 +2345,23 @@ fil_name_write_rename(
space_id, first_page_no, old_name, new_name, 0, mtr);
}

/** Write redo log for renaming a file.
@param[in] space_id tablespace id
@param[in] old_name tablespace file name
@param[in] new_name tablespace file name after renaming */
void
fil_name_write_rename(
ulint space_id,
const char* old_name,
const char* new_name)
{
mtr_t mtr;
mtr.start();
fil_name_write_rename_low(space_id, 0, old_name, new_name, &mtr);
mtr.commit();
log_write_up_to(mtr.commit_lsn(), true);
}

/** Write MLOG_FILE_NAME for a file.
@param[in] space_id tablespace id
@param[in] first_page_no first page number in the file
Expand Down Expand Up @@ -3583,12 +3600,7 @@ fil_rename_tablespace(
ut_ad(strchr(new_file_name, OS_PATH_SEPARATOR) != NULL);

if (!recv_recovery_on) {
mtr_t mtr;

mtr.start();
fil_name_write_rename(
id, 0, old_file_name, new_file_name, &mtr);
mtr.commit();
fil_name_write_rename(id, old_file_name, new_file_name);
log_mutex_enter();
}

Expand Down Expand Up @@ -4651,19 +4663,15 @@ startup, there may be many tablespaces which are not yet in the memory cache.
@param[in] print_error_if_does_not_exist
Print detailed error information to the
error log if a matching tablespace is not found from memory.
@param[in] adjust_space Whether to adjust space id on mismatch
@param[in] heap Heap memory
@param[in] table_id table id
@param[in] table_flags table flags
@return true if a matching tablespace exists in the memory cache */
bool
fil_space_for_table_exists_in_mem(
ulint id,
const char* name,
bool print_error_if_does_not_exist,
bool adjust_space,
mem_heap_t* heap,
table_id_t table_id,
ulint table_flags)
{
fil_space_t* fnamespace;
Expand All @@ -4688,41 +4696,6 @@ fil_space_for_table_exists_in_mem(
} else if (!valid || space == fnamespace) {
/* Found with the same file name, or got a flag mismatch. */
goto func_exit;
} else if (adjust_space
&& row_is_mysql_tmp_table_name(space->name)
&& !row_is_mysql_tmp_table_name(name)) {
/* Info from fnamespace comes from the ibd file
itself, it can be different from data obtained from
System tables since renaming files is not
transactional. We shall adjust the ibd file name
according to system table info. */
mutex_exit(&fil_system->mutex);

DBUG_EXECUTE_IF("ib_crash_before_adjust_fil_space",
DBUG_SUICIDE(););

const char* tmp_name = dict_mem_create_temporary_tablename(
heap, name, table_id);

fil_rename_tablespace(
fnamespace->id,
UT_LIST_GET_FIRST(fnamespace->chain)->name,
tmp_name, NULL);

DBUG_EXECUTE_IF("ib_crash_after_adjust_one_fil_space",
DBUG_SUICIDE(););

fil_rename_tablespace(
id, UT_LIST_GET_FIRST(space->chain)->name,
name, NULL);

DBUG_EXECUTE_IF("ib_crash_after_adjust_fil_space",
DBUG_SUICIDE(););

mutex_enter(&fil_system->mutex);
fnamespace = fil_space_get_by_name(name);
ut_ad(space == fnamespace);
goto func_exit;
}

if (!print_error_if_does_not_exist) {
Expand Down Expand Up @@ -6215,7 +6188,7 @@ fil_mtr_rename_log(
return(err);
}

fil_name_write_rename(
fil_name_write_rename_low(
old_table->space, 0, old_path, tmp_path, mtr);

ut_free(tmp_path);
Expand Down Expand Up @@ -6246,7 +6219,7 @@ fil_mtr_rename_log(
}
}

fil_name_write_rename(
fil_name_write_rename_low(
new_table->space, 0, new_path, old_path, mtr);

ut_free(new_path);
Expand Down
7 changes: 1 addition & 6 deletions storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13610,17 +13610,13 @@ innobase_rename_table(
TrxInInnoDB trx_in_innodb(trx);

trx_start_if_not_started(trx, true);
ut_ad(trx->will_lock > 0);

/* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations. */

row_mysql_lock_data_dictionary(trx);

/* Transaction must be flagged as a locking transaction or it hasn't
been started yet. */

ut_a(trx->will_lock > 0);

error = row_rename_table_for_mysql(norm_from, norm_to, trx, TRUE);

if (error == DB_TABLE_NOT_FOUND) {
Expand All @@ -13629,7 +13625,6 @@ innobase_rename_table(

We are doing a DDL operation. */
++trx->will_lock;
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
trx_start_if_not_started(trx, true);
error = row_rename_partitions_for_mysql(norm_from, norm_to,
trx);
Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/include/dict0dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ dict_table_rename_in_cache(
/*!< in: in ALTER TABLE we want
to preserve the original table name
in constraints which reference it */
MY_ATTRIBUTE((nonnull, warn_unused_result));
MY_ATTRIBUTE((nonnull));

/** Removes an index from the dictionary cache.
@param[in,out] table table whose index to remove
Expand Down
40 changes: 23 additions & 17 deletions storage/innobase/include/fil0fil.h
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,15 @@ fil_create_directory_for_tablename(
/*===============================*/
const char* name); /*!< in: name in the standard
'databasename/tablename' format */
/** Write redo log for renaming a file.
@param[in] space_id tablespace id
@param[in] old_name tablespace file name
@param[in] new_name tablespace file name after renaming */
void
fil_name_write_rename(
ulint space_id,
const char* old_name,
const char* new_name);
/********************************************************//**
Recreates table indexes by applying
TRUNCATE log record during recovery.
Expand Down Expand Up @@ -1155,27 +1164,24 @@ fil_file_readdir_next_file(
os_file_dir_t dir, /*!< in: directory stream */
os_file_stat_t* info); /*!< in/out: buffer where the
info is returned */
/*******************************************************************//**
Returns true if a matching tablespace exists in the InnoDB tablespace memory
cache. Note that if we have not done a crash recovery at the database startup,
there may be many tablespaces which are not yet in the memory cache.
/** Determine if a matching tablespace exists in the InnoDB tablespace
memory cache. Note that if we have not done a crash recovery at the database
startup, there may be many tablespaces which are not yet in the memory cache.
@param[in] id Tablespace ID
@param[in] name Tablespace name used in fil_space_create().
@param[in] print_error_if_does_not_exist
Print detailed error information to the
error log if a matching tablespace is not found from memory.
@param[in] heap Heap memory
@param[in] table_flags table flags
@return true if a matching tablespace exists in the memory cache */
bool
fil_space_for_table_exists_in_mem(
/*==============================*/
ulint id, /*!< in: space id */
const char* name, /*!< in: table name in the standard
'databasename/tablename' format */
ulint id,
const char* name,
bool print_error_if_does_not_exist,
/*!< in: print detailed error
information to the .err log if a
matching tablespace is not found from
memory */
bool adjust_space, /*!< in: whether to adjust space id
when find table space mismatch */
mem_heap_t* heap, /*!< in: heap memory */
table_id_t table_id, /*!< in: table id */
ulint table_flags); /*!< in: table flags */
mem_heap_t* heap,
ulint table_flags);

/** Try to extend a tablespace if it is smaller than the specified size.
@param[in,out] space tablespace
Expand Down
10 changes: 9 additions & 1 deletion storage/innobase/include/trx0rec.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,13 @@ trx_undo_rec_get_partial_row(
mem_heap_t* heap) /*!< in: memory heap from which the memory
needed is allocated */
MY_ATTRIBUTE((nonnull, warn_unused_result));
/** Report a RENAME TABLE operation.
@param[in,out] trx transaction
@param[in] table table that is being renamed
@return DB_SUCCESS or error code */
dberr_t
trx_undo_report_rename(trx_t* trx, const dict_table_t* table)
MY_ATTRIBUTE((nonnull, warn_unused_result));
/***********************************************************************//**
Writes information to an undo log about an insert, update, or a delete marking
of a clustered index record. This information is used in a rollback of the
Expand Down Expand Up @@ -285,7 +292,8 @@ trx_undo_read_v_idx(
compilation info multiplied by 16 is ORed to this value in an undo log
record */

#define TRX_UNDO_INSERT_DEFAULT 10 /* insert a "default value"
#define TRX_UNDO_RENAME_TABLE 9 /*!< RENAME TABLE */
#define TRX_UNDO_INSERT_DEFAULT 10 /*!< insert a "default value"
pseudo-record for instant ALTER */
#define TRX_UNDO_INSERT_REC 11 /* fresh insert into clustered index */
#define TRX_UNDO_UPD_EXIST_REC 12 /* update of a non-delete-marked
Expand Down
5 changes: 4 additions & 1 deletion storage/innobase/include/trx0rec.ic
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,8 @@ trx_undo_rec_copy(
len = mach_read_from_2(undo_rec)
- ut_align_offset(undo_rec, UNIV_PAGE_SIZE);
ut_ad(len < UNIV_PAGE_SIZE);
return((trx_undo_rec_t*) mem_heap_dup(heap, undo_rec, len));
trx_undo_rec_t* rec = static_cast<trx_undo_rec_t*>(
mem_heap_dup(heap, undo_rec, len));
mach_write_to_2(rec, len);
return rec;
}
14 changes: 12 additions & 2 deletions storage/innobase/row/row0mysql.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3511,7 +3511,7 @@ row_drop_single_table_tablespace(

/* If the tablespace is not in the cache, just delete the file. */
if (!fil_space_for_table_exists_in_mem(
space_id, tablename, true, false, NULL, 0, table_flags)) {
space_id, tablename, true, NULL, table_flags)) {

/* Force a delete of any discarded or temporary files. */
fil_delete_file(filepath);
Expand Down Expand Up @@ -4522,6 +4522,14 @@ row_rename_table_for_mysql(
goto funct_exit;
}

if (!table->is_temporary()) {
err = trx_undo_report_rename(trx, table);

if (err != DB_SUCCESS) {
goto funct_exit;
}
}

/* We use the private SQL parser of Innobase to generate the query
graphs needed in updating the dictionary data from system tables. */

Expand Down Expand Up @@ -4707,7 +4715,8 @@ row_rename_table_for_mysql(
}
}

if (dict_table_has_fts_index(table)
if (err == DB_SUCCESS
&& dict_table_has_fts_index(table)
&& !dict_tables_have_same_db(old_name, new_name)) {
err = fts_rename_aux_tables(table, new_name, trx);
if (err != DB_TABLE_NOT_FOUND) {
Expand Down Expand Up @@ -4862,6 +4871,7 @@ row_rename_table_for_mysql(
}

if (commit) {
DEBUG_SYNC(trx->mysql_thd, "before_rename_table_commit");
trx_commit_for_mysql(trx);
}

Expand Down
4 changes: 3 additions & 1 deletion storage/innobase/row/row0purge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -905,12 +905,14 @@ row_purge_parse_undo_rec(
node->rec_type = type;

switch (type) {
case TRX_UNDO_RENAME_TABLE:
return false;
case TRX_UNDO_INSERT_DEFAULT:
case TRX_UNDO_INSERT_REC:
break;
default:
#ifdef UNIV_DEBUG
ut_ad(0);
ut_ad(!"unknown undo log record type");
return false;
case TRX_UNDO_UPD_DEL_REC:
case TRX_UNDO_UPD_EXIST_REC:
Expand Down
Loading

0 comments on commit 2534b5c

Please sign in to comment.