From: Andrei Elkin Date: June 12 2011 7:35pm Subject: bzr push into mysql-next-mr-wl5569 branch (andrei.elkin:3284 to 3286) WL#5569 List-Archive: http://lists.mysql.com/commits/139120 Message-Id: <201106121935.p5CJZEkE007250@mysql1000.dsl.inet.fi> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1508118910==" --===============1508118910== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline 3286 Andrei Elkin 2011-06-12 wl#5569 MTS making default.push to run rpl suite with non-default --mts-slave-parallel-workers > 0 in all three format/mode (row,stmt, mixed). The default is run for all suites in mixed mode and rpl suites with row+ps, stmt formats. modified: mysql-test/collections/default.push 3285 Andrei Elkin 2011-06-12 [merge] wl#5569 MTS manual merge with few fixes for segfault of the last merge from the trunk etc, compilation issue on embedded. added: mysql-test/suite/rpl/r/rpl_parallel_seconds_behind_master.result mysql-test/suite/rpl/t/rpl_parallel_seconds_behind_master-slave.opt mysql-test/suite/rpl/t/rpl_parallel_seconds_behind_master.test modified: mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test mysql-test/suite/rpl/r/rpl_parallel_benchmark.result mysql-test/suite/rpl/r/rpl_slave_grp_exec.result mysql-test/suite/rpl/t/rpl_bug26395.test mysql-test/suite/rpl/t/rpl_cross_version.test mysql-test/suite/rpl/t/rpl_packet.test mysql-test/suite/rpl/t/rpl_seconds_behind_master.test mysql-test/suite/rpl/t/rpl_slave_grp_exec.test sql/binlog.cc sql/events.cc sql/log_event.cc sql/log_event.h sql/rpl_rli.cc sql/rpl_rli.h sql/rpl_rli_pdb.cc sql/rpl_rli_pdb.h sql/rpl_slave.cc sql/share/errmsg-utf8.txt sql/sp.cc sql/sql_acl.cc sql/sql_class.h sql/sql_db.cc sql/sql_rename.cc sql/sql_table.cc sql/sql_trigger.cc sql/sql_view.cc storage/blackhole/ha_blackhole.cc 3284 Alfranio Correia 2011-06-09 Post-fixes for merge. Fixed compilation in Windows and removed an used options. modified: mysql-test/extra/rpl_tests/rpl_crash_safe.inc mysql-test/suite/rpl/r/rpl_row_crash_safe.result mysql-test/suite/rpl/r/rpl_stm_mixed_crash_safe.result mysql-test/suite/rpl/t/rpl_mixed_parallel_crash_safe-slave.opt mysql-test/suite/rpl/t/rpl_row_crash_safe-slave.opt mysql-test/suite/rpl/t/rpl_row_parallel_crash_safe-slave.opt mysql-test/suite/rpl/t/rpl_stm_mixed_crash_safe-slave.opt mysql-test/suite/rpl/t/rpl_stm_parallel_crash_safe-slave.opt sql/mysqld.cc sql/mysqld.h sql/rpl_info_factory.cc sql/sql_base.cc === modified file 'mysql-test/collections/default.push' --- a/mysql-test/collections/default.push 2011-03-23 11:37:04 +0000 +++ b/mysql-test/collections/default.push 2011-06-12 19:33:32 +0000 @@ -1,3 +1,11 @@ -perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list --unit-tests -perl mysql-test-run.pl --timer --force --parallel=auto --comment=main_ps_row --vardir=var-main-ps_row --suite=main --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list -perl mysql-test-run.pl --timer --force --parallel=auto --comment=main_embedded --vardir=var-main_emebbed --suite=main --embedded --experimental=collections/default.experimental --skip-ndb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb --unit-tests + +perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_ps_row --vardir=var-rpl-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --suite=rpl + +perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_stmt --vardir=var-rpl-stmt --mysqld=--binlog-format=statement --experimental=collections/default.experimental --skip-ndb --suite=rpl + +perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_n_mix_MTS --vardir=var-rpl-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb --unit-tests --mysqld=--mts-slave-parallel-workers=4 --mysqld=--slave-transaction-retries=0 --suite=rpl + +perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_ps_row_MTS --vardir=var-rpl-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --mysqld=--mts-slave-parallel-workers=4 --mysqld=--slave-transaction-retries=0 --suite=rpl + +perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_stmt_rpl_MTS --vardir=var-rpl-stmt --mysqld=--binlog-format=statement --experimental=collections/default.experimental --skip-ndb --mysqld=--mts-slave-parallel-workers=4 --mysqld=--slave-transaction-retries=0 --suite=rpl === modified file 'mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test' --- a/mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test 2011-06-05 17:01:51 +0000 +++ b/mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test 2011-06-12 17:36:17 +0000 @@ -6,13 +6,13 @@ # load volume parameter # -let $iter= 08; -let $tables= 4; -let $wk_i_queries= 4; +let $iter= 02; +let $tables= 2; +let $wk_i_queries= 2; let $wk_m_queries= 0; let $nk_i_queries= 0; let $nk_m_queries= 0; -let $pre_inserted_rows= 200; +let $pre_inserted_rows= 50; connection slave; @@ -264,14 +264,22 @@ let $wait_timeout= 600; let $wait_condition= SELECT count(*)+sleep(1) = 5 FROM test1.benchmark; source include/wait_condition.inc; + +let $MYSQLD_DATADIR= `select @@datadir`; + +# cleanup for files that could not be removed in the end of previous invocation. +--remove_files_wildcard $MYSQLD_DATADIR *.out + use test; -select * from test1.benchmark into outfile 'benchmark.out'; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval select * from test1.benchmark into outfile '$MYSQLD_DATADIR/benchmark.out'; select ts from test1.benchmark where state like 'master started load' into @m_0; select ts from test1.benchmark where state like 'master ends load' into @m_1; select ts from test1.benchmark where state like 'slave takes on load' into @s_0; select ts from test1.benchmark where state like 'slave ends load' into @s_1; -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'; +--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR +eval 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 '$MYSQLD_DATADIR/delta.out'; --enable_result_log --enable_query_log === modified file 'mysql-test/suite/rpl/r/rpl_parallel_benchmark.result' --- a/mysql-test/suite/rpl/r/rpl_parallel_benchmark.result 2011-04-02 11:32:02 +0000 +++ b/mysql-test/suite/rpl/r/rpl_parallel_benchmark.result 2011-06-12 17:36:17 +0000 @@ -6,12 +6,12 @@ include/stop_slave.inc start slave; stop slave sql_thread; use test; -select * from test1.benchmark into outfile 'benchmark.out'; +select * from test1.benchmark into outfile 'MYSQLD_DATADIR/benchmark.out'; select ts from test1.benchmark where state like 'master started load' into @m_0; select ts from test1.benchmark where state like 'master ends load' into @m_1; select ts from test1.benchmark where state like 'slave takes on load' into @s_0; select ts from test1.benchmark where state like 'slave ends load' into @s_1; 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'; +time_to_sec(@s_1) - time_to_sec(@s_0) as 'delta_s' into outfile 'MYSQLD_DATADIR/delta.out'; set @@global.mts_exp_slave_local_timestamp= @save.mts_exp_slave_local_timestamp; include/rpl_end.inc === added file 'mysql-test/suite/rpl/r/rpl_parallel_seconds_behind_master.result' --- a/mysql-test/suite/rpl/r/rpl_parallel_seconds_behind_master.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/rpl/r/rpl_parallel_seconds_behind_master.result 2011-06-10 08:04:00 +0000 @@ -0,0 +1,35 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT'); +include/stop_slave.inc +set @save.mts_slave_parallel_workers= @@global.mts_slave_parallel_workers; +set @@global.mts_slave_parallel_workers= 4; +set @save.mts_checkpoint_period= @@global.mts_checkpoint_period; +set @@global.mts_checkpoint_period= 500; +set @save.slave_transaction_retries= @@global.slave_transaction_retries; +start slave io_thread; +include/wait_for_slave_io_to_start.inc +create table t1 (f1 int) engine=innodb; +create table t2 (f1 int) engine=innodb; +begin; +insert into t1 values (sleep(3) + 1); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. +commit; +begin; +insert into t2 values (1); +commit; +include/start_slave.inc +include/sync_slave_io_with_master.inc +lock table t2 write; +First transaction is done, now get Seconds_Behind_Master after it... +include/wait_for_slave_param.inc [Seconds_Behind_Master] +Seconds_Behind_Master after first transaction is as expected. +unlock tables; +include/wait_for_slave_param.inc [Seconds_Behind_Master] +drop tables t1, t2; +set @@global.mts_checkpoint_period= @save.mts_checkpoint_period; +set @@global.mts_slave_parallel_workers= @save.mts_slave_parallel_workers; +set @@global.slave_transaction_retries= @save.slave_transaction_retries; +include/rpl_end.inc +end of the tests === modified file 'mysql-test/suite/rpl/r/rpl_slave_grp_exec.result' --- a/mysql-test/suite/rpl/r/rpl_slave_grp_exec.result 2011-02-23 11:54:58 +0000 +++ b/mysql-test/suite/rpl/r/rpl_slave_grp_exec.result 2011-06-12 19:05:05 +0000 @@ -30,7 +30,7 @@ SELECT * FROM t3 ORDER BY a; a b 1 ZZ call mtr.add_suppression("Slave SQL.*Table .test.t3. doesn.t exist.* Error_code: 1146"); -include/wait_for_slave_sql_error.inc [errno=1146] +include/wait_for_slave_sql_to_stop.inc SHOW TABLES LIKE 't%'; Tables_in_test (t%) t1 @@ -58,7 +58,7 @@ INSERT INTO t3 VALUES(2, 'B'); INSERT INTO t2 VALUES(2, 'B'); INSERT INTO t1 VALUES(2, 'B'); UPDATE t1 SET b = 'X' WHERE a = 2; -include/wait_for_slave_sql_error.inc [errno=1146] +include/wait_for_slave_sql_to_stop.inc SELECT * FROM t1 ORDER BY a; a b 2 X @@ -94,7 +94,7 @@ INSERT INTO t1 VALUES (3, 'C'), (4, 'D') INSERT INTO t2 VALUES (3, 'C'), (4, 'D'); INSERT INTO t3 VALUES (3, 'C'), (4, 'D'); COMMIT; -include/wait_for_slave_sql_error.inc [errno=1146] +include/wait_for_slave_sql_to_stop.inc SELECT * FROM t1 ORDER BY a; a b 3 C === modified file 'mysql-test/suite/rpl/t/rpl_bug26395.test' --- a/mysql-test/suite/rpl/t/rpl_bug26395.test 2010-12-19 17:07:28 +0000 +++ b/mysql-test/suite/rpl/t/rpl_bug26395.test 2011-06-08 20:18:08 +0000 @@ -37,6 +37,10 @@ source include/have_innodb.inc; source include/have_debug.inc; source include/master-slave.inc; +# test adapts simulation of incomplete transaction that MTS does not tolerate +# when is stopped. So it reacts with an error whereas the single-threaded is fine. +-- source include/not_mts_slave_parallel_workers.inc + --echo ==== Initialize ==== @@ -67,7 +71,6 @@ source include/sync_slave_io_with_master # Sync slave's SQL thread. sync_with_master 0; - --echo ==== Verify results on slave ==== source include/stop_slave.inc; === modified file 'mysql-test/suite/rpl/t/rpl_cross_version.test' --- a/mysql-test/suite/rpl/t/rpl_cross_version.test 2011-01-17 18:51:01 +0000 +++ b/mysql-test/suite/rpl/t/rpl_cross_version.test 2011-06-12 19:05:05 +0000 @@ -12,6 +12,14 @@ --source include/master-slave.inc +# The test is disabled for windows due to +# Bug #42879 CHANGE MASTER RELAY_LOG_FILE=path fails on windows +# Todo: release it from not_windows +--source include/not_windows.inc + +# EXEC_LOAD_EVENT of 4.1 binlog can't be supported +-- source include/not_mts_slave_parallel_workers.inc + # # Bug#31240 load data infile replication between (4.0 or 4.1) and 5.1 fails # === modified file 'mysql-test/suite/rpl/t/rpl_packet.test' --- a/mysql-test/suite/rpl/t/rpl_packet.test 2011-06-09 15:27:47 +0000 +++ b/mysql-test/suite/rpl/t/rpl_packet.test 2011-06-12 19:05:05 +0000 @@ -11,6 +11,13 @@ # max-out size db name source include/master-slave.inc; source include/have_binlog_format_row.inc; + +# TODO: Fixing is handed over to Sergei. +# The test runs slow in MTS mode because of state of MTS at time of the graceful stop. +# In this case MTS can't stop immediately if there is a Worker that received a BEGIN but never COMMIT. +-- source include/not_mts_slave_parallel_workers.inc + + call mtr.add_suppression("Slave I/O: Got a packet bigger than 'max_allowed_packet' bytes, Error_code: 1153"); call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log:"); @@ -283,6 +290,7 @@ eval SET @@global.max_allowed_packet= $o DROP TABLE t1; # Clear Last_IO_Error + --source include/stop_slave_sql.inc RESET SLAVE; === added file 'mysql-test/suite/rpl/t/rpl_parallel_seconds_behind_master-slave.opt' --- a/mysql-test/suite/rpl/t/rpl_parallel_seconds_behind_master-slave.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/rpl/t/rpl_parallel_seconds_behind_master-slave.opt 2011-06-12 17:36:17 +0000 @@ -0,0 +1 @@ +--slave-transaction-retries=0 === added file 'mysql-test/suite/rpl/t/rpl_parallel_seconds_behind_master.test' --- a/mysql-test/suite/rpl/t/rpl_parallel_seconds_behind_master.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/rpl/t/rpl_parallel_seconds_behind_master.test 2011-06-12 17:36:17 +0000 @@ -0,0 +1,141 @@ +# +# Testing of Seconds_Behind_Master (SBM) to behave as the following +# SBM changes discretely per some number of processed group of events, +# e.g transactions. +# The number is either @@global.slave_checkpoint_group or less if +# @@global.slave_checkpoint_period timer elapses first. +# The value updates *after* the last group commit is executed. +# Resetting to zero behavior when Slave goes to read events is +# preserved. +# + +-- source include/master-slave.inc +-- source include/have_debug.inc + +# make the test only run once (STMT is actually needed because we rely +# on SHOW PROCESS LIST output in some of the tests) +-- source include/have_binlog_format_statement.inc + +# todo: sleep() is deterministic!!! +call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT'); + +# restart slave in MTS mode +connection slave; +source include/stop_slave.inc; +set @save.mts_slave_parallel_workers= @@global.mts_slave_parallel_workers; +set @@global.mts_slave_parallel_workers= 4; +set @save.mts_checkpoint_period= @@global.mts_checkpoint_period; +set @@global.mts_checkpoint_period= 500; # 0.5 sec +# to avoid warnings +set @save.slave_transaction_retries= @@global.slave_transaction_retries; + +# +# Idea of demonstration. +# +# Two transactions on the same db are generated for MTS. The first has some +# natural delay, and the 2nd will be locked out of its data. +# While the first is being processed Coordinator empties the relay-log +# to enter waiting for more events. +# It does so being awakened @@global.slave_checkpoint_period-ically +# to check out if some groups of events have been done to update SBM (demo 1). +# +# Resetting of SBM is a possibility whenever Coordinator +# notices no more groups left neither to read nor to process (demo 2). +# + +start slave io_thread; +source include/wait_for_slave_io_to_start.inc; + +connection master; + +create table t1 (f1 int) engine=innodb; +create table t2 (f1 int) engine=innodb; +save_master_pos; + +# 1st transaction that will be used to compute SBM. +# It will hang $idle time at least in processing to get min estimate for SBM +let $idle= 3; + +begin; + eval insert into t1 values (sleep($idle) + 1); +commit; + +# 2nd transaction to block Coordinator from resetting SBM +begin; + insert into t2 values (1); +commit; + +connection slave; +source include/start_slave.inc; + +# +# all events are in relay-log +# +connection master; + +source include/sync_slave_io_with_master.inc; + +# tables are created on slave +connection slave; +sync_with_master; + +connection slave1; +lock table t2 write; # to block 2nd trans + +connection slave; + +let $count= 1; +let $table= t1; +source include/wait_until_rows_count.inc; + +--echo First transaction is done, now get Seconds_Behind_Master after it... + +# +# demo 1: +# So now 1st is over, and it SBM must have gain at least $idle seconds. +# +let $slave_param= Seconds_Behind_Master; +let $slave_param_comparison= >=; +let $slave_param_value= $idle; +source include/wait_for_slave_param.inc; + +# checking sanity of SBM value +let $sbm= query_get_value("SHOW SLAVE STATUS", Seconds_Behind_Master, 1); +let $lower_bound= $idle; +if (`SELECT $sbm < $idle`) +{ + -- echo *** Seconds behind master is $sbm less than minimum expected $idle *** + -- source include/show_rpl_debug_info.inc + -- die +} + +--echo Seconds_Behind_Master after first transaction is as expected. + +connection slave1; +unlock tables; + +# +# demo 2: Resetting of SBM upon all groups have been processed and +# nothing left in relay-log. +# +connection slave; +let $slave_param= Seconds_Behind_Master; +let $slave_param_comparison= =; +let $slave_param_value= 0; +source include/wait_for_slave_param.inc; + +## +# cleanup +## +connection master; +drop tables t1, t2; + +sync_slave_with_master; + +set @@global.mts_checkpoint_period= @save.mts_checkpoint_period; +set @@global.mts_slave_parallel_workers= @save.mts_slave_parallel_workers; +set @@global.slave_transaction_retries= @save.slave_transaction_retries; + +--source include/rpl_end.inc + +--echo end of the tests === modified file 'mysql-test/suite/rpl/t/rpl_seconds_behind_master.test' --- a/mysql-test/suite/rpl/t/rpl_seconds_behind_master.test 2010-12-19 17:22:30 +0000 +++ b/mysql-test/suite/rpl/t/rpl_seconds_behind_master.test 2011-06-10 08:04:00 +0000 @@ -5,6 +5,10 @@ # on SHOW PROCESS LIST output in some of the tests) -- source include/have_binlog_format_statement.inc +# this test logics requires adaption to MTS policies for SBM +# (see rpl_parallel_seconds_behind_master.test) +-- source include/not_mts_slave_parallel_workers.inc + SET @old_debug= @@global.debug; call mtr.add_suppression('Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT'); === modified file 'mysql-test/suite/rpl/t/rpl_slave_grp_exec.test' --- a/mysql-test/suite/rpl/t/rpl_slave_grp_exec.test 2011-02-23 11:54:58 +0000 +++ b/mysql-test/suite/rpl/t/rpl_slave_grp_exec.test 2011-06-12 19:05:05 +0000 @@ -23,6 +23,12 @@ --source include/master-slave.inc --echo +# Test is MTS unfriendly because of +# a. incompatible with STS error reporting (MTS stop due to an error in applying +# causes inconsistency so the latter is reported) +# b. failing recovery +-- source include/not_mts_slave_parallel_workers.inc + # Create tables and data --echo *** Preparing data *** --connection master @@ -62,10 +68,22 @@ SELECT * FROM t2 ORDER BY a; SELECT * FROM t3 ORDER BY a; --connection slave -# 1146 = ER_NO_SUCH_TABLE call mtr.add_suppression("Slave SQL.*Table .test.t3. doesn.t exist.* Error_code: 1146"); ---let $slave_sql_errno= 1146 ---source include/wait_for_slave_sql_error.inc + +# in MTS case error is either of two: +#--let $slave_sql_errno= 1146,1593 +# whereas in the single-threaded case: +# 1146 = ER_NO_SUCH_TABLE +#--let $slave_sql_errno= 1146 + +--source include/wait_for_slave_sql_to_stop.inc +let $slave_sql_errno= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1); +if (`select $slave_sql_errno != 1146 and $slave_sql_errno != 1593`) +{ + --echo Unexpected error: $slave_sql_errno + --die +} + SHOW TABLES LIKE 't%'; if (`SELECT @@BINLOG_FORMAT = 'ROW'`) { --replace_regex /AA/AA_for_row_or_XX_for_stmt_mixed/ @@ -111,8 +129,18 @@ UPDATE t1 SET b = 'X' WHERE a = 2; --connection slave # 1146 = ER_NO_SUCH_TABLE ---let $slave_sql_errno= 1146 ---source include/wait_for_slave_sql_error.inc +# in MTS case error is either of two: +#--let $slave_sql_errno= 1146,1593 +# whereas in the single-threaded case: +#--let $slave_sql_errno= 1146 + +--source include/wait_for_slave_sql_to_stop.inc +let $slave_sql_errno= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1); +if (`select $slave_sql_errno != 1146 and $slave_sql_errno != 1593`) +{ + --echo Unexpected error: $slave_sql_errno + --die +} --connection master SELECT * FROM t1 ORDER BY a; @@ -126,6 +154,8 @@ SELECT * FROM t2 ORDER BY a; --source include/stop_slave_io.inc RENAME TABLE t3_bak TO t3; + +# TODO: recovery. Alfranio it fails to recover here. --source include/start_slave.inc --connection master @@ -157,8 +187,19 @@ COMMIT; --connection slave # 1146 = ER_NO_SUCH_TABLE ---let $slave_sql_errno= 1146 ---source include/wait_for_slave_sql_error.inc +# in MTS case error is either of two: +#--let $slave_sql_errno= 1146,1593 +# whereas in the single-threaded case: +#--let $slave_sql_errno= 1146 + +--source include/wait_for_slave_sql_to_stop.inc +let $slave_sql_errno= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1); +if (`select $slave_sql_errno != 1146 and $slave_sql_errno != 1593`) +{ + --echo Unexpected error: $slave_sql_errno + --die +} + --connection master SELECT * FROM t1 ORDER BY a; === modified file 'sql/binlog.cc' --- a/sql/binlog.cc 2011-06-09 15:27:47 +0000 +++ b/sql/binlog.cc 2011-06-12 19:05:05 +0000 @@ -4945,26 +4945,37 @@ THD::binlog_set_pending_rows_event(Rows_ /** @param db db name c-string to be inserted into abc-sorted THD::binlog_accessed_db_names list. - - Note, as the list node data (explicitly) so the node - struct itself (implicitly) are allocated in - thd->mem_root to be cleared at the end of the query - processing (@c THD::cleanup_after_query()). + + Note, as the list node data so the node + struct itself are allocated in THD::main_mem_root. + The list lasts for the top-level query time and resets + in @c THD::cleanup_after_query() and Query_log_event::write(). */ void -THD::add_to_binlog_updated_dbs(const char *db) +THD::add_to_binlog_accessed_dbs(const char *db) { char *after_db; + MEM_ROOT *db_mem_root= &main_mem_root; + + if (!binlog_accessed_db_names) + binlog_accessed_db_names= new (db_mem_root) List; + if (binlog_accessed_db_names->elements > MAX_DBS_IN_EVENT_MTS) { push_warning_printf(this, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_UPDATED_DBS_GREATER_MAX, - ER(ER_UPDATED_DBS_GREATER_MAX), + ER_MTS_UPDATED_DBS_GREATER_MAX, + ER(ER_MTS_UPDATED_DBS_GREATER_MAX), MAX_DBS_IN_EVENT_MTS); return; } - after_db= strdup_root(mem_root, db); + after_db= strdup_root(db_mem_root, db); + + /* + sorted insertion is implemented with first rearranging data + (pointer to char*) of the links and final appending of the least + ordered data to create a new link in the list. + */ if (binlog_accessed_db_names->elements != 0) { List_iterator it(*get_binlog_accessed_db_names()); @@ -4991,7 +5002,7 @@ THD::add_to_binlog_updated_dbs(const cha } } if (after_db) - binlog_accessed_db_names->push_back(after_db); + binlog_accessed_db_names->push_back(after_db, &main_mem_root); } @@ -5218,27 +5229,6 @@ int THD::decide_logging_format(TABLE_LIS prev_access_table= table->table; } - - /* - Master side of DML in the STMT format events parallelization. - All involving table db:s are stored in a abc-ordered name list. - In case the number of databases exceeds MAX_DBS_IN_EVENT_MTS maximum - the list gathering breaks since it won't be sent to the slave. - */ - if (is_write && variables.binlog_format != BINLOG_FORMAT_ROW && - lex->sql_command != SQLCOM_END /* rows-event applying by slave */) - { - if (!binlog_accessed_db_names) - { - binlog_accessed_db_names= new List; /* thd->mem_root is used */ - } - for (TABLE_LIST *table= tables; table; table= table->next_global) - { - if (table->placeholder()) - continue; - add_to_binlog_updated_dbs(table->db); - } - } DBUG_PRINT("info", ("flags_write_all_set: 0x%llx", flags_write_all_set)); DBUG_PRINT("info", ("flags_write_some_set: 0x%llx", flags_write_some_set)); @@ -5373,6 +5363,23 @@ int THD::decide_logging_format(TABLE_LIS DBUG_PRINT("info", ("decision: no logging since an error was generated")); DBUG_RETURN(-1); } + + if (is_write && !is_current_stmt_binlog_format_row() && + lex->sql_command != SQLCOM_END /* rows-event applying by slave */) + { + /* + Master side of DML in the STMT format events parallelization. + All involving table db:s are stored in a abc-ordered name list. + In case the number of databases exceeds MAX_DBS_IN_EVENT_MTS maximum + the list gathering breaks since it won't be sent to the slave. + */ + for (TABLE_LIST *table= tables; table; table= table->next_global) + { + if (table->placeholder()) + continue; + add_to_binlog_accessed_dbs(table->db); + } + } DBUG_PRINT("info", ("decision: logging in %s format", is_current_stmt_binlog_format_row() ? "ROW" : "STATEMENT")); === modified file 'sql/events.cc' --- a/sql/events.cc 2011-06-09 15:27:47 +0000 +++ b/sql/events.cc 2011-06-12 19:05:05 +0000 @@ -389,7 +389,7 @@ Events::create_event(THD *thd, Event_par } else { - thd->add_one_db_to_binlog_updated_dbs(parse_data->dbname.str); + thd->add_to_binlog_accessed_dbs(parse_data->dbname.str); /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER will be written into the binary log as the definer for the SQL thread. @@ -511,10 +511,9 @@ Events::update_event(THD *thd, Event_par /* Binlog the alter event. */ DBUG_ASSERT(thd->query() && thd->query_length()); - thd->set_binlog_accessed_db_names(new List); - thd->add_to_binlog_updated_dbs(parse_data->dbname.str); + thd->add_to_binlog_accessed_dbs(parse_data->dbname.str); if (new_dbname) - thd->add_to_binlog_updated_dbs(new_dbname->str); + thd->add_to_binlog_accessed_dbs(new_dbname->str); ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } @@ -583,7 +582,7 @@ Events::drop_event(THD *thd, LEX_STRING /* Binlog the drop event. */ DBUG_ASSERT(thd->query() && thd->query_length()); - thd->add_one_db_to_binlog_updated_dbs(dbname.str); + thd->add_to_binlog_accessed_dbs(dbname.str); ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } /* Restore the state of binlog format */ === modified file 'sql/log_event.cc' --- a/sql/log_event.cc 2011-06-09 15:27:47 +0000 +++ b/sql/log_event.cc 2011-06-12 19:05:05 +0000 @@ -672,6 +672,9 @@ Log_event::Log_event(enum_event_cache_ty :temp_buf(0), exec_time(0), flags(0), event_cache_type(cache_type_arg), 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) +#endif { server_id= ::server_id; /* @@ -694,6 +697,9 @@ Log_event::Log_event(const char* buf, event_cache_type(EVENT_INVALID_CACHE), 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) +#endif { #ifndef MYSQL_CLIENT thd = 0; @@ -2356,7 +2362,7 @@ Log_event::continue_group(Relay_log_info bool Log_event::contains_partition_info() { - return get_type_code() == TABLE_MAP_EVENT || + return (get_type_code() == TABLE_MAP_EVENT) || (get_type_code() == QUERY_EVENT && !ends_group() && !starts_group()) || (get_type_code() == EXECUTE_LOAD_QUERY_EVENT); } @@ -2405,6 +2411,7 @@ Slave_worker *Log_event::get_slave_worke bool is_b_event; int num_dbs= 0; Slave_worker *ret_worker= NULL; + THD *thd= rli->info_thd; /* checking partioning properties and perform corresponding actions */ @@ -2466,7 +2473,7 @@ Slave_worker *Log_event::get_slave_worke { int i= 0; num_dbs= mts_number_dbs(); - List_iterator it(*mts_get_dbs(rli->info_thd->mem_root)); + List_iterator it(*mts_get_dbs(thd->mem_root)); it++; ret_worker= rli->last_assigned_worker; @@ -2488,12 +2495,10 @@ Slave_worker *Log_event::get_slave_worke get_type_code() == QUERY_EVENT, ret_worker))) { - // destroy buffered events of the current group prior to exit - for (uint k= 0; k < rli->curr_group_da.elements; k++) - { - delete *(Log_event**) dynamic_array_ptr(&rli->curr_group_da, k); - } - + rli->report(ERROR_LEVEL, ER_MTS_CANT_PARALLEL, + ER(ER_MTS_CANT_PARALLEL), + get_type_str(), rli->get_event_relay_log_name(), + rli->get_event_relay_log_pos()); return ret_worker; } @@ -2516,13 +2521,13 @@ Slave_worker *Log_event::get_slave_worke DBUG_ASSERT(i == num_dbs || num_dbs == OVER_MAX_DBS_IN_EVENT_MTS); - // TODO: convert to C's private mem_root. + // TODO: convert to C's private mem_root to reset not per event but rather realrely. // Releasing the Coord's mem-root from the updated dbs. It's safe to do at this // point because the root is no longer needed along remained part of Coordinator's // execution flow. - free_root(rli->info_thd->mem_root, MYF(MY_KEEP_PREALLOC)); + free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC)); } else { @@ -2534,15 +2539,25 @@ Slave_worker *Log_event::get_slave_worke DBUG_ASSERT(rli->curr_group_assigned_parts.elements > 0 || ret_worker->id == 0); } - else // int_, rand_, user_ var:s + else // int_, rand_, user_ var:s, load-data events { Log_event *ptr_curr_ev= this; - DBUG_ASSERT(get_type_code() == INTVAR_EVENT || - get_type_code() == RAND_EVENT || - get_type_code() == USER_VAR_EVENT || - get_type_code() == ROWS_QUERY_LOG_EVENT || - get_type_code() == BEGIN_LOAD_QUERY_EVENT); + if (!(get_type_code() == INTVAR_EVENT || + get_type_code() == RAND_EVENT || + get_type_code() == USER_VAR_EVENT || + get_type_code() == ROWS_QUERY_LOG_EVENT || + get_type_code() == BEGIN_LOAD_QUERY_EVENT || + get_type_code() == APPEND_BLOCK_EVENT)) + { + DBUG_ASSERT(!ret_worker); + + rli->report(ERROR_LEVEL, ER_MTS_CANT_PARALLEL, + ER(ER_MTS_CANT_PARALLEL), + get_type_str(), rli->get_event_relay_log_name(), + rli->get_event_relay_log_pos()); + return ret_worker; + } insert_dynamic(&rli->curr_group_da, (uchar*) &ptr_curr_ev); @@ -2626,9 +2641,12 @@ Slave_worker *Log_event::get_slave_worke strcpy(ptr_g->checkpoint_relay_log_name, rli->get_group_relay_log_name()); ptr_g->checkpoint_relay_log_pos= rli->get_group_relay_log_pos(); + ptr_g->shifted= ret_worker->bitmap_shifted; + ret_worker->bitmap_shifted= 0; ret_worker->checkpoint_notified= TRUE; } ptr_g->checkpoint_seqno= rli->checkpoint_seqno; + ptr_g->ts= when + (time_t) exec_time; rli->checkpoint_seqno++; } @@ -2815,14 +2833,17 @@ void append_item_to_jobs(slave_job_item can't be decided yet. In the single threaded sequential mode the event maps to SQL thread rli. + @note in case of MTS failure Coordinator destroys all gathered + deferred events. + @return 0 as success, otherwise a failure. */ int Log_event::apply_event(Relay_log_info const *rli) { DBUG_ENTER("LOG_EVENT:apply_event"); - Slave_worker *w= NULL; Relay_log_info *c_rli= const_cast(rli); // constless alias bool parallel= FALSE, async_event= FALSE, seq_event= FALSE; + THD *thd= c_rli->info_thd; worker= c_rli; @@ -2875,19 +2896,15 @@ int Log_event::apply_event(Relay_log_inf wrappped with BEGIN/COMMIT or preceeded by User|Int|Random- var. MTS has to stop to suggest restart in the permanent sequential mode. */ + rli->report(ERROR_LEVEL, ER_MTS_CANT_PARALLEL, + ER(ER_MTS_CANT_PARALLEL), + get_type_str(), c_rli->get_event_relay_log_name(), + c_rli->get_event_relay_log_pos()); + + /* Coordinator cant continue, it marks MTS group status accordingly */ + c_rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP; - // TODO: improve err msg - rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, - ER(ER_SLAVE_FATAL_ERROR), - "Can't execute all binlog event in parallel mode"); - - // destroy possible buffered events of the current group prior to exit - for (uint k= 0; k < rli->curr_group_da.elements; k++) - { - delete *(Log_event**) dynamic_array_ptr(&rli->curr_group_da, k); - } - - DBUG_RETURN(-1); + goto err; } /* Marking sure the event will be executed in sequential mode. @@ -2920,13 +2937,28 @@ int Log_event::apply_event(Relay_log_inf worker= NULL; c_rli->mts_group_status= Relay_log_info::MTS_IN_GROUP; - c_rli->last_assigned_worker= w= get_slave_worker_id(c_rli); - if (!w || DBUG_EVALUATE_IF("fault_injection_get_slave_worker", 1, 0)) - DBUG_RETURN(rli->curr_group_assigned_parts.elements == 0 ? FALSE : TRUE); + worker= (Relay_log_info*) + (c_rli->last_assigned_worker= get_slave_worker_id(c_rli)); + +err: + if (thd->is_error()) + { + DBUG_ASSERT(!worker); - worker= (Relay_log_info*) w; + // destroy buffered events of the current group prior to exit + for (uint k= 0; k < rli->curr_group_da.elements; k++) + { + delete *(Log_event**) dynamic_array_ptr(&rli->curr_group_da, k); + } + } + else + { + DBUG_ASSERT(worker || rli->curr_group_assigned_parts.elements == 0); + } - DBUG_RETURN(FALSE); + DBUG_RETURN((!thd->is_error() || + DBUG_EVALUATE_IF("fault_injection_get_slave_worker", 1, 0)) ? + 0 : -1); } @@ -3845,7 +3877,7 @@ Query_log_event::Query_log_event(const c auto_increment_increment(1), auto_increment_offset(1), time_zone_len(0), lc_time_names_number(0), charset_database_number(0), table_map_for_update(0), master_data_written(0), - mts_accessed_dbs(OVER_MAX_DBS_IN_EVENT_MTS), m_mts_query_ends_group(FALSE) + mts_accessed_dbs(OVER_MAX_DBS_IN_EVENT_MTS) { ulong data_len; uint32 tmp; @@ -6596,19 +6628,19 @@ int Rotate_log_event::do_update_pos(Rela if ((server_id != ::server_id || rli->replicate_same_server_id) && !is_relay_log_event() && ((!rli->is_parallel_exec() && !rli->is_in_group()) || - rli->mts_group_status == Relay_log_info::MTS_NOT_IN_GROUP)) + rli->mts_group_status != Relay_log_info::MTS_IN_GROUP)) { + if (rli->is_parallel_exec()) + { + (void) mts_checkpoint_routine(rli, 0, FALSE, TRUE); // todo: error branch + } + mysql_mutex_lock(&rli->data_lock); DBUG_PRINT("info", ("old group_master_log_name: '%s' " "old group_master_log_pos: %lu", rli->get_group_master_log_name(), (ulong) rli->get_group_master_log_pos())); - if (rli->is_parallel_exec()) - { - (void) mts_checkpoint_routine(rli, 0, FALSE, TRUE); // todo: error branch - } - memcpy((void *)rli->get_group_master_log_name(), new_log_ident, ident_len + 1); rli->notify_group_master_log_name_update(); @@ -6621,7 +6653,7 @@ int Rotate_log_event::do_update_pos(Rela mysql_mutex_unlock(&rli->data_lock); rli->flush_info(TRUE); // todo: error branch if (rli->is_parallel_exec()) - rli->reset_notified_checkpoint(); + rli->reset_notified_checkpoint(0, when + (time_t) exec_time); /* Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of === modified file 'sql/log_event.h' --- a/sql/log_event.h 2011-06-09 15:27:47 +0000 +++ b/sql/log_event.h 2011-06-12 19:05:05 +0000 @@ -1138,37 +1138,6 @@ public: { return thd ? thd->db : 0; } - - /* - The method returns a list of updated by the event databases. - Other than in the case of Query-log-event the list is just one item. - */ - virtual List* mts_get_dbs(MEM_ROOT *mem_root) - { - List *res= new List; - res->push_back(strdup_root(mem_root, get_db())); - return res; - } - - /* - returns the number of updated by the event databases. - In other than Query-log-event case that's one. - */ - virtual uint8 mts_number_dbs() { return 1; } - - /* - Event can be exceptionally 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. - */ - virtual void mts_do_isolate_event() { DBUG_ASSERT(0); } - - /* - Verifying whether event is marked to execute in isolation. - */ - virtual bool mts_is_event_isolated() { return FALSE; } - #else Log_event(enum_event_cache_type cache_type_arg= EVENT_INVALID_CACHE, enum_event_logging_type logging_type_arg= EVENT_INVALID_LOGGING) @@ -1300,6 +1269,10 @@ public: @note There are incompatile combinations such the referred event is wrapped with BEGIN/COMMIT. Such cases should be identified by the caller and treates as an error. + + Notice, even though the func returns TRUE, some events + like old LOAD-DATA rooted EXEC_LOAD_EVENT can't run even + in isolated parallel mode and MTS would have to stop. @return TRUE if despite permanent parallel execution mode an event needs applying in a real isolation that is sequentially. @@ -1313,11 +1286,9 @@ public: get_type_code() == LOAD_EVENT || get_type_code() == SLAVE_EVENT || get_type_code() == CREATE_FILE_EVENT || - get_type_code() == APPEND_BLOCK_EVENT || - get_type_code() == EXEC_LOAD_EVENT || get_type_code() == DELETE_FILE_EVENT || get_type_code() == NEW_LOAD_EVENT || - + get_type_code() == EXEC_LOAD_EVENT || get_type_code() == FORMAT_DESCRIPTION_EVENT|| get_type_code() == INCIDENT_EVENT; @@ -1361,6 +1332,45 @@ public: */ Slave_worker *get_slave_worker_id(Relay_log_info *rli); + /* + The method returns a list of updated by the event databases. + Other than in the case of Query-log-event the list is just one item. + */ + virtual List* mts_get_dbs(MEM_ROOT *mem_root) + { + List *res= new List; + res->push_back(strdup_root(mem_root, get_db())); + return res; + } + + /* + returns the number of updated by the event databases. + In other than Query-log-event case that's one. + */ + virtual uint8 mts_number_dbs() { return 1; } + + /* + Event can be exceptionally 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. + */ + /* + Event can be indentified as a group terminator and such fact + is memoried by the function. + */ + virtual void mts_do_isolate_event() + { + DBUG_ASSERT(get_type_code() == QUERY_EVENT || + get_type_code() == EXEC_LOAD_EVENT || + get_type_code() == EXECUTE_LOAD_QUERY_EVENT); + m_mts_event_ends_group= TRUE; + } + /* + Verifying whether event is marked to execute in isolation. + */ + virtual bool mts_is_event_isolated() { return m_mts_event_ends_group; } + /** Apply the event to the database. @@ -1494,6 +1504,8 @@ protected: non-zero. The caller shall decrease the counter by one. */ virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); + + bool m_mts_event_ends_group; #endif }; @@ -1951,13 +1963,6 @@ public: uchar mts_accessed_dbs; char mts_accessed_db_names[MAX_DBS_IN_EVENT_MTS][NAME_LEN]; - /* - Event can be indentified as a group terminator and such fact - is memoried by the function. - */ - virtual void mts_do_isolate_event() { m_mts_query_ends_group= TRUE; } - virtual bool mts_is_event_isolated() { return m_mts_query_ends_group; } - #ifdef MYSQL_SERVER Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, @@ -2068,9 +2073,6 @@ public: /* !!! Public in this pat (!strncasecmp(query, STRING_WITH_LEN("ROLLBACK")) && strncasecmp(query, STRING_WITH_LEN("ROLLBACK TO "))); } -private: - - bool m_mts_query_ends_group; }; @@ -3152,8 +3154,17 @@ public: bool write(IO_CACHE* file); const char* get_db() { return db; } #endif +#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) /* MTS executes this event sequentially */ virtual uint8 mts_number_dbs() { return OVER_MAX_DBS_IN_EVENT_MTS; } + virtual List* mts_get_dbs(MEM_ROOT *mem_root) + { + List *res= new List; + res->push_back(strdup_root(mem_root, "")); + return res; + } +#endif + private: #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) virtual int do_apply_event(Relay_log_info const *rli); === modified file 'sql/rpl_rli.cc' --- a/sql/rpl_rli.cc 2011-06-09 15:27:47 +0000 +++ b/sql/rpl_rli.cc 2011-06-12 19:05:05 +0000 @@ -197,17 +197,35 @@ void Relay_log_info::reset_notified_rela Worker notices the new checkpoint value at the group commit to reset the current bitmap and starts using the clean bitmap indexed from zero of being reset checkpoint_seqno. + New seconds_behind_master timestamp is installed. + + @param shift number of bits to shift by Worker due to the current + checkpoint change. + @param new_ts new seconds_behind_master timestamp value unless zero. + Zero could be due to FD event. */ -void Relay_log_info::reset_notified_checkpoint() +void Relay_log_info::reset_notified_checkpoint(ulong shift, time_t new_ts= 0) { if (!is_parallel_exec()) return; for (uint i= 0; i < workers.elements; i++) { Slave_worker *w= *(Slave_worker **) dynamic_array_ptr(&workers, i); - w->checkpoint_notified= FALSE; + if (w->checkpoint_notified) + { + w->bitmap_shifted= 0; + w->checkpoint_notified= FALSE; + } + w->bitmap_shifted += shift; // to reset at passing the accumulate value into GAQ } checkpoint_seqno= 0; + + if (new_ts) + { + mysql_mutex_lock(&data_lock); + last_master_timestamp= new_ts; + mysql_mutex_unlock(&data_lock); + } } static inline int add_relay_log(Relay_log_info* rli,LOG_INFO* linfo) @@ -1044,7 +1062,7 @@ void Relay_log_info::stmt_done(my_off_t flush_info(is_transactional() ? TRUE : FALSE); // Alfranio todo: error branch if (is_parallel_exec()) - reset_notified_checkpoint(); + reset_notified_checkpoint(0); } } === modified file 'sql/rpl_rli.h' --- a/sql/rpl_rli.h 2011-06-09 15:27:47 +0000 +++ b/sql/rpl_rli.h 2011-06-12 19:05:05 +0000 @@ -496,7 +496,8 @@ public: includes Single-Threaded-Slave case. */ MTS_NOT_IN_GROUP, - MTS_IN_GROUP, /* at least one event was scheduled to a Worker */ + + MTS_IN_GROUP, /* at least one not-terminal event scheduled to a Worker */ MTS_END_GROUP, /* the last scheduled event is a terminal event */ MTS_KILLED_GROUP /* Coordinator gave out to reach MTS_END_GROUP */ } mts_group_status; @@ -540,7 +541,7 @@ public: Coordinator notifies Workers about this event. Coordinator and Workers maintain a bitmap of executed group that is reset with a new checkpoint. */ - void reset_notified_checkpoint(); + void reset_notified_checkpoint(ulong, time_t); /** Helper function to do after statement completion. === modified file 'sql/rpl_rli_pdb.cc' --- a/sql/rpl_rli_pdb.cc 2011-06-06 10:51:19 +0000 +++ b/sql/rpl_rli_pdb.cc 2011-06-12 17:36:17 +0000 @@ -225,6 +225,7 @@ bool Slave_worker::commit_positions(Log_ my_free(ptr_g->checkpoint_relay_log_name); ptr_g->checkpoint_relay_log_name= NULL; + // TODO: shift `group_execed' << ptr_g->shifted bitmap_clear_all(&group_execed); } // extract an updated relay-log name to store in Worker's rli. @@ -725,6 +726,8 @@ Slave_worker *get_least_occupied_worker( void Slave_worker::slave_worker_ends_group(Log_event* ev, int error) { + DBUG_ENTER("Slave_worker::slave_worker_ends_group"); + if (!error) { ulong gaq_idx= ev->mts_group_cnt; @@ -797,6 +800,9 @@ void Slave_worker::slave_worker_ends_gro #ifndef DBUG_OFF // TODO: open it! DBUG_ASSERT(usage_partition || !entry->worker->jobs.len); #endif + DBUG_PRINT("info", + ("Notifying entry %p release by worker %lu", entry, this->id)); + mysql_cond_signal(&slave_worker_hash_cond); } } @@ -827,6 +833,8 @@ void Slave_worker::slave_worker_ends_gro mysql_mutex_unlock(&c_rli->info_thd->LOCK_thd_data); mysql_mutex_unlock(&slave_worker_hash_lock); } + + DBUG_VOID_RETURN; } @@ -1105,6 +1113,9 @@ int wait_for_workers_to_finish(Relay_log THD *thd= rli->info_thd; const char info_format[]= "Waiting for Slave Worker %d to release partition `%s`"; + + DBUG_ENTER("wait_for_workers_to_finish"); + for (uint i= 0, ret= 0; i < hash->records; i++) { db_worker_hash_entry *entry; @@ -1127,16 +1138,22 @@ 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); entry->worker= NULL; // mark Worker to signal when usage drops to 0 - - proc_info= thd->enter_cond(&slave_worker_hash_cond, &slave_worker_hash_lock, - wait_info); - mysql_cond_wait(&slave_worker_hash_cond, &slave_worker_hash_lock); + do + { + proc_info= thd->enter_cond(&slave_worker_hash_cond, + &slave_worker_hash_lock, + wait_info); + mysql_cond_wait(&slave_worker_hash_cond, &slave_worker_hash_lock); + DBUG_PRINT("info", + ("Either got awakened of notified: " + "entry %p, usage %lu, worker %lu", + entry, entry->usage, w_id)); + } while (entry->usage != 0 && !thd->killed); thd->exit_cond(proc_info); ret++; - - DBUG_ASSERT(entry->usage == 0 || thd->killed); } else { @@ -1150,5 +1167,5 @@ int wait_for_workers_to_finish(Relay_log if (!ignore) const_cast(rli)->mts_group_status= Relay_log_info::MTS_NOT_IN_GROUP; - return ret; + DBUG_RETURN(ret); } === modified file 'sql/rpl_rli_pdb.h' --- a/sql/rpl_rli_pdb.h 2011-06-05 17:01:51 +0000 +++ b/sql/rpl_rli_pdb.h 2011-06-10 08:04:00 +0000 @@ -144,6 +144,8 @@ typedef struct st_slave_job_group my_off_t checkpoint_relay_log_pos; // T-event lop_pos filled by W for CheckPoint char* checkpoint_relay_log_name; volatile uchar done; // Flag raised by W, read and reset by C + ulong shifted; // shift the last CP bitmap at receiving a new CP + time_t ts; // Group's timestampt to update Seconds_behind_master } Slave_job_group; #define retrieve_job(from, to) \ @@ -265,6 +267,7 @@ public: long usage_partition; // number of different partitions handled by this worker volatile bool relay_log_change_notified; // Coord sets and resets, W can read volatile bool checkpoint_notified; // Coord sets and resets, W can read + ulong bitmap_shifted; // shift the last bitmap at receiving new CP bool wq_overrun_set; // W monitors its queue usage to incr/decr rli->mts_wqs_overrun /* We need to make this a dynamic field. /Alfranio === modified file 'sql/rpl_slave.cc' --- a/sql/rpl_slave.cc 2011-06-09 15:27:47 +0000 +++ b/sql/rpl_slave.cc 2011-06-12 19:05:05 +0000 @@ -1053,6 +1053,12 @@ static bool io_slave_killed(THD* thd, Ma In the event of deffering decision @rli->last_event_start_time waiting timer is set to force the killed status be accepted upon its expiration. + Notice Multi-Threaded-Slave behaives similarly in that when it's being + stopped and the current group of assigned events has not yet scheduled + completely, Coordinator deferres to accept to leave its read-distribute + state. The above timeout ensures waiting won't last endlessly, and in + such case an error is repoted. + @param thd pointer to a THD instance @param rli pointer to Relay_log_info instance @@ -1062,15 +1068,19 @@ static bool io_slave_killed(THD* thd, Ma static bool sql_slave_killed(THD* thd, Relay_log_info* rli) { bool ret= FALSE; + bool is_parallel_group= FALSE; + DBUG_ENTER("sql_slave_killed"); DBUG_ASSERT(rli->info_thd == thd); DBUG_ASSERT(rli->slave_running == 1); if (abort_loop || thd->killed || rli->abort_slave) { - if ((!rli->is_parallel_exec() && - thd->transaction.all.cannot_safely_rollback() && rli->is_in_group()) - || (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)) + if ((is_parallel_group= (rli->is_parallel_exec() && + rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)) + || + (!rli->is_parallel_exec() && + thd->transaction.all.cannot_safely_rollback() && rli->is_in_group())) { char msg_stopped[]= "... Slave SQL Thread stopped with incomplete event group " @@ -1116,23 +1126,27 @@ static bool sql_slave_killed(THD* thd, R if (ret == 0) { rli->report(WARNING_LEVEL, 0, + !is_parallel_group ? "Request to stop slave SQL Thread received while " "applying a group that has non-transactional " - "changes; waiting for completion of the group ... "); + "changes; waiting for completion of the group ... " + : + "Coordinator thread of multi-threaded slave is being stopped " + "in the middle of assigning a group of events; " + "deferring to exit until the group completion ... "); } else { rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR), - rli->mts_group_status == Relay_log_info::MTS_NOT_IN_GROUP ? - msg_stopped : msg_stopped_mts); + !is_parallel_group ? msg_stopped : msg_stopped_mts); } } else { ret= TRUE; rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR), - msg_stopped); + !is_parallel_group ? msg_stopped : msg_stopped_mts); } } else @@ -2977,7 +2991,8 @@ static int exec_relay_log_event(THD* thd event) or ev->when is set to 0, or a FD from master, we don't update the last_master_timestamp. */ - if (!(ev->is_artificial_event() || ev->is_relay_log_event() || + if (!(rli->is_parallel_exec() || + ev->is_artificial_event() || ev->is_relay_log_event() || (ev->when == 0) || ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)) { rli->last_master_timestamp= ev->when + (time_t) ev->exec_time; @@ -3719,6 +3734,12 @@ pthread_handler_t handle_slave_worker(vo { error= slave_worker_exec_job(w, rli); } + + /* + Cleanup after an error requires clear_error() go first. + Otherwise assert(!all) in binlog_rollback() + */ + thd->clear_error(); w->cleanup_context(thd, error); mysql_mutex_lock(&w->jobs_lock); @@ -3758,7 +3779,6 @@ err: if (thd) { - thd->clear_error(); mysql_mutex_lock(&LOCK_thread_count); THD_CHECK_SENTRY(thd); /* @@ -4040,7 +4060,7 @@ bool mts_checkpoint_routine(Relay_log_in } // end of commit_positions */ - rli->reset_notified_checkpoint(); + rli->reset_notified_checkpoint(cnt, rli->gaq->lwm.ts); end: set_timespec_nsec(rli->last_clock, 0); @@ -4083,6 +4103,7 @@ int slave_start_single_worker(Relay_log_ w->curr_group_exec_parts.elements= 0; w->relay_log_change_notified= FALSE; // the 1st group to contain relaylog name w->checkpoint_notified= FALSE; + w-> bitmap_shifted= 0; w->workers= rli->workers; // shallow copying is sufficient w->this_worker= w; w->wait_jobs= w->trans_jobs= w->stmt_jobs= w->curr_jobs= 0; @@ -5845,6 +5866,9 @@ 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(); + if (hot_log) + mysql_mutex_unlock(log_lock); + /* MTS checkpoint in the successful read branch */ @@ -5852,11 +5876,10 @@ static Log_event* next_event(Relay_log_i if (rli->is_parallel_exec() && (mts_checkpoint_period != 0 || force)) { ulonglong period= static_cast(mts_checkpoint_period * 1000000ULL); + mysql_mutex_unlock(&rli->data_lock); mts_checkpoint_routine(rli, period, force, TRUE); // TODO: ALFRANIO ERROR + mysql_mutex_lock(&rli->data_lock); } - - if (hot_log) - mysql_mutex_unlock(log_lock); DBUG_RETURN(ev); } DBUG_ASSERT(thd==rli->info_thd); @@ -5902,7 +5925,8 @@ static Log_event* next_event(Relay_log_i /* shows zero while it is sleeping (and until the next event is about to be executed) */ - rli->last_master_timestamp= 0; + if (!rli->is_parallel_exec()) + rli->last_master_timestamp= 0; DBUG_ASSERT(rli->relay_log.get_open_count() == rli->cur_log_old_open_count); @@ -5983,7 +6007,12 @@ static Log_event* next_event(Relay_log_i do { + mysql_mutex_unlock(log_lock); mts_checkpoint_routine(rli, period, FALSE, FALSE); // TODO: ALFRANIO ERROR + mysql_mutex_lock(log_lock); + if (rli->gaq->empty()) + rli->last_master_timestamp= 0; + set_timespec_nsec(waittime, period); thd->enter_cond(log_cond, log_lock, "Slave has read all relay log; " @@ -6485,8 +6514,8 @@ int start_slave(THD* thd , Master_info* { mi->rli->opt_slave_parallel_workers= 0; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_NO_FEATURE_ON_PARALLEL_SLAVE, - ER(ER_NO_FEATURE_ON_PARALLEL_SLAVE), + ER_MTS_FEATURE_IS_NOT_SUPPORTED, + ER(ER_MTS_FEATURE_IS_NOT_SUPPORTED), "UNTIL condtion", "Slave is started in the sequential execution mode."); } @@ -6498,8 +6527,8 @@ int start_slave(THD* thd , Master_info* if (mi->rli->opt_slave_parallel_workers != 0 && slave_trans_retries != 0) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_NO_FEATURE_ON_PARALLEL_SLAVE, - ER(ER_NO_FEATURE_ON_PARALLEL_SLAVE), + ER_MTS_FEATURE_IS_NOT_SUPPORTED, + ER(ER_MTS_FEATURE_IS_NOT_SUPPORTED), "Temporary failed transaction retry", "Such failure will force the slave to stop."); } === modified file 'sql/share/errmsg-utf8.txt' --- a/sql/share/errmsg-utf8.txt 2011-06-09 15:27:47 +0000 +++ b/sql/share/errmsg-utf8.txt 2011-06-12 19:05:05 +0000 @@ -6506,7 +6506,9 @@ ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DR ER_INDEX_COLUMN_TOO_LONG eng "Index column size too large. The maximum column size is %lu bytes." -ER_NO_FEATURE_ON_PARALLEL_SLAVE +ER_MTS_FEATURE_IS_NOT_SUPPORTED eng "%s is not supported in Parallel Slave. %s" -ER_UPDATED_DBS_GREATER_MAX +ER_MTS_UPDATED_DBS_GREATER_MAX eng "Modified database names number exceeds the maximum %d; the names are not written into the replication event." +ER_MTS_CANT_PARALLEL + eng "Can't execute the current event group in parallel mode running into event %s, relay-log name %s, position %s." === modified file 'sql/sp.cc' --- a/sql/sp.cc 2011-06-09 15:27:47 +0000 +++ b/sql/sp.cc 2011-06-12 19:05:05 +0000 @@ -1150,7 +1150,7 @@ sp_create_routine(THD *thd, int type, sp } /* restore sql_mode when binloging */ thd->variables.sql_mode= saved_mode; - thd->add_one_db_to_binlog_updated_dbs(sp->m_db.str); + thd->add_to_binlog_accessed_dbs(sp->m_db.str); /* Such a statement can always go directly to binlog, no trans cache */ if (thd->binlog_query(THD::STMT_QUERY_TYPE, log_query.c_ptr(), log_query.length(), @@ -1224,7 +1224,7 @@ sp_drop_routine(THD *thd, int type, sp_n if (ret == SP_OK) { - thd->add_one_db_to_binlog_updated_dbs(name->m_db.str); + thd->add_to_binlog_accessed_dbs(name->m_db.str); if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) ret= SP_INTERNAL_ERROR; sp_cache_invalidate(); === modified file 'sql/sql_acl.cc' --- a/sql/sql_acl.cc 2011-05-31 13:52:09 +0000 +++ b/sql/sql_acl.cc 2011-06-12 19:05:05 +0000 @@ -3689,6 +3689,7 @@ int mysql_table_grant(THD *thd, TABLE_LI should_write_to_binlog= TRUE; db_name= table_list->get_db_name(); + thd->add_to_binlog_accessed_dbs(db_name); // collecting db:s for MTS table_name= table_list->get_table_name(); /* Find/create cached table grant */ @@ -3912,8 +3913,9 @@ bool mysql_routine_grant(THD *thd, TABLE } db_name= table_list->db; + if (write_to_binlog) + thd->add_to_binlog_accessed_dbs(db_name); table_name= table_list->table_name; - grant_name= routine_hash_search(Str->host.str, NullS, db_name, Str->user.str, table_name, is_proc, 1); if (!grant_name) @@ -4100,6 +4102,7 @@ bool mysql_grant(THD *thd, const char *d my_error(ER_WRONG_USAGE, MYF(0), "DB GRANT", "GLOBAL PRIVILEGES"); result= -1; } + thd->add_to_binlog_accessed_dbs(db); } else if (is_proxy) { === modified file 'sql/sql_class.h' --- a/sql/sql_class.h 2011-06-09 15:27:47 +0000 +++ b/sql/sql_class.h 2011-06-12 19:05:05 +0000 @@ -1951,31 +1951,13 @@ public: } /* - MTS: initializer of binlog_accessed_db_names list - */ - void set_binlog_accessed_db_names(List* arg) - { - binlog_accessed_db_names= arg; - } - - /* MTS: resetter of binlog_accessed_db_names list normally at the end of the query execution */ void clear_binlog_accessed_db_names() { binlog_accessed_db_names= NULL; } /* MTS: method inserts a new unique name into binlog_updated_dbs */ - void add_to_binlog_updated_dbs(const char *db); - - /* - MTS: method shortcuts initialization and insertion of just one db name - into binlog_updated_dbs - */ - void add_one_db_to_binlog_updated_dbs(const char *db) - { - set_binlog_accessed_db_names(new List); - binlog_accessed_db_names->push_back(strdup_root(mem_root, db)); - } + void add_to_binlog_accessed_dbs(const char *db); #endif /* MYSQL_CLIENT */ === modified file 'sql/sql_db.cc' --- a/sql/sql_db.cc 2011-06-09 15:27:47 +0000 +++ b/sql/sql_db.cc 2011-06-12 19:05:05 +0000 @@ -657,7 +657,7 @@ not_silent: */ qinfo.db = db; qinfo.db_len = strlen(db); - thd->add_one_db_to_binlog_updated_dbs(db); + thd->add_to_binlog_accessed_dbs(db); /* These DDL methods and logging are protected with the exclusive metadata lock on the schema @@ -967,7 +967,7 @@ update_binlog: if (query_pos != query_data_start) { - thd->add_one_db_to_binlog_updated_dbs(db); + thd->add_to_binlog_accessed_dbs(db); /* These DDL methods and logging are protected with the exclusive metadata lock on the schema. === modified file 'sql/sql_rename.cc' --- a/sql/sql_rename.cc 2011-06-09 15:27:47 +0000 +++ b/sql/sql_rename.cc 2011-06-12 19:05:05 +0000 @@ -317,12 +317,8 @@ do_rename(THD *thd, TABLE_LIST *ren_tabl break; } - if (!thd->get_binlog_accessed_db_names()) - { - thd->set_binlog_accessed_db_names(new List); - } - thd->add_to_binlog_updated_dbs(ren_table->db); - thd->add_to_binlog_updated_dbs(new_db); + thd->add_to_binlog_accessed_dbs(ren_table->db); + thd->add_to_binlog_accessed_dbs(new_db); if (rc && !skip_error) DBUG_RETURN(1); === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2011-06-09 15:27:47 +0000 +++ b/sql/sql_table.cc 2011-06-12 19:05:05 +0000 @@ -2241,12 +2241,7 @@ int mysql_rm_table_no_locks(THD *thd, TA find_temporary_table(thd, table) && table->mdl_request.ticket != NULL)); - /* MTS: similarly to decide_logging_format() gathering of the db names */ - if (!thd->get_binlog_accessed_db_names()) - { - thd->set_binlog_accessed_db_names(new List); - } - thd->add_to_binlog_updated_dbs(table->db); + thd->add_to_binlog_accessed_dbs(table->db); /* drop_temporary_table may return one of the following error codes: @@ -4588,7 +4583,7 @@ bool mysql_create_table(THD *thd, TABLE_ (thd->is_current_stmt_binlog_format_row() && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))) { - thd->add_one_db_to_binlog_updated_dbs(create_table->db); + thd->add_to_binlog_accessed_dbs(create_table->db); result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans); } } @@ -6002,13 +5997,9 @@ bool mysql_alter_table(THD *thd,char *ne if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db)) new_db= db; - if (!thd->get_binlog_accessed_db_names()) - { - thd->set_binlog_accessed_db_names(new List); - } - thd->add_to_binlog_updated_dbs(db); + thd->add_to_binlog_accessed_dbs(db); if (new_db != db) - thd->add_to_binlog_updated_dbs(new_db); + thd->add_to_binlog_accessed_dbs(new_db); build_table_filename(reg_path, sizeof(reg_path) - 1, db, table_name, reg_ext, 0); build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0); === modified file 'sql/sql_trigger.cc' --- a/sql/sql_trigger.cc 2011-06-09 15:27:47 +0000 +++ b/sql/sql_trigger.cc 2011-06-12 19:05:05 +0000 @@ -528,7 +528,7 @@ end: if (!result) { if (tables) - thd->add_one_db_to_binlog_updated_dbs(tables->db); + thd->add_to_binlog_accessed_dbs(tables->db); result= write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length()); } === modified file 'sql/sql_view.cc' --- a/sql/sql_view.cc 2011-06-09 15:27:47 +0000 +++ b/sql/sql_view.cc 2011-06-12 19:05:05 +0000 @@ -690,7 +690,7 @@ bool mysql_create_view(THD *thd, TABLE_L buff.append(views->source.str, views->source.length); int errcode= query_error_code(thd, TRUE); - thd->add_one_db_to_binlog_updated_dbs(views->db); + thd->add_to_binlog_accessed_dbs(views->db); if (thd->binlog_query(THD::STMT_QUERY_TYPE, buff.ptr(), buff.length(), FALSE, FALSE, FALSE, errcode)) res= TRUE; @@ -1698,11 +1698,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIS } continue; } - if (!thd->get_binlog_accessed_db_names()) - { - thd->set_binlog_accessed_db_names(new List); - } - thd->add_to_binlog_updated_dbs(view->db); + thd->add_to_binlog_accessed_dbs(view->db); if (mysql_file_delete(key_file_frm, path, MYF(MY_WME))) error= TRUE; === modified file 'storage/blackhole/ha_blackhole.cc' --- a/storage/blackhole/ha_blackhole.cc 2011-05-26 15:20:09 +0000 +++ b/storage/blackhole/ha_blackhole.cc 2011-06-12 19:05:05 +0000 @@ -19,7 +19,7 @@ #include "unireg.h" #include "probes_mysql.h" #include "ha_blackhole.h" -#include "sql_class.h" // THD, SYSTEM_THREAD_SLAVE_SQL +#include "sql_class.h" // THD, SYSTEM_THREAD_SLAVE_* /* Static declarations for handlerton */ @@ -114,7 +114,8 @@ int ha_blackhole::update_row(const uchar { DBUG_ENTER("ha_blackhole::update_row"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL || + thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER) && thd->query() == NULL) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -123,7 +124,8 @@ int ha_blackhole::delete_row(const uchar { DBUG_ENTER("ha_blackhole::delete_row"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL || + thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER) && thd->query() == NULL) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -142,7 +144,8 @@ int ha_blackhole::rnd_next(uchar *buf) MYSQL_READ_ROW_START(table_share->db.str, table_share->table_name.str, TRUE); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL || + thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER) && thd->query() == NULL) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -232,7 +235,8 @@ int ha_blackhole::index_read_map(uchar * DBUG_ENTER("ha_blackhole::index_read"); MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL || + thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER) && thd->query() == NULL) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -249,7 +253,8 @@ int ha_blackhole::index_read_idx_map(uch DBUG_ENTER("ha_blackhole::index_read_idx"); MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL || + thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER) && thd->query() == NULL) rc= 0; else rc= HA_ERR_END_OF_FILE; @@ -265,7 +270,8 @@ int ha_blackhole::index_read_last_map(uc DBUG_ENTER("ha_blackhole::index_read_last"); MYSQL_INDEX_READ_ROW_START(table_share->db.str, table_share->table_name.str); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) + if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL || + thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER) && thd->query() == NULL) rc= 0; else rc= HA_ERR_END_OF_FILE; --===============1508118910== 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/MERGE/mysql-\ # next-mr-wl5569/ # testament_sha1: 1fec9a0953a26d79edfadace3a6d7df24706ee03 # timestamp: 2011-06-12 22:35:14 +0300 # source_branch: file:///home/andrei/MySQL/BZR/2a-23May/mysql-trunk/ # base_revision_id: alfranio.correia@stripped\ # z2kohs5ajujgd77j # # Begin bundle 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 --===============1508118910==--