Commit d107bdaa authored by unknown's avatar unknown

MDEV-4506, parallel replication.

Some after-review fixes.
parent 13fddb32
This diff is collapsed.
......@@ -540,7 +540,7 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
void do_checkpoint_request(ulong binlog_id);
void purge();
int write_transaction_or_stmt(group_commit_entry *entry, uint64 commit_id);
bool queue_for_group_commit(group_commit_entry *entry, wait_for_commit *wfc);
bool queue_for_group_commit(group_commit_entry *entry);
bool write_transaction_to_binlog_events(group_commit_entry *entry);
void trx_group_commit_leader(group_commit_entry *leader);
bool is_xidlist_idle_nolock();
......
This diff is collapsed.
......@@ -1317,7 +1317,7 @@ class Log_event
@see do_apply_event
*/
int apply_event(struct rpl_group_info *rgi)
int apply_event(rpl_group_info *rgi)
{
return do_apply_event(rgi);
}
......@@ -1331,7 +1331,7 @@ class Log_event
@see do_update_pos
*/
int update_pos(struct rpl_group_info *rgi)
int update_pos(rpl_group_info *rgi)
{
return do_update_pos(rgi);
}
......@@ -1432,7 +1432,7 @@ class Log_event
@retval 0 Event applied successfully
@retval errno Error code if event application failed
*/
virtual int do_apply_event(struct rpl_group_info *rgi)
virtual int do_apply_event(rpl_group_info *rgi)
{
return 0; /* Default implementation does nothing */
}
......@@ -1461,7 +1461,7 @@ class Log_event
1). Observe that handler errors are returned by the
do_apply_event() function, and not by this one.
*/
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
/**
......@@ -1986,10 +1986,10 @@ class Query_log_event: public Log_event
public: /* !!! Public in this patch to allow old usage */
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
int do_apply_event(struct rpl_group_info *rgi,
int do_apply_event(rpl_group_info *rgi,
const char *query_arg,
uint32 q_len_arg);
static bool peek_is_commit_rollback(const char *event_start,
......@@ -2103,7 +2103,7 @@ class Slave_log_event: public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
......@@ -2416,12 +2416,12 @@ class Load_log_event: public Log_event
public: /* !!! Public in this patch to allow old usage */
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi)
virtual int do_apply_event(rpl_group_info *rgi)
{
return do_apply_event(thd->slave_net,rgi,0);
}
int do_apply_event(NET *net, struct rpl_group_info *rgi,
int do_apply_event(NET *net, rpl_group_info *rgi,
bool use_rli_only_for_errors);
#endif
};
......@@ -2500,7 +2500,7 @@ class Start_log_event_v3: public Log_event
protected:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info*)
{
/*
......@@ -2596,8 +2596,8 @@ class Format_description_log_event: public Start_log_event_v3
static bool is_version_before_checksum(const master_version_split *version_split);
protected:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
#endif
};
......@@ -2675,8 +2675,8 @@ Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg,
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
#endif
};
......@@ -2754,8 +2754,8 @@ class Rand_log_event: public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
#endif
};
......@@ -2803,7 +2803,7 @@ class Xid_log_event: public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
enum_skip_reason do_shall_skip(Relay_log_info *rli);
#endif
};
......@@ -2870,8 +2870,8 @@ class User_var_log_event: public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
#endif
};
......@@ -2905,7 +2905,7 @@ class Stop_log_event: public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli)
{
/*
......@@ -3007,7 +3007,7 @@ class Rotate_log_event: public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
#endif
};
......@@ -3119,8 +3119,8 @@ class Gtid_log_event: public Log_event
uint16 flags, bool is_transactional, uint64 commit_id);
#ifdef HAVE_REPLICATION
void pack_info(THD *thd, Protocol *protocol);
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
#endif
#else
......@@ -3249,7 +3249,7 @@ class Gtid_list_log_event: public Log_event
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
bool to_packet(String *packet);
bool write(IO_CACHE *file);
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
#endif
static bool peek(const char *event_start, uint32 event_len,
uint8 checksum_alg,
......@@ -3328,7 +3328,7 @@ class Create_file_log_event: public Load_log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
......@@ -3383,7 +3383,7 @@ class Append_block_log_event: public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
......@@ -3424,7 +3424,7 @@ class Delete_file_log_event: public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
......@@ -3464,7 +3464,7 @@ class Execute_load_log_event: public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
......@@ -3563,7 +3563,7 @@ class Execute_load_query_log_event: public Query_log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
......@@ -3635,8 +3635,8 @@ class Annotate_rows_log_event: public Log_event
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
private:
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info*);
#endif
......@@ -4050,8 +4050,8 @@ class Table_map_log_event : public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
#endif
......@@ -4278,8 +4278,8 @@ class Rows_log_event : public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
/*
......@@ -4612,7 +4612,7 @@ class Incident_log_event : public Log_event {
#endif
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
#endif
virtual bool write_data_header(IO_CACHE *file);
......
......@@ -36,7 +36,7 @@
// Old implementation of do_apply_event()
int
Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, struct rpl_group_info *rgi)
Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, rpl_group_info *rgi)
{
DBUG_ENTER("Old_rows_log_event::do_apply_event(st_relay_log_info*)");
int error= 0;
......@@ -1451,7 +1451,7 @@ int Old_rows_log_event::do_add_row_data(uchar *row_data, size_t length)
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
int Old_rows_log_event::do_apply_event(struct rpl_group_info *rgi)
int Old_rows_log_event::do_apply_event(rpl_group_info *rgi)
{
DBUG_ENTER("Old_rows_log_event::do_apply_event(Relay_log_info*)");
int error= 0;
......@@ -1834,7 +1834,7 @@ Old_rows_log_event::do_shall_skip(Relay_log_info *rli)
}
int
Old_rows_log_event::do_update_pos(struct rpl_group_info *rgi)
Old_rows_log_event::do_update_pos(rpl_group_info *rgi)
{
Relay_log_info *rli= rgi->rli;
DBUG_ENTER("Old_rows_log_event::do_update_pos");
......
......@@ -214,8 +214,8 @@ class Old_rows_log_event : public Log_event
private:
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
virtual int do_apply_event(struct rpl_group_info *rgi);
virtual int do_update_pos(struct rpl_group_info *rgi);
virtual int do_apply_event(rpl_group_info *rgi);
virtual int do_update_pos(rpl_group_info *rgi);
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
/*
......@@ -275,7 +275,7 @@ class Old_rows_log_event : public Log_event
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
int do_apply_event(Old_rows_log_event*, struct rpl_group_info *rgi);
int do_apply_event(Old_rows_log_event*, rpl_group_info *rgi);
/*
Primitive to prepare for a sequence of row executions.
......@@ -403,7 +403,7 @@ class Write_rows_log_event_old : public Old_rows_log_event
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
// use old definition of do_apply_event()
virtual int do_apply_event(struct rpl_group_info *rgi)
virtual int do_apply_event(rpl_group_info *rgi)
{ return Old_rows_log_event::do_apply_event(this, rgi); }
// primitives for old version of do_apply_event()
......@@ -481,7 +481,7 @@ class Update_rows_log_event_old : public Old_rows_log_event
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
// use old definition of do_apply_event()
virtual int do_apply_event(struct rpl_group_info *rgi)
virtual int do_apply_event(rpl_group_info *rgi)
{ return Old_rows_log_event::do_apply_event(this, rgi); }
// primitives for old version of do_apply_event()
......@@ -556,7 +556,7 @@ class Delete_rows_log_event_old : public Old_rows_log_event
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
// use old definition of do_apply_event()
virtual int do_apply_event(struct rpl_group_info *rgi)
virtual int do_apply_event(rpl_group_info *rgi)
{ return Old_rows_log_event::do_apply_event(this, rgi); }
// primitives for old version of do_apply_event()
......
......@@ -62,7 +62,7 @@ rpl_slave_state::update_state_hash(uint64 sub_id, rpl_gtid *gtid)
int
rpl_slave_state::record_and_update_gtid(THD *thd, struct rpl_group_info *rgi)
rpl_slave_state::record_and_update_gtid(THD *thd, rpl_group_info *rgi)
{
uint64 sub_id;
......
......@@ -62,7 +62,7 @@ rpt_handle_event(rpl_parallel_thread::queued_event *qev,
struct rpl_parallel_thread *rpt)
{
int err;
struct rpl_group_info *rgi= qev->rgi;
rpl_group_info *rgi= qev->rgi;
Relay_log_info *rli= rgi->rli;
THD *thd= rgi->thd;
......@@ -128,8 +128,9 @@ handle_rpl_parallel_thread(void *arg)
old_msg= thd->proc_info;
thd->enter_cond(&rpt->COND_rpl_thread, &rpt->LOCK_rpl_thread,
"Waiting for work from SQL thread");
while (!rpt->stop && !thd->killed && !(events= rpt->event_queue))
while (!(events= rpt->event_queue) && !rpt->stop && !thd->killed)
mysql_cond_wait(&rpt->COND_rpl_thread, &rpt->LOCK_rpl_thread);
/* Mark that this thread is now executing */
rpt->free= false;
rpt->event_queue= rpt->last_in_queue= NULL;
thd->exit_cond(old_msg);
......@@ -145,9 +146,15 @@ handle_rpl_parallel_thread(void *arg)
uint64 wait_start_sub_id;
bool end_of_group;
/* Handle a new event group, which will be initiated by a GTID event. */
if (event_type == GTID_EVENT)
{
in_event_group= true;
/*
If the standalone flag is set, then this event group consists of a
single statement (possibly preceeded by some Intvar_log_event and
similar), without any terminating COMMIT/ROLLBACK/XID.
*/
group_standalone=
(0 != (static_cast<Gtid_log_event *>(events->ev)->flags2 &
Gtid_log_event::FL_STANDALONE));
......@@ -540,12 +547,12 @@ rpl_parallel::wait_for_done()
bool
rpl_parallel::do_event(struct rpl_group_info *serial_rgi, Log_event *ev)
rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev)
{
rpl_parallel_entry *e;
rpl_parallel_thread *cur_thread;
rpl_parallel_thread::queued_event *qev;
struct rpl_group_info *rgi;
rpl_group_info *rgi;
Relay_log_info *rli= serial_rgi->rli;
enum Log_event_type typ;
......
......@@ -23,7 +23,7 @@ struct rpl_parallel_thread {
struct queued_event {
queued_event *next;
Log_event *ev;
struct rpl_group_info *rgi;
rpl_group_info *rgi;
} *event_queue, *last_in_queue;
};
......@@ -59,7 +59,7 @@ struct rpl_parallel_entry {
mysql_mutex_t LOCK_parallel_entry;
mysql_cond_t COND_parallel_entry;
uint64 current_sub_id;
struct rpl_group_info *current_group_info;
rpl_group_info *current_group_info;
/*
The sub_id of the last event group in the previous batch of group-committed
transactions.
......@@ -78,7 +78,7 @@ struct rpl_parallel {
~rpl_parallel();
rpl_parallel_entry *find(uint32 domain_id);
void wait_for_done();
bool do_event(struct rpl_group_info *serial_rgi, Log_event *ev);
bool do_event(rpl_group_info *serial_rgi, Log_event *ev);
};
......
......@@ -1193,7 +1193,7 @@ bool Relay_log_info::cached_charset_compare(char *charset) const
void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
time_t event_creation_time, THD *thd,
struct rpl_group_info *rgi)
rpl_group_info *rgi)
{
#ifndef DBUG_OFF
extern uint debug_not_change_ts_if_art_event;
......@@ -1265,6 +1265,11 @@ void Relay_log_info::cleanup_context(THD *thd, bool error)
{
DBUG_ENTER("Relay_log_info::cleanup_context");
/*
In parallel replication, different THDs can be used from different
parallel threads. But in single-threaded mode, only the THD of the main
SQL thread is allowed.
*/
DBUG_ASSERT(opt_slave_parallel_threads > 0 || sql_thd == thd);
/*
1) Instances of Table_map_log_event, if ::do_apply_event() was called on them,
......@@ -1552,6 +1557,7 @@ event_group_new_gtid(rpl_group_info *rgi, Gtid_log_event *gev)
uint64 sub_id= rpl_global_gtid_slave_state.next_subid(gev->domain_id);
if (!sub_id)
{
/* Out of memory caused hash insertion to fail. */
return 1;
}
rgi->gtid_sub_id= sub_id;
......
......@@ -422,7 +422,7 @@ class Relay_log_info : public Slave_reporting_capability
*/
void stmt_done(my_off_t event_log_pos,
time_t event_creation_time, THD *thd,
struct rpl_group_info *rgi);
rpl_group_info *rgi);
/**
......@@ -521,10 +521,14 @@ class Relay_log_info : public Slave_reporting_capability
/*
This is data for various state needed to be kept for the processing of
one event group in the SQL thread.
one event group (transaction) during replication.
For single-threaded replication it is linked from the RLI, for parallel
replication it is linked into each event group being executed in parallel.
In single-threaded replication, there will be one global rpl_group_info and
one global Relay_log_info per master connection. They will be linked
together.
In parallel replication, there will be one rpl_group_info object for
each running thd. All rpl_group_info will share the same Relay_log_info.
*/
struct rpl_group_info
{
......@@ -555,7 +559,7 @@ struct rpl_group_info
for the wrong commit).
*/
uint64 wait_commit_sub_id;
struct rpl_group_info *wait_commit_group_info;
rpl_group_info *wait_commit_group_info;
/*
If non-zero, the event group must wait for this sub_id to be committed
before the execution of the event group is allowed to start.
......
......@@ -1143,7 +1143,7 @@ bool Deferred_log_events::is_empty()
return array.elements == 0;
}
bool Deferred_log_events::execute(struct rpl_group_info *rgi)
bool Deferred_log_events::execute(rpl_group_info *rgi)
{
bool res= false;
......
......@@ -3019,7 +3019,7 @@ static int has_temporary_error(THD *thd)
ev->update_pos().
*/
int apply_event_and_update_pos(Log_event* ev, THD* thd,
struct rpl_group_info *rgi,
rpl_group_info *rgi,
rpl_parallel_thread *rpt)
{
int exec_res= 0;
......
......@@ -80,7 +80,7 @@ void mysql_client_binlog_statement(THD* thd)
my_bool have_fd_event= TRUE;
int err;
Relay_log_info *rli;
struct rpl_group_info *rgi;
rpl_group_info *rgi;
rli= thd->rli_fake;
if (!rli)
......
......@@ -5666,6 +5666,10 @@ wait_for_commit::register_wait_for_prior_commit(wait_for_commit *waitee)
waiting_for_commit= false;
else
{
/*
Put ourself at the head of the waitee's list of transactions that must
wait for it to commit first.
*/
this->next_subsequent_commit= waitee->subsequent_commits_list;
waitee->subsequent_commits_list= this;
}
......@@ -5704,7 +5708,7 @@ wait_for_commit::wait_for_prior_commit2()
The waiter needs to lock the waitee to delete itself from the list in
unregister_wait_for_prior_commit(). Thus wakeup_subsequent_commits() can not
hold its own lock while locking waiters, lest we deadlock.
hold its own lock while locking waiters, as this could lead to deadlock.
So we need to prevent unregister_wait_for_prior_commit() running while wakeup
is in progress - otherwise the unregister could complete before the wakeup,
......@@ -5727,6 +5731,7 @@ wait_for_commit::wait_for_prior_commit2()
would not be woken up until next wakeup, which could be potentially much
later than necessary.
*/
void
wait_for_commit::wakeup_subsequent_commits2()
{
......
......@@ -1615,7 +1615,7 @@ struct wait_for_commit
*/
bool waiting_for_commit;
/*
Flag set when wakeup_subsequent_commits_running() is active, see commonts
Flag set when wakeup_subsequent_commits_running() is active, see comments
on that function for details.
*/
bool wakeup_subsequent_commits_running;
......
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