From: Andrei Elkin Date: December 7 2010 6:03pm Subject: bzr push into mysql-next-mr-wl5569 branch (andrei.elkin:3232) List-Archive: http://lists.mysql.com/commits/126251 Message-Id: <201012071803.oB7I3oLt032547@mysql1000.dsl.inet.fi> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0819934548==" --===============0819934548== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline 3232 Andrei Elkin 2010-12-07 [merge] manual merge with a piece of recovery support on repo. rpl_parallel hits an assert that Alfranio is fixing modified: mysql-test/suite/rpl/r/rpl_parallel.result mysql-test/suite/rpl/t/rpl_parallel-slave.opt mysql-test/suite/rpl/t/rpl_parallel.test sql/rpl_info_dummy.cc sql/rpl_info_dummy.h sql/rpl_info_factory.cc sql/rpl_info_file.cc sql/rpl_info_file.h sql/rpl_info_handler.h sql/rpl_info_table.cc sql/rpl_info_table.h sql/rpl_mi.cc sql/rpl_rli.cc sql/rpl_rli.h sql/rpl_rli_pdb.cc sql/rpl_rli_pdb.h sql/rpl_slave.cc sql/rpl_slave.h === modified file 'mysql-test/extra/rpl_tests/rpl_parallel_load.test' --- a/mysql-test/extra/rpl_tests/rpl_parallel_load.test 2010-12-04 17:14:50 +0000 +++ b/mysql-test/extra/rpl_tests/rpl_parallel_load.test 2010-12-07 17:35:16 +0000 @@ -87,17 +87,8 @@ while($i) --enable_query_log -#connection slave; - -# Exec log position is not accurate in the prototype ---sleep 2 ---disable_query_log ---disable_result_log -###select sleep(300); ---enable_result_log ---enable_query_log - sync_slave_with_master; +#connection slave; --disable_query_log --disable_result_log @@ -213,11 +204,6 @@ connection slave; --disable_query_log --disable_result_log -### --sleep 15 # todo: convert to wait for the last event has been applied - ---echo *** you can connect and change the exec mode as well now *** ---echo *** and select * from benchmark before to run consistency check *** - insert into test0.benchmark set state='slave is processing load'; # To force filling timestamp cols with the slave local clock values @@ -239,13 +225,6 @@ select ts from test0.benchmark where sta select time_to_sec(@m_1) - time_to_sec(@m_0) as 'delta_m', time_to_sec(@s_1) - time_to_sec(@s_0) as 'delta_s' into outfile 'delta.out'; -# debug: pre diff check-out ---disable_result_log ---disable_query_log -##select sleep(9999); ---enable_result_log ---enable_query_log - let $i = $databases + 1; while($i) { @@ -262,13 +241,6 @@ while($i) --enable_result_log --enable_query_log -# debug: pre diff check-out ---disable_result_log ---disable_query_log -##select sleep(9999); ---enable_result_log ---enable_query_log - connection master; @@ -288,12 +260,8 @@ while($i) --enable_result_log --enable_query_log -connection slave; - -# same as above - prototype Exec pos in not accurate ---sleep 5 - -#sync_slave_with_master; +sync_slave_with_master; +#connection slave; -# End of 4.1 tests +# End of the tests === modified file 'mysql-test/suite/rpl/r/rpl_parallel.result' --- a/mysql-test/suite/rpl/r/rpl_parallel.result 2010-12-07 03:05:41 +0000 +++ b/mysql-test/suite/rpl/r/rpl_parallel.result 2010-12-07 18:01:39 +0000 @@ -12,8 +12,6 @@ call mtr.add_suppression('Slave: Error d include/stop_slave.inc start slave; stop slave sql_thread; -*** you can connect and change the exec mode as well now *** -*** and select * from benchmark before to run consistency check *** use test; select * from test0.benchmark into outfile 'benchmark.out'; select ts from test0.benchmark where state like 'master started load' into @m_0; === modified file 'mysql-test/suite/rpl/r/rpl_parallel_conf_limits.result' --- a/mysql-test/suite/rpl/r/rpl_parallel_conf_limits.result 2010-12-02 17:46:46 +0000 +++ b/mysql-test/suite/rpl/r/rpl_parallel_conf_limits.result 2010-12-07 17:35:16 +0000 @@ -4,7 +4,9 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -create view coord_wait_list as SELECT id from Information_Schema.processlist where state like 'Waiting for Slave Worker%'; +create view coord_wait_list as +SELECT id from Information_Schema.processlist +where state like 'Waiting for Slave Worker%'; include/stop_slave.inc set @save.slave_parallel_workers= @@global.slave_parallel_workers; set @@global.slave_parallel_workers= 4; @@ -13,9 +15,6 @@ set @@global.mts_slave_worker_queue_len_ include/start_slave.inc create database d0; create table d0.t1 (a int auto_increment primary key) engine=innodb; -select sleep(2); -sleep(2) -0 begin; insert into d0.t1 set a=null; begin; === modified file 'mysql-test/suite/rpl/r/rpl_sequential.result' --- a/mysql-test/suite/rpl/r/rpl_sequential.result 2010-12-02 17:46:46 +0000 +++ b/mysql-test/suite/rpl/r/rpl_sequential.result 2010-12-07 17:35:16 +0000 @@ -12,8 +12,6 @@ call mtr.add_suppression('Slave: Error d include/stop_slave.inc start slave; stop slave sql_thread; -*** you can connect and change the exec mode as well now *** -*** and select * from benchmark before to run consistency check *** use test; select * from test0.benchmark into outfile 'benchmark.out'; select ts from test0.benchmark where state like 'master started load' into @m_0; === modified file 'mysql-test/suite/rpl/t/disabled.def' --- a/mysql-test/suite/rpl/t/disabled.def 2010-09-06 12:52:04 +0000 +++ b/mysql-test/suite/rpl/t/disabled.def 2010-12-07 17:35:16 +0000 @@ -12,3 +12,4 @@ rpl_row_create_table : Bug#51574 2010-02-27 andrei failed different way than earlier with bug#45576 rpl_spec_variables : BUG#47661 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux +rpl_row_ignorable_event : Bug#58784 7-12-2010 andrei rpl_row_ignorable_event fails on PB2 === modified file 'mysql-test/suite/rpl/t/rpl_parallel_conf_limits.test' --- a/mysql-test/suite/rpl/t/rpl_parallel_conf_limits.test 2010-12-02 17:46:46 +0000 +++ b/mysql-test/suite/rpl/t/rpl_parallel_conf_limits.test 2010-12-07 17:35:16 +0000 @@ -2,8 +2,11 @@ # WL#5569 MTS # # The test verifies correctness of MTS execution when system meets -# various limits due to configuration options. +# various limits due to few configuration options: # +# @@global.mts_pending_jobs_size_max +# @@global.mts_slave_worker_queue_len_max +# @@global.mts_partition_hash_soft_max source include/master-slave.inc; # no support for Query-log-event in this test @@ -11,7 +14,9 @@ source include/have_binlog_format_row.in connection slave; -create view coord_wait_list as SELECT id from Information_Schema.processlist where state like 'Waiting for Slave Worker%'; +create view coord_wait_list as + SELECT id from Information_Schema.processlist + where state like 'Waiting for Slave Worker%'; # restart in Parallel source include/stop_slave.inc; @@ -30,9 +35,8 @@ create database d0; create table d0.t1 (a int auto_increment primary key) engine=innodb; -connection slave; +sync_slave_with_master; -select sleep(2); begin; insert into d0.t1 set a=null; # lock a row that master has inserted into @@ -87,14 +91,8 @@ source include/start_slave.inc; connection master; create table d0.t2 (a int auto_increment primary key, b text null) engine=innodb; -connection slave; +sync_slave_with_master; -# sync_slave_with_master ---disable_query_log ---disable_result_log -select sleep(2); ---enable_result_log ---enable_query_log begin; insert into d0.t2 set a= 1; @@ -180,17 +178,8 @@ while ($i) dec $i; } -# TODO: +sync_slave_with_master; -connection slave; - ---disable_query_log ---disable_result_log -select sleep(1); ---enable_result_log ---enable_query_log - -#sync_slave_with_master set @@global.mts_partition_hash_soft_max= @save.mts_partition_hash_soft_max; connection master; @@ -203,8 +192,8 @@ while ($i) } -connection slave; -#sync_slave_with_master +#connection slave; +sync_slave_with_master; # @@ -216,13 +205,10 @@ connection master; drop database d0; -# sync_slave_with_master -connection slave; +sync_slave_with_master; +#connection slave; drop view coord_wait_list; - ---sleep 2 - set @@global.slave_parallel_workers= @save.slave_parallel_workers; === modified file 'mysql-test/suite/rpl/t/rpl_parallel_conflicts.test' --- a/mysql-test/suite/rpl/t/rpl_parallel_conflicts.test 2010-12-02 17:46:46 +0000 +++ b/mysql-test/suite/rpl/t/rpl_parallel_conflicts.test 2010-12-07 17:35:16 +0000 @@ -67,14 +67,9 @@ create table d3.t1 (a int auto_increment # # two conflicting jobs to follow -# sync_slave_with_master - -# TODO: remove once `sync_slave_with_master' got fixed - ---sleep 3 - +sync_slave_with_master; # To be really conflicting slave needs to block commit of the first. -connection slave; +#connection slave; begin; insert into d2.t1 values (1); @@ -210,10 +205,8 @@ drop database d1; drop database d2; drop database d3; ---sleep 4 - -connection slave; -#sync_slave_with_master; +sync_slave_with_master; +#connection slave; drop view coord_wait_list; set @@global.slave_parallel_workers= @save.slave_parallel_workers; === modified file 'mysql-test/suite/rpl/t/rpl_parallel_start_stop.test' --- a/mysql-test/suite/rpl/t/rpl_parallel_start_stop.test 2010-12-02 17:46:46 +0000 +++ b/mysql-test/suite/rpl/t/rpl_parallel_start_stop.test 2010-12-07 17:35:16 +0000 @@ -53,12 +53,6 @@ source include/wait_until_rows_count.inc select id from coord_proc_list into @c_id; ---disable_query_log ---disable_result_log -#select sleep(300); ---enable_query_log ---enable_result_log - kill query @c_id; let $count= 0; @@ -80,20 +74,10 @@ CREATE TABLE t1 (a int primary key); insert into t1 values (1),(2); -# -# todo: remove when recovery recovers `sync_slave_with_master' -# - ---sleep 3 ---disable_result_log ---disable_query_log -#select sleep(600); ---enable_result_log ---enable_query_log +sync_slave_with_master; +#connection slave; -connection slave; -# sync_slave_with_master; let $count= 2; let $table= t1; source include/wait_until_rows_count.inc; @@ -112,12 +96,6 @@ let $count= 0; let $table= worker_proc_list; source include/wait_until_rows_count.inc; ---disable_result_log ---disable_query_log -#select sleep(600); ---enable_result_log ---enable_query_log - source include/wait_for_slave_sql_to_stop.inc; delete from t1; @@ -128,14 +106,8 @@ source include/start_slave.inc; connection master; drop table t1; -# -# todo: remove when recovery recovers `sync_slave_with_master' -# - ---sleep 3 - -connection slave; -#sync_slave_with_master; +sync_slave_with_master; +#connection slave; drop view worker_proc_list; drop view coord_proc_list; === modified file 'sql/log_event.cc' --- a/sql/log_event.cc 2010-12-05 20:04:17 +0000 +++ b/sql/log_event.cc 2010-12-07 17:35:16 +0000 @@ -2527,8 +2527,8 @@ int Log_event::apply_event(Relay_log_inf { if (parallel) { - // This case relates to Query parallel apply which breaks into - // DDL and {B, Q, T} group, where Q owns g-parallel property. + // This `only-sequential' case relates to Query parallel apply which + // breaks into DDL and {B, Q, T} group, where Q owns g-parallel property. // Apply possibly deferred B if (rli->curr_group_da.elements > 0) @@ -2539,9 +2539,16 @@ int Log_event::apply_event(Relay_log_inf DBUG_ASSERT(rli->curr_group_da.elements == 0); DBUG_ASSERT(rli->curr_group_seen_begin); - // TODO: rollback - // c_rli->gaq->assigned_group_index= rli->gaq->en_queue((void *) &g); + // While Query-log-event is not supported GAQ needs rollback + if (rli->curr_group_seen_begin) + { + Slave_job_group g; + ulong ind= rli->gaq->de_tail((uchar *) &g); + const_cast(rli)->mts_total_groups--; + DBUG_ASSERT(rli->last_assigned_worker == NULL); + DBUG_ASSERT(c_rli->gaq->assigned_group_index == ind); + } res= ev_begin->do_apply_event(rli); delete ev_begin; /* B appears to be serial, reset parallel status of group @@ -2716,6 +2723,13 @@ int slave_worker_exec_job(Slave_worker * w->slave_worker_ends_group(ev, error); /* last done sets post exec */ } + /* + commit_positions() fullfils group pos incr and flush + TODO: remove + if (!error) + ev->update_pos(w->w_rli); + */ + mysql_mutex_lock(&w->jobs_lock); de_queue(&w->jobs, job_item); @@ -2725,17 +2739,6 @@ int slave_worker_exec_job(Slave_worker * w->jobs.overfill= FALSE; mysql_cond_signal(&w->jobs_cond); } - - /* - preserving signatures of existing methods. - todo: convert update_pos(w->w_rli) -> update_pos(w) - to remove w_rli w/a - TODO: remove ? - */ - if (!error) - ev->update_pos(w->w_rli); - - mysql_mutex_unlock(&w->jobs_lock); /* statistics */ @@ -2786,9 +2789,8 @@ int slave_worker_exec_job(Slave_worker * err: - // TODO!!! ANDREI to RESTORE - // if (!ev) - // delete ev; // after ev->update_pos() event is garbage + if (!ev) + delete ev; // after ev->update_pos() event is garbage DBUG_RETURN(error); } === modified file 'sql/log_event.h' --- a/sql/log_event.h 2010-11-27 15:36:50 +0000 +++ b/sql/log_event.h 2010-12-07 17:35:16 +0000 @@ -1197,7 +1197,7 @@ public: } /** - MST: some events can be applied by Coordinator concurrently with Workers. + MST: some events have to be applied by Coordinator concurrently with Workers. @return TRUE if that's the case, FALSE otherwise. === modified file 'sql/rpl_rli_pdb.cc' --- a/sql/rpl_rli_pdb.cc 2010-12-07 03:05:41 +0000 +++ b/sql/rpl_rli_pdb.cc 2010-12-07 18:01:39 +0000 @@ -593,6 +593,33 @@ ulong circular_buffer_queue::de_queue(uc return ret; } +/** + removing an item from the tail side +*/ +ulong circular_buffer_queue::de_tail(uchar *val) +{ + ulong ret; + if (e == s) + { + DBUG_ASSERT(len == 0); + return (ulong) -1; + } + + a= (e + len - 1) % s; + get_dynamic(&Q, val, a); + len--; + + // post boundary cond + if (a == e) + e= s; + + DBUG_ASSERT(e == s || + (len == (a >= e)? (a - e) : + (s + a - e))); + + return a; + +} /** @return the used index at success or -1 when queue is full */ === modified file 'sql/rpl_rli_pdb.h' --- a/sql/rpl_rli_pdb.h 2010-12-07 03:05:41 +0000 +++ b/sql/rpl_rli_pdb.h 2010-12-07 18:01:39 +0000 @@ -67,10 +67,14 @@ public: location. @return the queue's array index that the de-queued item - locates at, or + located at, or an error encoded in beyond the index legacy range. */ ulong de_queue(uchar *); + /** + Similar to de_queue but extracting happens from the tail side. + */ + ulong de_tail(uchar *val); /** return the index where the arg item locates === modified file 'sql/rpl_slave.cc' --- a/sql/rpl_slave.cc 2010-12-07 03:05:41 +0000 +++ b/sql/rpl_slave.cc 2010-12-07 18:01:39 +0000 @@ -168,7 +168,7 @@ static int terminate_slave_thread(THD *t bool skip_lock); static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info); int slave_worker_exec_job(Slave_worker * w, Relay_log_info *rli); -bool mts_checkpoint_routine(Relay_log_info *rli, ulong period); +static bool mts_checkpoint_routine(Relay_log_info *rli, ulong period, bool locked); bool mts_recovery_routine(Relay_log_info *rli); /* @@ -3690,7 +3690,7 @@ bool mts_recovery_routine(Relay_log_info @return FALSE success, TRUE otherwise */ -bool mts_checkpoint_routine(Relay_log_info *rli, ulong period) +bool mts_checkpoint_routine(Relay_log_info *rli, ulong period, bool locked) { ulong cnt; bool error= FALSE; @@ -3723,7 +3723,8 @@ bool mts_checkpoint_routine(Relay_log_in }; sort_dynamic(&rli->least_occupied_workers, (qsort_cmp) ulong_cmp); - mysql_mutex_lock(&rli->data_lock); + if (!locked) + mysql_mutex_lock(&rli->data_lock); // Coordinator::commit_positions() { @@ -3732,6 +3733,9 @@ bool mts_checkpoint_routine(Relay_log_in // group_master_log_name is updated only by Coordinator and it can't change // within checkpoint interval because Coordinator flushes the updated value // at once. + // Note, unlike group_master_log_name, event_relay_log_pos is updated solely + // within Coordinator read loop context. Hence, it's possible at times + // event_rlp > group_rlp. rli->set_group_master_log_pos(rli->gaq->lwm.group_master_log_pos); rli->set_group_relay_log_pos(rli->gaq->lwm.group_relay_log_pos); @@ -3739,21 +3743,23 @@ bool mts_checkpoint_routine(Relay_log_in if (rli->gaq->lwm.group_relay_log_name[0] != 0) rli->set_group_relay_log_name(rli->gaq->lwm.group_relay_log_name); - error= rli->flush_info(TRUE); + //todo: uncomment notifies when UNTIL will be supported - // end of commit_positions - - rli->notify_group_relay_log_name_update(); - rli->notify_group_master_log_name_update(); + //rli->notify_group_master_log_name_update(); + //rli->notify_group_relay_log_name_update(); + // todo: optimize with if (wait_flag) broadcast + // waiter: set wait_flag; waits....; drops wait_flag; mysql_cond_broadcast(&rli->data_cond); + if (!locked) + mysql_mutex_unlock(&rli->data_lock); - mysql_mutex_unlock(&rli->data_lock); + error= rli->flush_info(TRUE); + // end of commit_positions end: set_timespec_nsec(rli->last_clock, 0); - // ANDREI NOTIFICATIONS? DBUG_RETURN(error); } @@ -5326,10 +5332,13 @@ static Log_event* next_event(Relay_log_i rli->set_future_event_relay_log_pos(my_b_tell(cur_log)); ev->future_event_relay_log_pos= rli->get_future_event_relay_log_pos(); + /* + MTS checkpoint in the successful read branch + */ if (rli->is_parallel_exec() && rli->lwm_period != 0.0) { ulong period= rli->lwm_period * 1000000000UL; - mts_checkpoint_routine(rli, period); // ALFRANIO --- WHAT TO DO with ERRORS? + mts_checkpoint_routine(rli, period, TRUE); // ALFRANIO --- WHAT TO DO with ERRORS? } if (hot_log) @@ -5458,7 +5467,7 @@ static Log_event* next_event(Relay_log_i ulong period= rli->lwm_period * 1000000000UL; do { - mts_checkpoint_routine(rli, period); // ALFRANIO ERROR + mts_checkpoint_routine(rli, period, FALSE); // ALFRANIO ERROR set_timespec_nsec(waittime, period); thd->enter_cond(log_cond, log_lock, "Slave has read all relay log; " --===============0819934548== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/andrei.elkin@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: andrei.elkin@stripped # target_branch: file:///home/andrei/MySQL/BZR/2a-23May/WL/mysql-next-\ # mr-wl5569/ # testament_sha1: 6d042c48ec6f0a8a279ddc01082ec07395373b5f # timestamp: 2010-12-07 20:03:50 +0200 # base_revision_id: alfranio.correia@stripped\ # bt3cc1l4pohgzhtt # # Begin bundle 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 --===============0819934548==--