#At file:///home/andrei/MySQL/BZR/2a-23May/MERGE/mysql-next-mr-wl5569/ based on revid:andrei.elkin@stripped
3287 Andrei Elkin 2011-06-14
wl#5569 MTS
Fixing failing tests due to
a. a flaw in `isolated parallel' mode implementation.
Isolation applies to a group of event rather than to an instance.
And event that contains over-max accessed db:s or event from Old master
trigger marking the current being scheduled group. Such group will be executed
having all prior scheduled done and nomore will be scheduled until the group
is done.
b. Notification to Coordinator about errored-out Worker is corrected.
@ sql/log_event.cc
isolation applies to a group of event rather than to an instance.
Logics of isolation while the group is still executed by a Worker
is refined through use of `bool curr_group_isolated' that lasts the group
sceduling time and is set and reset in Log_event::get_slave_worker_id().
Assert is added to monitor tmp tables correct migration.
get_slave_worker() is called with `need_temp_tables' set to TRUE.
@ sql/log_event.h
Renaming to indicate that isolation applies to a group of event.
Adding more candidate event to mts_do_isolate_group() assert.
@ sql/rpl_rli.h
Isolation mode related declaration.
@ sql/rpl_rli_pdb.cc
Refining notification logics. Coordinator needs both its THD::KILLED and signalling
to slave_worker_hash_cond.
@ sql/rpl_slave.cc
Isolation mode related init-ion.
modified:
sql/log_event.cc
sql/log_event.h
sql/rpl_rli.h
sql/rpl_rli_pdb.cc
sql/rpl_slave.cc
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2011-06-12 19:05:05 +0000
+++ b/sql/log_event.cc 2011-06-14 09:27:38 +0000
@@ -673,7 +673,7 @@ Log_event::Log_event(enum_event_cache_ty
event_logging_type(logging_type_arg), crc(0), thd(0),
checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- , m_mts_event_ends_group(FALSE)
+ , m_mts_event_isolated_group(FALSE)
#endif
{
server_id= ::server_id;
@@ -698,7 +698,7 @@ Log_event::Log_event(const char* buf,
event_logging_type(EVENT_INVALID_LOGGING),
crc(0), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- , m_mts_event_ends_group(FALSE)
+ , m_mts_event_isolated_group(FALSE)
#endif
{
#ifndef MYSQL_CLIENT
@@ -2428,6 +2428,7 @@ Slave_worker *Log_event::get_slave_worke
ulong gaq_idx;
rli->mts_total_groups++;
+ rli->curr_group_isolated= FALSE;
g.master_log_pos= log_pos;
g.group_master_log_pos= g.group_relay_log_pos= 0;
g.group_master_log_name= NULL; // todo: remove
@@ -2483,6 +2484,8 @@ Slave_worker *Log_event::get_slave_worke
if (!ret_worker)
ret_worker= *(Slave_worker**) dynamic_array_ptr(&rli->workers, 0);
(void) wait_for_workers_to_finish(rli, ret_worker);
+
+ rli->curr_group_isolated= TRUE;
}
do
@@ -2492,8 +2495,7 @@ Slave_worker *Log_event::get_slave_worke
if (!(ret_worker=
get_slave_worker(*ref_cur_db, rli,
&mts_assigned_partitions[i],
- get_type_code() == QUERY_EVENT,
- ret_worker)))
+ TRUE, ret_worker)))
{
rli->report(ERROR_LEVEL, ER_MTS_CANT_PARALLEL,
ER(ER_MTS_CANT_PARALLEL),
@@ -2501,7 +2503,8 @@ Slave_worker *Log_event::get_slave_worke
rli->get_event_relay_log_pos());
return ret_worker;
}
-
+ // all temporary tables are transferred from Coordinator in over-max case
+ DBUG_ASSERT(num_dbs != OVER_MAX_DBS_IN_EVENT_MTS || !thd->temporary_tables);
DBUG_ASSERT(!strcmp(mts_assigned_partitions[i]->db, *ref_cur_db));
DBUG_ASSERT(ret_worker == mts_assigned_partitions[i]->worker);
DBUG_ASSERT(mts_assigned_partitions[i]->usage > 0);
@@ -2589,10 +2592,12 @@ Slave_worker *Log_event::get_slave_worke
{
// index of GAQ that this terminal event belongs to
mts_group_cnt= rli->gaq->assigned_group_index;
-
- // special marking for T event of {p,g} B-less group
- if (num_dbs == OVER_MAX_DBS_IN_EVENT_MTS)
- mts_do_isolate_event();
+ /*
+ special marking for T event of a group containing over-max db:s event
+ including {p,g} B-less group.
+ */
+ if (rli->curr_group_isolated)
+ mts_do_isolate_group();
rli->mts_group_status= Relay_log_info::MTS_END_GROUP;
ptr_g= (Slave_job_group *)
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2011-06-12 19:05:05 +0000
+++ b/sql/log_event.h 2011-06-14 09:27:38 +0000
@@ -1350,26 +1350,23 @@ public:
virtual uint8 mts_number_dbs() { return 1; }
/*
- Event can be exceptionally marked to force its execution.
+ Group of events can be marked to force its execution
in isolation from any other Workers.
- Other than Query-log-event class should not have any implementation
- of this method.
+ Typically that is done for a transaction that contains
+ a query accessing more than OVER_MAX_DBS_IN_EVENT_MTS db:s
*/
- /*
- Event can be indentified as a group terminator and such fact
- is memoried by the function.
- */
- virtual void mts_do_isolate_event()
+ virtual void mts_do_isolate_group()
{
- DBUG_ASSERT(get_type_code() == QUERY_EVENT ||
+ DBUG_ASSERT(ends_group() ||
+ get_type_code() == QUERY_EVENT ||
get_type_code() == EXEC_LOAD_EVENT ||
get_type_code() == EXECUTE_LOAD_QUERY_EVENT);
- m_mts_event_ends_group= TRUE;
+ m_mts_event_isolated_group= TRUE;
}
/*
Verifying whether event is marked to execute in isolation.
*/
- virtual bool mts_is_event_isolated() { return m_mts_event_ends_group; }
+ virtual bool mts_is_group_isolated() { return m_mts_event_isolated_group; }
/**
Apply the event to the database.
@@ -1505,7 +1502,7 @@ protected:
*/
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
- bool m_mts_event_ends_group;
+ bool m_mts_event_isolated_group;
#endif
};
=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h 2011-06-12 19:05:05 +0000
+++ b/sql/rpl_rli.h 2011-06-14 09:27:38 +0000
@@ -448,6 +448,7 @@ public:
DYNAMIC_ARRAY curr_group_assigned_parts; // CGAP
DYNAMIC_ARRAY curr_group_da; // deferred array to hold partition-info-free events
bool curr_group_seen_begin; // current group started with B-event or not
+ bool curr_group_isolated; // current group requires execution in isolation
volatile ulong mts_wqs_underrun_w_id; // Id of a Worker whose queue is getting empty
volatile long mts_wqs_overrun; // W to incr and decr
ulong mts_wqs_underrun_cnt; // Coord goes to sleep when senses Workers are content
=== modified file 'sql/rpl_rli_pdb.cc'
--- a/sql/rpl_rli_pdb.cc 2011-06-12 17:36:17 +0000
+++ b/sql/rpl_rli_pdb.cc 2011-06-14 09:27:38 +0000
@@ -280,6 +280,7 @@ static void free_entry(db_worker_hash_en
DBUG_ASSERT(c_thd->system_thread == SYSTEM_THREAD_SLAVE_SQL);
DBUG_ASSERT(entry->usage == 0 ||
+ !entry->worker || // the last entry owner could have errored out
entry->worker->running_status != Slave_worker::RUNNING);
mts_move_temp_tables_to_thd(c_thd, entry->temporary_tables);
@@ -825,12 +826,14 @@ void Slave_worker::slave_worker_ends_gro
if (error)
{
- mysql_mutex_lock(&slave_worker_hash_lock);
+ // Killing Coordinator to indicate eventual consistency error
mysql_mutex_lock(&c_rli->info_thd->LOCK_thd_data);
-
- c_rli->info_thd->awake(THD::KILL_QUERY); // notify Crdn
-
+ c_rli->info_thd->awake(THD::KILL_QUERY);
mysql_mutex_unlock(&c_rli->info_thd->LOCK_thd_data);
+
+ // Awakening Coordinator that could be waiting for entry release
+ mysql_mutex_lock(&slave_worker_hash_lock);
+ mysql_cond_signal(&slave_worker_hash_cond);
mysql_mutex_unlock(&slave_worker_hash_lock);
}
@@ -1138,8 +1141,8 @@ int wait_for_workers_to_finish(Relay_log
if (entry->usage > 0 && !thd->killed)
{
- long w_id= entry->worker->id;
- sprintf(wait_info, info_format, entry->worker->id, entry->db);
+ Slave_worker * w_entry= entry->worker;
+ sprintf(wait_info, info_format, w_entry->id, entry->db);
entry->worker= NULL; // mark Worker to signal when usage drops to 0
do
{
@@ -1150,8 +1153,9 @@ int wait_for_workers_to_finish(Relay_log
DBUG_PRINT("info",
("Either got awakened of notified: "
"entry %p, usage %lu, worker %lu",
- entry, entry->usage, w_id));
+ entry, entry->usage, w_entry->id));
} while (entry->usage != 0 && !thd->killed);
+ entry->worker= w_entry; // restoring last association, needed only for assert
thd->exit_cond(proc_info);
ret++;
}
=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc 2011-06-12 19:05:05 +0000
+++ b/sql/rpl_slave.cc 2011-06-14 09:27:38 +0000
@@ -2769,8 +2769,8 @@ int apply_event_and_update_pos(Log_event
{
Slave_job_item item= {ev}, *job_item= &item;
Slave_worker *w= (Slave_worker *) ev->worker;
- // specially marked end of B-less group event requires sync with worker
- bool need_sync= ev->mts_is_event_isolated();
+ // specially marked group typically with OVER_MAX_DBS_IN_EVENT_MTS db:s
+ bool need_sync= ev->mts_is_group_isolated();
// all events except BEGIN-query must be marked with a non-NULL Worker
DBUG_ASSERT(((Slave_worker*) ev->worker) == rli->last_assigned_worker);
@@ -4195,6 +4195,7 @@ int slave_start_workers(Relay_log_info *
rli->mts_worker_underrun_level= ::opt_mts_worker_underrun_level;
rli->mts_total_groups= 0;
rli->curr_group_seen_begin= FALSE;
+ rli->curr_group_isolated= FALSE;
rli->checkpoint_seqno= 0;
rli->mts_group_status= Relay_log_info::MTS_NOT_IN_GROUP;
/*
Attachment: [text/bzr-bundle] bzr/andrei.elkin@oracle.com-20110614092738-5xnta7fh42l4m3xj.bundle
| Thread |
|---|
| • bzr commit into mysql-next-mr-wl5569 branch (andrei.elkin:3287) WL#5569 | Andrei Elkin | 14 Jun |