Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion sql/rpl_rli.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2173,7 +2173,8 @@ rpl_group_info::rpl_group_info(Relay_log_info *rli)
deferred_events(NULL), m_annotate_event(0), is_parallel_exec(false),
gtid_ev_flags2(0), gtid_ev_flags_extra(0), gtid_ev_sa_seq_no(0),
reserved_start_alter_thread(0), finish_event_group_called(0), rpt(NULL),
start_alter_ev(NULL), direct_commit_alter(false), sa_info(NULL)
start_alter_ev(NULL), direct_commit_alter(false), sa_info(NULL),
is_new_trans(false)
{
reinit(rli);
bzero(&current_gtid, sizeof(current_gtid));
Expand Down
26 changes: 25 additions & 1 deletion sql/rpl_rli.h
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ struct rpl_group_info
Query_log_event *start_alter_ev;
bool direct_commit_alter;
start_alter_info *sa_info;

bool is_new_trans; // marker of start_new_trans context
rpl_group_info(Relay_log_info *rli_);
~rpl_group_info();
void reinit(Relay_log_info *rli);
Expand Down Expand Up @@ -1075,6 +1075,30 @@ struct rpl_group_info

};

/**
The function
@return true when the slave applier context is normal
false when either no slave applier around or
the applier is executing start_new_trans
*/
inline bool not_new_trans(rpl_group_info* rgi)
{
return rgi && !rgi->is_new_trans;
}
/**
The following functions for start_new_trans' ctor and dtor.
*/
inline void mark_in_new_trans(rpl_group_info* rgi)
{
if (rgi)
rgi->is_new_trans= true;
}
inline void unmark_in_new_trans(rpl_group_info* rgi)
{
if (rgi)
rgi->is_new_trans= false;
}


/*
The class rpl_sql_thread_info is the THD::system_thread_info for an SQL
Expand Down
5 changes: 2 additions & 3 deletions sql/sql_class.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6678,8 +6678,7 @@ start_new_trans::start_new_trans(THD *thd)
thd->server_status&= ~(SERVER_STATUS_IN_TRANS |
SERVER_STATUS_IN_TRANS_READONLY);
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
org_rgi_slave= thd->rgi_slave;
thd->rgi_slave= NULL;
mark_in_new_trans(thd->rgi_slave);
}


Expand All @@ -6696,7 +6695,7 @@ void start_new_trans::restore_old_transaction()
MYSQL_COMMIT_TRANSACTION(org_thd->m_transaction_psi);
org_thd->m_transaction_psi= m_transaction_psi;
org_thd->variables.wsrep_on= wsrep_on;
org_thd->rgi_slave= org_rgi_slave;
unmark_in_new_trans(org_thd->rgi_slave);
org_thd= 0;
}

Expand Down
5 changes: 0 additions & 5 deletions sql/sql_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -6314,11 +6314,6 @@ class start_new_trans
uint in_sub_stmt;
uint server_status;
my_bool wsrep_on;
/*
THD:rgi_slave may hold a part of the replicated "old" transaction's
execution context. Therefore it has to be reset/restored too.
*/
rpl_group_info* org_rgi_slave;

public:
start_new_trans(THD *thd);
Expand Down
24 changes: 18 additions & 6 deletions sql/temporary_tables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,8 @@ void THD::restore_tmp_table_share(TMP_TABLE_SHARE *share)
If its a replication slave, report whether slave temporary tables
exist (Relay_log_info::save_temporary_tables) or report about THD
temporary table (Open_tables_state::temporary_tables) otherwise.
Note start-new-trans context is not about replication transaction
in which case the function uses the non-slave normal branch.

@return false Temporary tables exist
true No temporary table exist
Expand All @@ -957,7 +959,14 @@ bool THD::has_temporary_tables()
DBUG_ENTER("THD::has_temporary_tables");
bool result;
#ifdef HAVE_REPLICATION
if (rgi_slave)
/*
Slave applier thread may execute an out-of-band "new-transaction"
and do so in the middle of a replicated transaction processing.
All functions that open the access to slave temporary table repository
including the current one have to deny it within the start-new-transaction
context.
*/
if (not_new_trans(rgi_slave))
{
mysql_mutex_lock(&rgi_slave->rli->data_lock);
result= rgi_slave->rli->save_temporary_tables &&
Expand Down Expand Up @@ -1062,7 +1071,8 @@ TMP_TABLE_SHARE *THD::create_temporary_table(LEX_CUSTRING *frm,
during cleanup() from Relay_log_info::close_temporary_tables()
*/
init_tmp_table_share(this, share, saved_key_cache, key_length,
strend(saved_key_cache) + 1, tmp_path, !slave_thread);
strend(saved_key_cache) + 1, tmp_path,
!not_new_trans(rgi_slave));

/*
Prefer using frm image over file. The image might not be available in
Expand Down Expand Up @@ -1218,7 +1228,7 @@ TABLE *THD::open_temporary_table(TMP_TABLE_SHARE *share,
In replication, temporary tables are not confined to a single
thread/THD.
*/
if (slave_thread)
if (not_new_trans(rgi_slave))
flags|= HA_OPEN_GLOBAL_TMP_TABLE;
if (open_table_from_share(this, share, &alias,
(uint) HA_OPEN_KEYFILE,
Expand All @@ -1240,7 +1250,7 @@ TABLE *THD::open_temporary_table(TMP_TABLE_SHARE *share,
share->all_tmp_tables.push_front(table);

/* Increment Slave_open_temp_table_definitions status variable count. */
if (rgi_slave)
if (not_new_trans(rgi_slave))
slave_open_temp_tables++;

DBUG_PRINT("tmptable", ("Opened table: '%s'.'%s table: %p",
Expand Down Expand Up @@ -1656,6 +1666,8 @@ void THD::free_temporary_table(TABLE *table)
/**
On replication slave, acquire the Relay_log_info's data_lock and use slave
temporary tables.
Note start-new-trans context is not about replication transaction
in which case the function returns false.

@return true Lock acquired
false Lock wasn't acquired
Expand All @@ -1671,7 +1683,7 @@ bool THD::lock_temporary_tables()
}

#ifdef HAVE_REPLICATION
if (rgi_slave)
if (not_new_trans(rgi_slave)) /* see has_temporary_tables comments */
{
mysql_mutex_lock(&rgi_slave->rli->data_lock);
temporary_tables= rgi_slave->rli->save_temporary_tables;
Expand Down Expand Up @@ -1699,7 +1711,7 @@ void THD::unlock_temporary_tables()
}

#ifdef HAVE_REPLICATION
if (rgi_slave)
if (not_new_trans(rgi_slave)) /* ditto lock */
{
rgi_slave->rli->save_temporary_tables= temporary_tables;
temporary_tables= NULL; /* Safety */
Expand Down
Loading