List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:April 2 2011 11:34am
Subject:bzr push into mysql-next-mr-wl5569 branch (andrei.elkin:3269 to 3272) WL#5569
View as plain text  
 3272 Andrei Elkin	2011-04-02
      wl#5569 MTS
      
      a test file for benchmarking is added.
      Benchmarking results can be gained by extracting the master side generating 
      and the slave side applying times like in the following loop:
      workers=6; 
         for n in `seq 1 3`; 
           do echo; echo loop: $n; echo;
           my_mtr.sh --mysqld=--mts-slave-parallel-workers=$workers  \
                     rpl_parallel_benchmark --mysqld=--binlog-format=statement \
           && cat /dev/shm/var/mysqld.2/data/test/delta.out >> p${workers}_stmt.out 2>&1;
         done
     @ mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test
        the load generator for a test file for benchmarking is added.
     @ mysql-test/suite/rpl/r/rpl_parallel_benchmark.result
        a new results file is added.
     @ mysql-test/suite/rpl/t/rpl_parallel_benchmark-slave.opt
        slave does to log into binary log. The number of workers is supposed to set via --mysqld at mtr invocation.
     @ mysql-test/suite/rpl/t/rpl_parallel_benchmark.test
        a test file for benchmarking is added.

    added:
      mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test
      mysql-test/suite/rpl/r/rpl_parallel_benchmark.result
      mysql-test/suite/rpl/t/rpl_parallel_benchmark-master.opt
      mysql-test/suite/rpl/t/rpl_parallel_benchmark-slave.opt
      mysql-test/suite/rpl/t/rpl_parallel_benchmark.test
 3271 Andrei Elkin	2011-03-30
      wl#5754 Query event parallel execution
      
      Small cleanup for comments as requested by reviewer.
     @ sql/log_event.cc
        only comments cleanup.
     @ sql/rpl_slave.cc
        only comments cleanup.

    modified:
      sql/log_event.cc
      sql/rpl_slave.cc
 3270 Andrei Elkin	2011-02-27
      WL#5754 Query event parallel execution
      
      Bundling together implementation the whole DML+DDL Query parallel support.
      That includes:
      
      The earlierst four rev:s to cut off the DML stage of the parallel query project from
      the following devoted to DDL.
      The four skeleton parallel applying of Queries containing a temporary table,
      and implement a core of the design that is the DML queries.
      Queries can contain arbitrary features including temp tables.
      
      The DDL part also refined few items related to the general low-level design.
      In particular,  of the mark of the over-max db:s in the updated-db:s status var is turned to
      be another new constant value.
      The very last patch to the bundle addresses the last review mail notes.
     @ mysql-test/r/mysqld--help-notwin.result
        results get updated.
        ******
        results gets updated.
     @ mysql-test/suite/rpl/r/rpl_packet.result
        results updated.
     @ mysql-test/suite/rpl/r/rpl_parallel_ddl.result
        the new test results are added.
        
        ******
        results get updated.
     @ mysql-test/suite/rpl/r/rpl_parallel_multi_db.result
        new result file is added.
        ******
        results get updated.
     @ mysql-test/suite/rpl/r/rpl_parallel_start_stop.result
        results get updated.
     @ mysql-test/suite/rpl/r/rpl_parallel_temp_query.result
        a new results file
        ******
        new result file is added.
     @ mysql-test/suite/rpl/t/rpl_packet.test
        making a hashing fixes in order the test to pass. 
        todo: refine logics of max_allowed_packed for master & slave.
     @ mysql-test/suite/rpl/t/rpl_parallel_ddl.test
        DDL specifics for parallelization tests are added.
        ******
        added over-the-max updated db:s case through RENAME tables.
        ******
        added remained DDL set members to test.
     @ mysql-test/suite/rpl/t/rpl_parallel_fallback.test
        Marked a todo.
     @ mysql-test/suite/rpl/t/rpl_parallel_multi_db.test
        multi-db DML query test is added.
        todo: add triggers, sf(), SP.
        ******
        adding stored routines testing.
        ******
        increased the number of db:s. Notice that forces to change the default of --thread-stack size;
        added over-the-max updated db:s case through multi-updates.
     @ mysql-test/suite/rpl/t/rpl_parallel_start_stop.test
        removed explicit log pos from the results.
     @ mysql-test/suite/rpl/t/rpl_parallel_temp_query.test
        query with temporary tables testing.
     @ mysql-test/suite/sys_vars/r/all_vars.result
        results get updated.
     @ sql/binlog.cc
        gathering to be updated db in the DML case. Over-MAX_DBS_IN_QUERY_MTS-sized list won't be shipped
        to the slave.
        ******
        correcting memory allocation to be in thd's memroot.
        ******
        separating out multiple db gathering into a THD method to be invoked as for DML so
        for few cases of DDL.
        ******
        Changed location of comparisions against MAX_DBS_IN_QUERY_MTS to be inside the adding to db list method;
        refined logics of gathering db in decide_(): *all* db:s whenever there is at least one table to update are picked up.
        ******
        Comments are added, other changes are due to MAX_DBS_IN_QUERY_MTS + 1 ceased to be the over-max mark.
     @ sql/events.cc
        gathering updated dbs for create/drop events.
     @ sql/field.cc
        relaxing an assert (todo: add to it more specific claim field->table is temp).
        ******
        adding comments to asserts.
        ******
        improved comments.
     @ sql/handler.cc
        relaxing an assert (todo: add to it more specific claim table is temp).
        ******
        adding comments to asserts.
     @ sql/log_event.cc
        master and slave (Coord's and Worker's) handling of updated db:s.
        The Coordinator's distribution changed to involve a loop per db, similaraly for the Worker
        at applying.
        ******
        adding comments and correcting clearence of binlog_updated_db_names to not let
        BEGIN, COMMIT in particular to get the updated list.
        ******
        removed an extraneous assert.
        ******
        cleaned some parts of the code;
        improved comments;
        refined an assert;
        turned Coordinator to use a specific new mem-root;
        other changes are due to MAX_DBS_IN_QUERY_MTS + 1 ceased to be the over-max mark.
     @ sql/log_event.h
        Hardcoding the max updated db:s.
        Static allocation for updated db:s in Query log event is motivated
        by the fact of the event is shared by both C and W and the standard malloc/free
        can't be a reasonble choice either.
        Added a new status and changed dependent info.
        Added a new method to return the *list* of updated db:s which in all but Query case
        is just a wrapper over get_db().
        
        ******
        adding commits, and interfaces to helper functions.
        ******
        updated some comments.
        ******
        added OVER_MAX_DBS_IN_QUERY_MTS to serve as the over-max db:s mark instead of the former MAX_DBS_IN_QUERY_MTS + 1;
        mts_get_dbs() receives a mem-root arg supplied by Worker or Coord.
     @ sql/mysqld.cc
        removed opt_mts_master_updated_dbs_max.
     @ sql/mysqld.h
        removed opt_mts_master_updated_dbs_max.
     @ sql/rpl_rli.cc
        a new temp table mutex init, destroy and a set of helper functions providing access
        to C,W's thd:s in arbitrary place of the server code are added.
        ******
        fixing an error.
        ******
        relocalating helper functions to rpl_slave.cc.
     @ sql/rpl_rli.h
        a new temp table mutex is added to RLI class.
        ******
        improving comments.
        ******
        A memroot for the Coordiator is placed into rli.
     @ sql/rpl_slave.cc
        SLAVE_THD_WORKER appeared to be redundant. Worker's thd->system_thread is set to the same
        as the Coordinator thread constant.
        ******
        Added a work-around/cleanup needed by the standard temp table closing algorithm.
        ******
        comments explaining close_temp_tables() not to run by Workers.
        Accepting relocated functions.
        ******
        init alloc and the final destuction of the Coord rli->mts_coor_mem_root mem-root.
     @ sql/rpl_slave.h
        declarations of auxiliary func:s defined in rpl_slave.cc are moved from log_event.h.
     @ sql/share/errmsg-utf8.txt
        Added a new error/warning on master specific to Query parallel replication.
     @ sql/sp.cc
        covering db gathering for create/drop SP.
     @ sql/sql_base.cc
        replacing refs to thd->temporary with an appropriate one corresponding to the Coord's thd->t_t:s.
        Also surrounding critical sections of codes dealing with opening, finding, closing or changing
        temproray_tables' list with a specific mutex lock/unlock.
        ******
        Correcting and simplifying logics for the temp table parallel support.
        In particular close_temporary_tables() does not need to know about thd of the caller.
        
        ******
        simplified the temp table support related addons.
        The double ref to thd->temporary_table is needed only in one place.
     @ sql/sql_class.cc
        master side gathering updated db:s new memeber initializations.
        ******
        Correcting logics of merging the updated db:s of a child to the parent's top-level.
        ******
        removed dead-comments.
     @ sql/sql_class.h
        master side gathering updated db:s list and accessor members. 
        ******
        adding a necessary cleanup method.
        ******
        adding two base methods of db gathering: one for a queries that can update only one db,
        and the other for multiple db:s.
        
        ******
        added more comments, removed dead-codes.
     @ sql/sql_db.cc
        create/drop database case of db gathering.
     @ sql/sql_rename.cc
        rename table(s) case of db gathering.
     @ sql/sql_table.cc
        create, drop, alter cases of db gathering.
        ******
        Changed location of comparisions against MAX_DBS_IN_QUERY_MTS to be inside the adding to db list method.
     @ sql/sql_trigger.cc
        create/drop trigger case of db gathering.
     @ sql/sql_view.cc
        support for CREATE/DROP views is added.
     @ sql/sys_vars.cc
        Added a system variable (todo/fixme: may turn out to be unnecessary though).
        
        ******
        removed ealier added variable.

    added:
      mysql-test/suite/rpl/r/rpl_parallel_ddl.result
      mysql-test/suite/rpl/r/rpl_parallel_multi_db.result
      mysql-test/suite/rpl/r/rpl_parallel_temp_query.result
      mysql-test/suite/rpl/t/rpl_parallel_ddl.test
      mysql-test/suite/rpl/t/rpl_parallel_multi_db-master.opt
      mysql-test/suite/rpl/t/rpl_parallel_multi_db-slave.opt
      mysql-test/suite/rpl/t/rpl_parallel_multi_db.test
      mysql-test/suite/rpl/t/rpl_parallel_temp_query.test
    modified:
      mysql-test/r/mysqld--help-notwin.result
      mysql-test/suite/rpl/r/rpl_packet.result
      mysql-test/suite/rpl/r/rpl_parallel_start_stop.result
      mysql-test/suite/rpl/t/rpl_packet.test
      mysql-test/suite/rpl/t/rpl_parallel_fallback.test
      mysql-test/suite/rpl/t/rpl_parallel_start_stop.test
      mysql-test/suite/sys_vars/r/all_vars.result
      sql/binlog.cc
      sql/events.cc
      sql/field.cc
      sql/handler.cc
      sql/log_event.cc
      sql/log_event.h
      sql/mysqld.cc
      sql/mysqld.h
      sql/rpl_rli.cc
      sql/rpl_rli.h
      sql/rpl_slave.cc
      sql/rpl_slave.h
      sql/share/errmsg-utf8.txt
      sql/sp.cc
      sql/sql_base.cc
      sql/sql_class.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
      sql/sys_vars.cc
 3269 Andrei Elkin	2011-01-12 [merge]
      merging from mysql-trunk

    removed:
      include/my_no_pthread.h
      libmysqld/copyright
      mysys/mf_brkhant.c
      storage/ndb/docs/doxygen/header.mgmapi.tex
      storage/ndb/docs/doxygen/header.ndbapi.tex
      storage/ndb/src/cw/cpcc-win32/vb6/
      storage/ndb/src/cw/cpcc-win32/vb6/Computer.cls
      storage/ndb/src/cw/cpcc-win32/vb6/Database.cls
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 110.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 231.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 237.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 241.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 242.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 270.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 271.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 273.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 31.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 337.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 338.ico
      storage/ndb/src/cw/cpcc-win32/vb6/Icon 339.ico
      storage/ndb/src/cw/cpcc-win32/vb6/MSSCCPRJ.SCC
      storage/ndb/src/cw/cpcc-win32/vb6/Module1.bas
      storage/ndb/src/cw/cpcc-win32/vb6/NdbCPC.vbp
      storage/ndb/src/cw/cpcc-win32/vb6/NdbCPC.vbw
      storage/ndb/src/cw/cpcc-win32/vb6/Process.cls
      storage/ndb/src/cw/cpcc-win32/vb6/closed folder.ico
      storage/ndb/src/cw/cpcc-win32/vb6/computer.ico
      storage/ndb/src/cw/cpcc-win32/vb6/frmAbout.frm
      storage/ndb/src/cw/cpcc-win32/vb6/frmLogin.frm
      storage/ndb/src/cw/cpcc-win32/vb6/frmMain.frm
      storage/ndb/src/cw/cpcc-win32/vb6/frmNewComputer.frm
      storage/ndb/src/cw/cpcc-win32/vb6/frmNewComputer.frx
      storage/ndb/src/cw/cpcc-win32/vb6/frmNewDatabase.frx
      storage/ndb/src/cw/cpcc-win32/vb6/frmNewDatabase1.frm
      storage/ndb/src/cw/cpcc-win32/vb6/frmNewDatabase2.frm
      storage/ndb/src/cw/cpcc-win32/vb6/frmNewDatabase2.log
      storage/ndb/src/cw/cpcc-win32/vb6/frmNewDatabase3.frm
      storage/ndb/src/cw/cpcc-win32/vb6/frmOptions.frm
      storage/ndb/src/cw/cpcc-win32/vb6/frmSplash.frx
      storage/ndb/src/cw/cpcc-win32/vb6/networking.ico
      storage/ndb/src/cw/cpcc-win32/vb6/open folder.ico
    added:
      mysql-test/r/filesort_debug.result
      mysql-test/t/filesort_debug.test
    renamed:
      mysql-test/suite/funcs_1/r/myisam_views.result => mysql-test/suite/funcs_1/r/myisam_views-big.result
      mysql-test/suite/funcs_1/t/myisam_views.test => mysql-test/suite/funcs_1/t/myisam_views-big.test
    modified:
      BUILD/FINISH.sh
      BUILD/SETUP.sh
      BUILD/autorun.sh
      BUILD/build_mccge.sh
      BUILD/check-cpu
      BUILD/cleanup
      BUILD/cmake_configure.sh
      BUILD/compile-alpha
      BUILD/compile-alpha-debug
      BUILD/compile-amd64-debug-max
      BUILD/compile-amd64-debug-max-no-ndb
      BUILD/compile-amd64-gcov
      BUILD/compile-amd64-gprof
      BUILD/compile-amd64-max
      BUILD/compile-amd64-max-sci
      BUILD/compile-amd64-valgrind-max
      BUILD/compile-darwin-mwcc
      BUILD/compile-dist
      BUILD/compile-hpux11-parisc2-aCC
      BUILD/compile-ia64-debug-max
      BUILD/compile-irix-mips64-mipspro
      BUILD/compile-ndb-autotest
      BUILD/compile-pentium
      BUILD/compile-pentium-cybozu
      BUILD/compile-pentium-debug
      BUILD/compile-pentium-debug-max
      BUILD/compile-pentium-debug-max-no-embedded
      BUILD/compile-pentium-debug-max-no-ndb
      BUILD/compile-pentium-debug-openssl
      BUILD/compile-pentium-debug-yassl
      BUILD/compile-pentium-gcov
      BUILD/compile-pentium-gprof
      BUILD/compile-pentium-icc
      BUILD/compile-pentium-icc-valgrind-max
      BUILD/compile-pentium-icc-yassl
      BUILD/compile-pentium-max
      BUILD/compile-pentium-myodbc
      BUILD/compile-pentium-pgcc
      BUILD/compile-pentium-valgrind-max
      BUILD/compile-pentium-valgrind-max-no-ndb
      BUILD/compile-pentium64
      BUILD/compile-pentium64-debug
      BUILD/compile-pentium64-debug-max
      BUILD/compile-pentium64-gcov
      BUILD/compile-pentium64-gprof
      BUILD/compile-pentium64-max
      BUILD/compile-pentium64-max-sci
      BUILD/compile-pentium64-valgrind-max
      BUILD/compile-ppc
      BUILD/compile-ppc-debug
      BUILD/compile-ppc-debug-max
      BUILD/compile-ppc-debug-max-no-ndb
      BUILD/compile-ppc-max
      BUILD/compile-solaris-amd64
      BUILD/compile-solaris-amd64-debug
      BUILD/compile-solaris-amd64-forte
      BUILD/compile-solaris-amd64-forte-debug
      BUILD/compile-solaris-sparc
      BUILD/compile-solaris-sparc-debug
      BUILD/compile-solaris-sparc-forte
      BUILD/compile-solaris-sparc-purify
      client/completion_hash.h
      client/mysqladmin.cc
      cmd-line-utils/readline/CMakeLists.txt
      config.h.cmake
      dbug/dbug.c
      dbug/dbug_add_tags.pl
      dbug/dbug_analyze.c
      dbug/my_main.c
      dbug/tests.c
      extra/yassl/examples/client/client.cpp
      extra/yassl/examples/echoclient/echoclient.cpp
      extra/yassl/examples/echoserver/echoserver.cpp
      extra/yassl/examples/server/server.cpp
      extra/yassl/include/lock.hpp
      extra/yassl/include/openssl/crypto.h
      extra/yassl/include/openssl/des.h
      extra/yassl/include/openssl/des_old.h
      extra/yassl/include/openssl/engine.h
      extra/yassl/include/openssl/err.h
      extra/yassl/include/openssl/evp.h
      extra/yassl/include/openssl/generate_prefix_files.pl
      extra/yassl/include/openssl/hmac.h
      extra/yassl/include/openssl/lhash.h
      extra/yassl/include/openssl/md4.h
      extra/yassl/include/openssl/md5.h
      extra/yassl/include/openssl/objects.h
      extra/yassl/include/openssl/opensslv.h
      extra/yassl/include/openssl/pem.h
      extra/yassl/include/openssl/pkcs12.h
      extra/yassl/include/openssl/prefix_crypto.h
      extra/yassl/include/openssl/prefix_ssl.h
      extra/yassl/include/openssl/rand.h
      extra/yassl/include/openssl/rsa.h
      extra/yassl/include/openssl/sha.h
      extra/yassl/include/openssl/x509.h
      extra/yassl/include/openssl/x509v3.h
      extra/yassl/src/lock.cpp
      extra/yassl/src/make.bat
      extra/yassl/taocrypt/benchmark/benchmark.cpp
      extra/yassl/taocrypt/benchmark/make.bat
      extra/yassl/taocrypt/src/make.bat
      extra/yassl/taocrypt/test/make.bat
      extra/yassl/taocrypt/test/memory.cpp
      extra/yassl/taocrypt/test/test.cpp
      extra/yassl/testsuite/make.bat
      extra/yassl/testsuite/test.hpp
      extra/yassl/testsuite/testsuite.cpp
      include/CMakeLists.txt
      include/heap.h
      include/my_base.h
      include/my_bitmap.h
      include/my_global.h
      include/my_handler.h
      include/my_pthread.h
      include/my_sys.h
      include/myisam.h
      include/mysql_com.h
      include/thr_alarm.h
      libmysql/client_settings.h
      libmysql/libmysql.c
      libmysqld/examples/test-run
      mysql-test/collections/default.experimental
      mysql-test/collections/default.weekly
      mysql-test/collections/mysql-trunk.weekly
      mysql-test/include/icp_tests.inc
      mysql-test/lib/mtr_cases.pm
      mysql-test/lib/mtr_process.pl
      mysql-test/mysql-stress-test.pl
      mysql-test/mysql-test-run.pl
      mysql-test/purify.supp
      mysql-test/r/auto_increment.result
      mysql-test/r/func_math.result
      mysql-test/r/innodb_icp.result
      mysql-test/r/innodb_icp_none.result
      mysql-test/r/innodb_mysql_sync.result
      mysql-test/r/myisam_icp.result
      mysql-test/r/myisam_icp_none.result
      mysql-test/r/myisam_mrr_all.result
      mysql-test/r/myisam_mrr_cost_all.result
      mysql-test/r/mysqlbinlog.result
      mysql-test/r/not_embedded_server.result
      mysql-test/r/order_by_all.result
      mysql-test/r/partition.result
      mysql-test/r/partition_error.result
      mysql-test/r/partition_range.result
      mysql-test/r/select_all.result
      mysql-test/r/select_all_jcl6.result
      mysql-test/r/select_icp_mrr_jcl6.result
      mysql-test/r/select_none_jcl6.result
      mysql-test/r/show_check.result
      mysql-test/r/udf.result
      mysql-test/r/union.result
      mysql-test/suite/engines/funcs/r/db_alter_character_set.result
      mysql-test/suite/engines/funcs/r/db_alter_collate_ascii.result
      mysql-test/suite/engines/funcs/r/db_alter_collate_utf8.result
      mysql-test/suite/engines/funcs/r/in_multicolumn_string_pk_constraint_error.result
      mysql-test/suite/engines/funcs/r/in_multicolumn_string_pk_constraint_ignore.result
      mysql-test/suite/engines/funcs/r/in_multicolumn_string_unique_constraint_error.result
      mysql-test/suite/engines/funcs/r/in_string_pk_constraint_error.result
      mysql-test/suite/engines/funcs/r/in_string_unique_constraint_error.result
      mysql-test/suite/engines/funcs/r/rpl000013.result
      mysql-test/suite/engines/funcs/r/rpl_000015.result
      mysql-test/suite/engines/funcs/r/rpl_change_master.result
      mysql-test/suite/engines/funcs/r/rpl_drop.result
      mysql-test/suite/engines/funcs/r/rpl_flushlog_loop.result
      mysql-test/suite/engines/funcs/r/rpl_loaddata_s.result
      mysql-test/suite/engines/funcs/r/rpl_log_pos.result
      mysql-test/suite/engines/funcs/r/rpl_rbr_to_sbr.result
      mysql-test/suite/engines/funcs/r/rpl_row_drop.result
      mysql-test/suite/engines/funcs/r/rpl_row_inexist_tbl.result
      mysql-test/suite/engines/funcs/r/rpl_row_reset_slave.result
      mysql-test/suite/engines/funcs/r/rpl_row_sp005.result
      mysql-test/suite/engines/funcs/r/rpl_row_trig003.result
      mysql-test/suite/engines/funcs/r/rpl_row_until.result
      mysql-test/suite/engines/funcs/r/rpl_server_id1.result
      mysql-test/suite/engines/funcs/r/rpl_server_id2.result
      mysql-test/suite/engines/funcs/r/rpl_session_var.result
      mysql-test/suite/engines/funcs/r/rpl_slave_status.result
      mysql-test/suite/engines/funcs/r/rpl_stm_no_op.result
      mysql-test/suite/engines/funcs/r/rpl_switch_stm_row_mixed.result
      mysql-test/suite/engines/funcs/r/rpl_temp_table.result
      mysql-test/suite/engines/funcs/r/rpl_trigger.result
      mysql-test/suite/engines/funcs/r/se_join_left.result
      mysql-test/suite/engines/funcs/r/se_join_left_outer.result
      mysql-test/suite/engines/funcs/r/se_join_natural_left.result
      mysql-test/suite/engines/funcs/r/se_join_natural_left_outer.result
      mysql-test/suite/engines/funcs/r/sf_alter.result
      mysql-test/suite/engines/funcs/r/sf_cursor.result
      mysql-test/suite/engines/funcs/r/sp_alter.result
      mysql-test/suite/engines/funcs/r/sp_cursor.result
      mysql-test/suite/engines/funcs/r/ta_rename.result
      mysql-test/suite/engines/funcs/t/db_alter_collate_utf8.test
      mysql-test/suite/engines/funcs/t/disabled.def
      mysql-test/suite/engines/funcs/t/in_multicolumn_string_pk_constraint_error.test
      mysql-test/suite/engines/funcs/t/in_multicolumn_string_pk_constraint_ignore.test
      mysql-test/suite/engines/funcs/t/in_multicolumn_string_unique_constraint_error.test
      mysql-test/suite/engines/funcs/t/in_string_pk_constraint_error.test
      mysql-test/suite/engines/funcs/t/in_string_unique_constraint_error.test
      mysql-test/suite/engines/funcs/t/rpl000013.test
      mysql-test/suite/engines/funcs/t/rpl_000015.test
      mysql-test/suite/engines/funcs/t/rpl_change_master.test
      mysql-test/suite/engines/funcs/t/rpl_err_ignoredtable.test
      mysql-test/suite/engines/funcs/t/rpl_flushlog_loop.test
      mysql-test/suite/engines/funcs/t/rpl_get_lock.test
      mysql-test/suite/engines/funcs/t/rpl_loaddata_s.test
      mysql-test/suite/engines/funcs/t/rpl_loadfile.test
      mysql-test/suite/engines/funcs/t/rpl_log_pos.test
      mysql-test/suite/engines/funcs/t/rpl_misc_functions.test
      mysql-test/suite/engines/funcs/t/rpl_rbr_to_sbr.test
      mysql-test/suite/engines/funcs/t/rpl_row_drop.test
      mysql-test/suite/engines/funcs/t/rpl_row_inexist_tbl.test
      mysql-test/suite/engines/funcs/t/rpl_row_until.test
      mysql-test/suite/engines/funcs/t/rpl_server_id1.test
      mysql-test/suite/engines/funcs/t/rpl_server_id2.test
      mysql-test/suite/engines/funcs/t/rpl_slave_status.test
      mysql-test/suite/engines/funcs/t/rpl_switch_stm_row_mixed.test
      mysql-test/suite/engines/funcs/t/rpl_temp_table.test
      mysql-test/suite/engines/funcs/t/rpl_temporary.test
      mysql-test/suite/engines/funcs/t/rpl_trigger.test
      mysql-test/suite/engines/funcs/t/se_join_left.test
      mysql-test/suite/engines/funcs/t/se_join_left_outer.test
      mysql-test/suite/engines/funcs/t/se_join_natural_left.test
      mysql-test/suite/engines/funcs/t/se_join_natural_left_outer.test
      mysql-test/suite/engines/iuds/r/insert_number.result
      mysql-test/suite/engines/iuds/r/strings_charsets_update_delete.result
      mysql-test/suite/engines/iuds/r/strings_update_delete.result
      mysql-test/suite/engines/iuds/r/type_bit_iuds.result
      mysql-test/suite/engines/iuds/r/update_delete_calendar.result
      mysql-test/suite/engines/iuds/r/update_delete_number.result
      mysql-test/suite/engines/iuds/t/disabled.def
      mysql-test/suite/engines/iuds/t/insert_number.test
      mysql-test/suite/engines/iuds/t/update_delete_calendar.test
      mysql-test/suite/innodb/r/innodb-timeout.result
      mysql-test/suite/innodb/r/innodb.result
      mysql-test/suite/innodb/t/innodb-timeout.test
      mysql-test/suite/innodb/t/innodb.test
      mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc
      mysql-test/suite/parts/r/part_supported_sql_func_innodb.result
      mysql-test/suite/parts/r/part_supported_sql_func_myisam.result
      mysql-test/suite/perfschema/include/binlog_common.inc
      mysql-test/suite/perfschema/r/binlog_mix.result
      mysql-test/suite/perfschema/r/binlog_row.result
      mysql-test/suite/perfschema/r/binlog_stmt.result
      mysql-test/suite/perfschema/t/binlog_mix.test
      mysql-test/suite/perfschema/t/binlog_row.test
      mysql-test/suite/perfschema/t/binlog_stmt.test
      mysql-test/t/auto_increment.test
      mysql-test/t/func_math.test
      mysql-test/t/innodb_mysql_sync.test
      mysql-test/t/mysqlbinlog.test
      mysql-test/t/not_embedded_server.test
      mysql-test/t/partition.test
      mysql-test/t/partition_error.test
      mysql-test/t/partition_range.test
      mysql-test/t/show_check.test
      mysql-test/t/udf.test
      mysql-test/t/union.test
      mysql-test/valgrind.supp
      mysys/mf_iocache.c
      mysys/mf_iocache2.c
      mysys/mf_keycache.c
      mysys/mf_keycaches.c
      mysys/mf_pack.c
      mysys/my_bitmap.c
      mysys/my_fopen.c
      mysys/my_fstream.c
      mysys/my_gethostbyname.c
      mysys/my_getsystime.c
      mysys/my_init.c
      mysys/my_lib.c
      mysys/my_open.c
      mysys/my_pread.c
      mysys/my_pthread.c
      mysys/my_read.c
      mysys/my_static.c
      mysys/my_thr_init.c
      mysys/my_write.c
      mysys/mysys_priv.h
      mysys/thr_alarm.c
      mysys/thr_lock.c
      mysys/thr_mutex.c
      mysys/thr_rwlock.c
      scripts/fill_help_tables.sql
      scripts/make_binary_distribution.sh
      scripts/make_win_bin_dist
      scripts/mysql_fix_extensions.sh
      scripts/mysql_setpermission.sh
      scripts/mysql_system_tables_data.sql
      scripts/mysql_system_tables_fix.sql
      scripts/mysql_test_data_timezone.sql
      scripts/mysqlaccess.sh
      scripts/mysqld_multi.sh
      scripts/mysqldumpslow.sh
      scripts/mysqlhotcopy.sh
      sql-common/client.c
      sql-common/client_plugin.c
      sql/bounded_queue.h
      sql/client_settings.h
      sql/field.cc
      sql/filesort.cc
      sql/gen_lex_hash.cc
      sql/ha_partition.cc
      sql/handler.cc
      sql/handler.h
      sql/item.h
      sql/item_cmpfunc.cc
      sql/item_cmpfunc.h
      sql/item_func.cc
      sql/item_func.h
      sql/item_subselect.cc
      sql/item_sum.cc
      sql/item_timefunc.h
      sql/log.cc
      sql/log_event.cc
      sql/log_event.h
      sql/message.h
      sql/net_serv.cc
      sql/set_var.cc
      sql/set_var.h
      sql/share/charsets/languages.html
      sql/sql_admin.cc
      sql/sql_base.cc
      sql/sql_partition.cc
      sql/sql_select.cc
      sql/sql_show.cc
      sql/sql_udf.cc
      sql/sql_yacc.yy
      sql/table.cc
      storage/heap/heapdef.h
      storage/heap/hp_block.c
      storage/heap/hp_create.c
      storage/heap/hp_delete.c
      storage/heap/hp_open.c
      storage/heap/hp_static.c
      storage/heap/hp_test2.c
      storage/innobase/btr/btr0btr.c
      storage/innobase/btr/btr0cur.c
      storage/innobase/buf/buf0buf.c
      storage/innobase/dict/dict0dict.c
      storage/innobase/fsp/fsp0fsp.c
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/handler/i_s.cc
      storage/innobase/include/btr0cur.h
      storage/innobase/include/data0data.h
      storage/innobase/include/data0data.ic
      storage/innobase/include/row0upd.h
      storage/innobase/include/srv0srv.h
      storage/innobase/include/sync0rw.h
      storage/innobase/include/trx0i_s.h
      storage/innobase/include/trx0purge.h
      storage/innobase/include/univ.i
      storage/innobase/log/log0recv.c
      storage/innobase/row/row0mysql.c
      storage/innobase/row/row0purge.c
      storage/innobase/row/row0umod.c
      storage/innobase/row/row0upd.c
      storage/innobase/srv/srv0srv.c
      storage/innobase/srv/srv0start.c
      storage/innobase/trx/trx0i_s.c
      storage/innobase/trx/trx0purge.c
      storage/innobase/ut/ut0dbg.c
      storage/myisam/ftbench/Ecompare.pl
      storage/myisam/ftbench/Ecreate.pl
      storage/myisam/ftbench/Ereport.pl
      storage/myisam/ftbench/ft-test-run.sh
      storage/myisam/ha_myisam.cc
      storage/myisam/mi_check.c
      storage/myisam/mi_close.c
      storage/myisam/mi_delete.c
      storage/myisam/mi_delete_all.c
      storage/myisam/mi_dynrec.c
      storage/myisam/mi_log.c
      storage/myisam/mi_open.c
      storage/myisam/mi_static.c
      storage/myisam/mi_statrec.c
      storage/myisam/mi_test_all.sh
      storage/myisam/mi_update.c
      storage/myisam/mi_write.c
      storage/myisam/myisamdef.h
      storage/myisam/myisampack.c
      storage/myisam/rt_index.c
      storage/myisam/sort.c
      storage/myisammrg/myrg_def.h
      storage/ndb/Makefile.am
      storage/ndb/config/make-win-dsw.sh
      storage/ndb/config/win-includes
      storage/ndb/config/win-libraries
      storage/ndb/config/win-name
      storage/ndb/config/win-sources
      storage/ndb/docs/Makefile.am
      storage/ndb/docs/doxygen/Doxyfile.mgmapi
      storage/ndb/docs/doxygen/Doxyfile.ndb
      storage/ndb/docs/doxygen/Doxyfile.ndbapi
      storage/ndb/docs/doxygen/Doxyfile.odbc
      storage/ndb/docs/doxygen/postdoxy.pl
      storage/ndb/docs/doxygen/predoxy.pl
      storage/ndb/src/cw/cpcc-win32/csharp/CPC_Form.cs
      storage/ndb/src/cw/cpcc-win32/csharp/Computer.cs
      storage/ndb/src/cw/cpcc-win32/csharp/ComputerAddDialog.cs
      storage/ndb/src/cw/cpcc-win32/csharp/ComputerRemoveDialog.cs
      storage/ndb/src/cw/cpcc-win32/csharp/Database.cs
      storage/ndb/src/cw/cpcc-win32/csharp/PanelWizard.cs
      storage/ndb/src/cw/cpcc-win32/csharp/Process.cs
      storage/ndb/src/cw/cpcc-win32/csharp/ProcessDefineDialog.cs
      storage/ndb/src/cw/cpcc-win32/csharp/fileaccess/FileMgmt.cs
      storage/ndb/src/cw/cpcc-win32/csharp/simpleparser/SimpleCPCParser.cs
      storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/SocketComm.cs
      storage/ndb/src/cw/cpcc-win32/csharp/socketcomm/myTcpClient.cs
      storage/ndb/src/cw/cpcc-win32/csharp/startDatabaseDlg.cs
      storage/ndb/src/cw/cpcc-win32/csharp/telnetclient/telnetClient.cs
      storage/ndb/src/libndb.ver.in
      storage/ndb/test/ndbapi/slow_select.cpp
      storage/ndb/test/ndbapi/testBitfield.cpp
      storage/ndb/test/ndbapi/testLcp.cpp
      storage/ndb/test/ndbnet/test.run
      storage/ndb/test/ndbnet/testError.run
      storage/ndb/test/ndbnet/testMNF.run
      storage/ndb/test/ndbnet/testNR.run
      storage/ndb/test/ndbnet/testNR1.run
      storage/ndb/test/ndbnet/testNR4.run
      storage/ndb/test/ndbnet/testSRhang.run
      storage/ndb/test/ndbnet/testTR295.run
      storage/ndb/test/run-test/16node-tests.txt
      storage/ndb/test/run-test/atrt-analyze-result.sh
      storage/ndb/test/run-test/atrt-clear-result.sh
      storage/ndb/test/run-test/atrt-gather-result.sh
      storage/ndb/test/run-test/atrt-mysql-test-run
      storage/ndb/test/run-test/atrt-setup.sh
      storage/ndb/test/run-test/atrt-testBackup
      storage/ndb/test/run-test/basic.txt
      storage/ndb/test/run-test/daily-basic-tests.txt
      storage/ndb/test/run-test/daily-devel-tests.txt
      storage/ndb/test/run-test/make-config.sh
      storage/ndb/test/run-test/make-html-reports.sh
      storage/ndb/test/run-test/make-index.sh
      storage/ndb/test/run-test/ndb-autotest.sh
      storage/ndb/test/sql/test_create_drop.pl
      storage/ndb/test/sql/test_range_bounds.pl
      storage/ndb/tools/clean-links.sh
      storage/ndb/tools/make-errors.pl
      storage/ndb/tools/make-links.sh
      storage/ndb/tools/ndb_error_reporter
      storage/ndb/tools/rgrep
      support-files/MacOSX/Description.plist.sh
      support-files/MacOSX/Info.plist.sh
      support-files/MacOSX/MySQLCOM
      support-files/MacOSX/StartupItem.Description.plist
      support-files/MacOSX/StartupItem.Info.plist
      support-files/MacOSX/StartupItem.postinstall
      support-files/MacOSX/StartupParameters.plist.sh
      support-files/MacOSX/mwar-wrapper
      support-files/MacOSX/mwcc-wrapper
      support-files/MacOSX/postflight.sh
      support-files/MacOSX/preflight.sh
      support-files/RHEL4-SElinux/mysql.fc
      support-files/RHEL4-SElinux/mysql.te
      support-files/compiler_warnings.supp
      tests/big_record.pl
      tests/drop_test.pl
      tests/export.pl
      tests/fork2_test.pl
      tests/fork_big.pl
      tests/fork_big2.pl
      tests/grant.pl
      tests/index_corrupt.pl
      tests/insert_and_repair.pl
      tests/lock_test.pl
      tests/mysql_client_test.c
      tests/pmail.pl
      tests/rename_test.pl
      tests/table_types.pl
      tests/test_delayed_insert.pl
      tests/thread_test.c
      tests/truncate.pl
      unittest/gunit/bounded_queue-t.cc
      unittest/gunit/mdl-t.cc
      unittest/gunit/mdl_mytap-t.cc
      unittest/gunit/my_regex-t.cc
      unittest/gunit/sql_list-t.cc
      unittest/gunit/thread_utils-t.cc
      unittest/gunit/thread_utils.cc
      mysql-test/suite/funcs_1/t/myisam_views-big.test
=== added file 'mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test'
--- a/mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_parallel_benchmark_load.test	2011-04-02 11:32:02 +0000
@@ -0,0 +1,274 @@
+#
+# This is a load generator to call from rpl_parallel and rpl_sequential tests
+#
+
+#
+# load volume parameter
+#
+
+let $iter= 128;
+let $tables= 4;
+let $wk_queries= 16;
+let $nk_queries= 0;
+let $pre_inserted_rows= 400;
+
+connection slave;
+
+call mtr.add_suppression('Slave: Error dropping database'); ## todo: fix
+
+source include/stop_slave.inc;
+start slave;
+
+connection master;
+
+--disable_query_log
+--disable_result_log
+
+use test;
+delimiter |;
+create procedure one_session(k int)
+begin
+  while k > 0 do
+    insert into tm_nk values(k, 0);
+    insert into tm_wk values(null, 0);
+    insert into ti_nk values(k, 0);
+    insert into ti_wk values(null, 0);
+    set k = k - 1;
+  end while;
+end|
+delimiter ;|
+
+## let $i = $workers + 1;
+##eval 
+# delimiter |;
+# create procedure p1(i int)
+# begin
+#     while i > 0
+#       ##while ($i)
+#       ##{
+#       ## let $i1=$i;
+#       ## dec $i1;
+#       ## use test$i1;
+#       ## call on_session();
+#       ## dec $i;
+#       ##}
+#       use test0;
+#       call one_session();
+#       use test1;
+#       call one_session();
+#       use test2;
+#       call one_session();
+#       use test3;
+#       call one_session();
+#       i= i-1;
+#     end while;
+# end|
+# delimiter ;|
+
+
+let $i = $databases;
+while($i)
+{
+  eval create database test$i;
+
+  let $m= $tables;
+  while ($m)
+  {
+  eval create table test$i.tm_nk_$m (a int, b int, c text) engine=myisam;
+  eval create table test$i.tm_wk_$m (a int auto_increment primary key, b int, c text) engine=myisam;
+  eval create table test$i.ti_nk_$m (a int, b int, c text) engine=innodb;
+  eval create table test$i.ti_wk_$m (a int auto_increment primary key, b int, c text) engine=innodb;
+  let $k= $pre_inserted_rows;
+  while ($k)
+  {
+   eval insert into test$i.ti_wk_$m values(null,  $i, uuid());
+   eval insert into test$i.ti_nk_$m values(null,  $i, uuid());
+
+   dec $k;
+  }
+  dec $m;
+  }
+
+
+  # this table is special - just for timing. It's more special on test1 db
+  # where it contains master timing of the load as well.
+  eval create table test$i.benchmark (state text) engine=myisam; # timestamp keep on the slave side
+
+  dec $i;
+}
+
+--enable_result_log
+--enable_query_log
+
+
+sync_slave_with_master;
+#connection slave;
+
+--disable_query_log
+--disable_result_log
+
+let $i = $databases;
+while($i)
+{
+  eval alter table test$i.benchmark add ts timestamp not null default current_timestamp;
+
+  dec $i;
+}
+--enable_result_log
+--enable_query_log
+
+
+# not gather events into relay log w/o executing yet
+stop slave sql_thread;
+
+##call p1(1);
+
+connection master;
+
+--disable_query_log
+--disable_result_log
+
+#
+# Load producer
+#
+
+# initial timestamp to record
+
+# the extra ts col on slave is effective only with the STMT format (todo: bug-report)
+set @save.binlog_format= @@session.binlog_format;
+set @@session.binlog_format=STATEMENT;
+let $i = $databases;
+while($i)
+{
+  eval insert into test$i.benchmark set state='slave takes on load';
+
+  dec $i;
+}
+set @@session.binlog_format= @save.binlog_format;
+
+connection slave;
+
+insert into test1.benchmark set state='master started load';
+
+
+connection master;
+
+while ($iter)
+{
+    let $i = $databases;
+
+    while ($i)
+    {
+
+	begin;
+   	   ###eval insert into tm_nk values($iter, $i1, repeat('a', round(rand()*10)));
+
+    	   let $q= $wk_queries;
+	   while ($q)
+	   {
+	       let $m= `select 1 + floor(rand() * $tables)`;
+	       eval insert into test$i.ti_wk_$m values(null,  $i, uuid());
+
+	       dec $q;
+	   }
+
+    	   let $q= $nk_queries;
+	   while ($q)
+	   {
+	       let $m= `select 1 + floor(rand() * $tables)`;
+	       eval insert into test$i.ti_nk_$m values(null,  $i, uuid());
+
+	       dec $q;
+	   }
+	commit;
+
+	dec $i;
+    }
+
+    dec $iter;
+}
+
+connection slave;
+
+##use test1;
+insert into test1.benchmark set state='master ends load';
+
+connection master;
+
+# terminal timestamp to record
+
+let $i = $databases;
+set @save.binlog_format= @@session.binlog_format;
+set @@session.binlog_format=STATEMENT;
+while($i)
+{
+  eval insert into test$i.benchmark set state='slave ends load';
+
+  dec $i;
+}
+set @@session.binlog_format= @save.binlog_format;
+
+--enable_result_log
+--enable_query_log
+
+connection slave;
+
+## todo: record start and end time of appying to compare times of
+#  parallel and sequential execution.
+
+--disable_query_log
+--disable_result_log
+
+insert into test1.benchmark set state='slave is processing load';
+
+# To force filling timestamp cols with the slave local clock values
+# to implement benchmarking.
+
+set @save.mts_exp_slave_local_timestamp=@@global.mts_exp_slave_local_timestamp;
+set @@global.mts_exp_slave_local_timestamp=1;
+
+--sleep 1
+
+start slave sql_thread;
+
+let $wait_timeout= 600;
+let $wait_condition= SELECT count(*)+sleep(1) = 5 FROM test1.benchmark;
+source include/wait_condition.inc;
+
+use test;
+select * from test1.benchmark into outfile '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';
+
+--enable_result_log
+--enable_query_log
+
+
+connection master;
+
+--disable_query_log
+--disable_result_log
+
+let $i = $databases;
+while($i)
+{
+  eval drop database test$i;
+
+  dec $i;
+}
+
+use test;
+drop procedure one_session;
+
+--enable_result_log
+--enable_query_log
+
+sync_slave_with_master;
+#connection slave;
+set @@global.mts_exp_slave_local_timestamp= @save.mts_exp_slave_local_timestamp;
+
+# End of the tests

=== modified file 'mysql-test/r/mysqld--help-notwin.result'
--- a/mysql-test/r/mysqld--help-notwin.result	2011-01-11 23:01:02 +0000
+++ b/mysql-test/r/mysqld--help-notwin.result	2011-02-27 17:35:25 +0000
@@ -362,9 +362,6 @@ The following options may be given as th
  If enabled slave itself computes the event appying time
  value to implicitly affected timestamp columms. Otherwise
  (default) it installs prescribed by the master value
- --mts-exp-slave-run-query-in-parallel 
- The default not an actual database name is used as
- partition info for parallel execution of Query_log_event 
  --mts-partition-hash-soft-max=# 
  Number of records in the mts partition hash below which
  entries with zero usage are tolerated
@@ -910,7 +907,6 @@ mts-checkpoint-group 512
 mts-checkpoint-period 300
 mts-coordinator-basic-nap 5
 mts-exp-slave-local-timestamp FALSE
-mts-exp-slave-run-query-in-parallel FALSE
 mts-partition-hash-soft-max 16
 mts-pending-jobs-size-max 16777216
 mts-slave-parallel-workers 0

=== modified file 'mysql-test/suite/rpl/r/rpl_packet.result'
--- a/mysql-test/suite/rpl/r/rpl_packet.result	2010-12-19 17:22:30 +0000
+++ b/mysql-test/suite/rpl/r/rpl_packet.result	2011-02-27 17:35:25 +0000
@@ -23,12 +23,12 @@ select * from information_schema.session
 VARIABLE_NAME	VARIABLE_VALUE
 SLAVE_RUNNING	ON
 drop database DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________;
-SET @@global.max_allowed_packet=4096;
-SET @@global.net_buffer_length=4096;
+SET @@global.max_allowed_packet=4096 + (floor(64 * 3 * 254 / 1024) + 1) * 1024;
+SET @@global.net_buffer_length=@@global.max_allowed_packet;
 include/stop_slave.inc
 include/start_slave.inc
 CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM;
-INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048');
+INSERT INTO t1 VALUES (REPEAT('a', @@global.max_allowed_packet));
 include/wait_for_slave_io_error.inc [errno=1153]
 Last_IO_Error = 'Got a packet bigger than 'max_allowed_packet' bytes'
 include/stop_slave_sql.inc
@@ -51,10 +51,10 @@ include/wait_for_slave_to_start.inc
 DROP TABLE t1;
 select @@global.max_allowed_packet;
 @@global.max_allowed_packet
-4096
+53248
 select @@global.net_buffer_length;
 @@global.net_buffer_length
-4096
+53248
 select @@global.max_allowed_packet;
 @@global.max_allowed_packet
 1024
@@ -62,7 +62,7 @@ select @@global.net_buffer_length;
 @@global.net_buffer_length
 1024
 CREATE TABLE t1 (a TEXT) ENGINE=MyISAM;
-INSERT INTO t1 VALUES (REPEAT('a', 2048));
+INSERT INTO t1 VALUES (REPEAT('a', @@global.max_allowed_packet));
 # 1153 = ER_NET_PACKET_TOO_LARGE
 include/wait_for_slave_io_error.inc [errno=1153]
 Last_IO_Error = 'Got a packet bigger than 'max_allowed_packet' bytes'

=== added file 'mysql-test/suite/rpl/r/rpl_parallel_benchmark.result'
--- a/mysql-test/suite/rpl/r/rpl_parallel_benchmark.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_parallel_benchmark.result	2011-04-02 11:32:02 +0000
@@ -0,0 +1,17 @@
+include/master-slave.inc
+[connection master]
+set @save.mts_slave_parallel_workers= @@global.mts_slave_parallel_workers;
+call mtr.add_suppression('Slave: Error dropping database');
+include/stop_slave.inc
+start slave;
+stop slave sql_thread;
+use test;
+select * from test1.benchmark into outfile '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';
+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_ddl.result'
--- a/mysql-test/suite/rpl/r/rpl_parallel_ddl.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_parallel_ddl.result	2011-02-27 17:35:25 +0000
@@ -0,0 +1,265 @@
+include/master-slave.inc
+[connection master]
+include/stop_slave.inc
+set @save.mts_slave_parallel_workers= @@global.mts_slave_parallel_workers;
+set @@global.mts_slave_parallel_workers= 4;
+include/start_slave.inc
+Warnings:
+Note	1726	Temporary failed transaction retry is not supported in Parallel Slave. Such failure will force the slave to stop.
+include/diff_tables.inc [master:d32.t8, slave:d32.t8]
+include/diff_tables.inc [master:d32.t7, slave:d32.t7]
+include/diff_tables.inc [master:d32.t6, slave:d32.t6]
+include/diff_tables.inc [master:d32.t5, slave:d32.t5]
+include/diff_tables.inc [master:d32.t4, slave:d32.t4]
+include/diff_tables.inc [master:d32.t3, slave:d32.t3]
+include/diff_tables.inc [master:d32.t2, slave:d32.t2]
+include/diff_tables.inc [master:d32.t1, slave:d32.t1]
+include/diff_tables.inc [master:d31.t8, slave:d31.t8]
+include/diff_tables.inc [master:d31.t7, slave:d31.t7]
+include/diff_tables.inc [master:d31.t6, slave:d31.t6]
+include/diff_tables.inc [master:d31.t5, slave:d31.t5]
+include/diff_tables.inc [master:d31.t4, slave:d31.t4]
+include/diff_tables.inc [master:d31.t3, slave:d31.t3]
+include/diff_tables.inc [master:d31.t2, slave:d31.t2]
+include/diff_tables.inc [master:d31.t1, slave:d31.t1]
+include/diff_tables.inc [master:d30.t8, slave:d30.t8]
+include/diff_tables.inc [master:d30.t7, slave:d30.t7]
+include/diff_tables.inc [master:d30.t6, slave:d30.t6]
+include/diff_tables.inc [master:d30.t5, slave:d30.t5]
+include/diff_tables.inc [master:d30.t4, slave:d30.t4]
+include/diff_tables.inc [master:d30.t3, slave:d30.t3]
+include/diff_tables.inc [master:d30.t2, slave:d30.t2]
+include/diff_tables.inc [master:d30.t1, slave:d30.t1]
+include/diff_tables.inc [master:d29.t8, slave:d29.t8]
+include/diff_tables.inc [master:d29.t7, slave:d29.t7]
+include/diff_tables.inc [master:d29.t6, slave:d29.t6]
+include/diff_tables.inc [master:d29.t5, slave:d29.t5]
+include/diff_tables.inc [master:d29.t4, slave:d29.t4]
+include/diff_tables.inc [master:d29.t3, slave:d29.t3]
+include/diff_tables.inc [master:d29.t2, slave:d29.t2]
+include/diff_tables.inc [master:d29.t1, slave:d29.t1]
+include/diff_tables.inc [master:d28.t8, slave:d28.t8]
+include/diff_tables.inc [master:d28.t7, slave:d28.t7]
+include/diff_tables.inc [master:d28.t6, slave:d28.t6]
+include/diff_tables.inc [master:d28.t5, slave:d28.t5]
+include/diff_tables.inc [master:d28.t4, slave:d28.t4]
+include/diff_tables.inc [master:d28.t3, slave:d28.t3]
+include/diff_tables.inc [master:d28.t2, slave:d28.t2]
+include/diff_tables.inc [master:d28.t1, slave:d28.t1]
+include/diff_tables.inc [master:d27.t8, slave:d27.t8]
+include/diff_tables.inc [master:d27.t7, slave:d27.t7]
+include/diff_tables.inc [master:d27.t6, slave:d27.t6]
+include/diff_tables.inc [master:d27.t5, slave:d27.t5]
+include/diff_tables.inc [master:d27.t4, slave:d27.t4]
+include/diff_tables.inc [master:d27.t3, slave:d27.t3]
+include/diff_tables.inc [master:d27.t2, slave:d27.t2]
+include/diff_tables.inc [master:d27.t1, slave:d27.t1]
+include/diff_tables.inc [master:d26.t8, slave:d26.t8]
+include/diff_tables.inc [master:d26.t7, slave:d26.t7]
+include/diff_tables.inc [master:d26.t6, slave:d26.t6]
+include/diff_tables.inc [master:d26.t5, slave:d26.t5]
+include/diff_tables.inc [master:d26.t4, slave:d26.t4]
+include/diff_tables.inc [master:d26.t3, slave:d26.t3]
+include/diff_tables.inc [master:d26.t2, slave:d26.t2]
+include/diff_tables.inc [master:d26.t1, slave:d26.t1]
+include/diff_tables.inc [master:d25.t8, slave:d25.t8]
+include/diff_tables.inc [master:d25.t7, slave:d25.t7]
+include/diff_tables.inc [master:d25.t6, slave:d25.t6]
+include/diff_tables.inc [master:d25.t5, slave:d25.t5]
+include/diff_tables.inc [master:d25.t4, slave:d25.t4]
+include/diff_tables.inc [master:d25.t3, slave:d25.t3]
+include/diff_tables.inc [master:d25.t2, slave:d25.t2]
+include/diff_tables.inc [master:d25.t1, slave:d25.t1]
+include/diff_tables.inc [master:d24.t8, slave:d24.t8]
+include/diff_tables.inc [master:d24.t7, slave:d24.t7]
+include/diff_tables.inc [master:d24.t6, slave:d24.t6]
+include/diff_tables.inc [master:d24.t5, slave:d24.t5]
+include/diff_tables.inc [master:d24.t4, slave:d24.t4]
+include/diff_tables.inc [master:d24.t3, slave:d24.t3]
+include/diff_tables.inc [master:d24.t2, slave:d24.t2]
+include/diff_tables.inc [master:d24.t1, slave:d24.t1]
+include/diff_tables.inc [master:d23.t8, slave:d23.t8]
+include/diff_tables.inc [master:d23.t7, slave:d23.t7]
+include/diff_tables.inc [master:d23.t6, slave:d23.t6]
+include/diff_tables.inc [master:d23.t5, slave:d23.t5]
+include/diff_tables.inc [master:d23.t4, slave:d23.t4]
+include/diff_tables.inc [master:d23.t3, slave:d23.t3]
+include/diff_tables.inc [master:d23.t2, slave:d23.t2]
+include/diff_tables.inc [master:d23.t1, slave:d23.t1]
+include/diff_tables.inc [master:d22.t8, slave:d22.t8]
+include/diff_tables.inc [master:d22.t7, slave:d22.t7]
+include/diff_tables.inc [master:d22.t6, slave:d22.t6]
+include/diff_tables.inc [master:d22.t5, slave:d22.t5]
+include/diff_tables.inc [master:d22.t4, slave:d22.t4]
+include/diff_tables.inc [master:d22.t3, slave:d22.t3]
+include/diff_tables.inc [master:d22.t2, slave:d22.t2]
+include/diff_tables.inc [master:d22.t1, slave:d22.t1]
+include/diff_tables.inc [master:d21.t8, slave:d21.t8]
+include/diff_tables.inc [master:d21.t7, slave:d21.t7]
+include/diff_tables.inc [master:d21.t6, slave:d21.t6]
+include/diff_tables.inc [master:d21.t5, slave:d21.t5]
+include/diff_tables.inc [master:d21.t4, slave:d21.t4]
+include/diff_tables.inc [master:d21.t3, slave:d21.t3]
+include/diff_tables.inc [master:d21.t2, slave:d21.t2]
+include/diff_tables.inc [master:d21.t1, slave:d21.t1]
+include/diff_tables.inc [master:d20.t8, slave:d20.t8]
+include/diff_tables.inc [master:d20.t7, slave:d20.t7]
+include/diff_tables.inc [master:d20.t6, slave:d20.t6]
+include/diff_tables.inc [master:d20.t5, slave:d20.t5]
+include/diff_tables.inc [master:d20.t4, slave:d20.t4]
+include/diff_tables.inc [master:d20.t3, slave:d20.t3]
+include/diff_tables.inc [master:d20.t2, slave:d20.t2]
+include/diff_tables.inc [master:d20.t1, slave:d20.t1]
+include/diff_tables.inc [master:d19.t8, slave:d19.t8]
+include/diff_tables.inc [master:d19.t7, slave:d19.t7]
+include/diff_tables.inc [master:d19.t6, slave:d19.t6]
+include/diff_tables.inc [master:d19.t5, slave:d19.t5]
+include/diff_tables.inc [master:d19.t4, slave:d19.t4]
+include/diff_tables.inc [master:d19.t3, slave:d19.t3]
+include/diff_tables.inc [master:d19.t2, slave:d19.t2]
+include/diff_tables.inc [master:d19.t1, slave:d19.t1]
+include/diff_tables.inc [master:d18.t8, slave:d18.t8]
+include/diff_tables.inc [master:d18.t7, slave:d18.t7]
+include/diff_tables.inc [master:d18.t6, slave:d18.t6]
+include/diff_tables.inc [master:d18.t5, slave:d18.t5]
+include/diff_tables.inc [master:d18.t4, slave:d18.t4]
+include/diff_tables.inc [master:d18.t3, slave:d18.t3]
+include/diff_tables.inc [master:d18.t2, slave:d18.t2]
+include/diff_tables.inc [master:d18.t1, slave:d18.t1]
+include/diff_tables.inc [master:d17.t8, slave:d17.t8]
+include/diff_tables.inc [master:d17.t7, slave:d17.t7]
+include/diff_tables.inc [master:d17.t6, slave:d17.t6]
+include/diff_tables.inc [master:d17.t5, slave:d17.t5]
+include/diff_tables.inc [master:d17.t4, slave:d17.t4]
+include/diff_tables.inc [master:d17.t3, slave:d17.t3]
+include/diff_tables.inc [master:d17.t2, slave:d17.t2]
+include/diff_tables.inc [master:d17.t1, slave:d17.t1]
+include/diff_tables.inc [master:d16.t8, slave:d16.t8]
+include/diff_tables.inc [master:d16.t7, slave:d16.t7]
+include/diff_tables.inc [master:d16.t6, slave:d16.t6]
+include/diff_tables.inc [master:d16.t5, slave:d16.t5]
+include/diff_tables.inc [master:d16.t4, slave:d16.t4]
+include/diff_tables.inc [master:d16.t3, slave:d16.t3]
+include/diff_tables.inc [master:d16.t2, slave:d16.t2]
+include/diff_tables.inc [master:d16.t1, slave:d16.t1]
+include/diff_tables.inc [master:d15.t8, slave:d15.t8]
+include/diff_tables.inc [master:d15.t7, slave:d15.t7]
+include/diff_tables.inc [master:d15.t6, slave:d15.t6]
+include/diff_tables.inc [master:d15.t5, slave:d15.t5]
+include/diff_tables.inc [master:d15.t4, slave:d15.t4]
+include/diff_tables.inc [master:d15.t3, slave:d15.t3]
+include/diff_tables.inc [master:d15.t2, slave:d15.t2]
+include/diff_tables.inc [master:d15.t1, slave:d15.t1]
+include/diff_tables.inc [master:d14.t8, slave:d14.t8]
+include/diff_tables.inc [master:d14.t7, slave:d14.t7]
+include/diff_tables.inc [master:d14.t6, slave:d14.t6]
+include/diff_tables.inc [master:d14.t5, slave:d14.t5]
+include/diff_tables.inc [master:d14.t4, slave:d14.t4]
+include/diff_tables.inc [master:d14.t3, slave:d14.t3]
+include/diff_tables.inc [master:d14.t2, slave:d14.t2]
+include/diff_tables.inc [master:d14.t1, slave:d14.t1]
+include/diff_tables.inc [master:d13.t8, slave:d13.t8]
+include/diff_tables.inc [master:d13.t7, slave:d13.t7]
+include/diff_tables.inc [master:d13.t6, slave:d13.t6]
+include/diff_tables.inc [master:d13.t5, slave:d13.t5]
+include/diff_tables.inc [master:d13.t4, slave:d13.t4]
+include/diff_tables.inc [master:d13.t3, slave:d13.t3]
+include/diff_tables.inc [master:d13.t2, slave:d13.t2]
+include/diff_tables.inc [master:d13.t1, slave:d13.t1]
+include/diff_tables.inc [master:d12.t8, slave:d12.t8]
+include/diff_tables.inc [master:d12.t7, slave:d12.t7]
+include/diff_tables.inc [master:d12.t6, slave:d12.t6]
+include/diff_tables.inc [master:d12.t5, slave:d12.t5]
+include/diff_tables.inc [master:d12.t4, slave:d12.t4]
+include/diff_tables.inc [master:d12.t3, slave:d12.t3]
+include/diff_tables.inc [master:d12.t2, slave:d12.t2]
+include/diff_tables.inc [master:d12.t1, slave:d12.t1]
+include/diff_tables.inc [master:d11.t8, slave:d11.t8]
+include/diff_tables.inc [master:d11.t7, slave:d11.t7]
+include/diff_tables.inc [master:d11.t6, slave:d11.t6]
+include/diff_tables.inc [master:d11.t5, slave:d11.t5]
+include/diff_tables.inc [master:d11.t4, slave:d11.t4]
+include/diff_tables.inc [master:d11.t3, slave:d11.t3]
+include/diff_tables.inc [master:d11.t2, slave:d11.t2]
+include/diff_tables.inc [master:d11.t1, slave:d11.t1]
+include/diff_tables.inc [master:d10.t8, slave:d10.t8]
+include/diff_tables.inc [master:d10.t7, slave:d10.t7]
+include/diff_tables.inc [master:d10.t6, slave:d10.t6]
+include/diff_tables.inc [master:d10.t5, slave:d10.t5]
+include/diff_tables.inc [master:d10.t4, slave:d10.t4]
+include/diff_tables.inc [master:d10.t3, slave:d10.t3]
+include/diff_tables.inc [master:d10.t2, slave:d10.t2]
+include/diff_tables.inc [master:d10.t1, slave:d10.t1]
+include/diff_tables.inc [master:d9.t8, slave:d9.t8]
+include/diff_tables.inc [master:d9.t7, slave:d9.t7]
+include/diff_tables.inc [master:d9.t6, slave:d9.t6]
+include/diff_tables.inc [master:d9.t5, slave:d9.t5]
+include/diff_tables.inc [master:d9.t4, slave:d9.t4]
+include/diff_tables.inc [master:d9.t3, slave:d9.t3]
+include/diff_tables.inc [master:d9.t2, slave:d9.t2]
+include/diff_tables.inc [master:d9.t1, slave:d9.t1]
+include/diff_tables.inc [master:d8.t8, slave:d8.t8]
+include/diff_tables.inc [master:d8.t7, slave:d8.t7]
+include/diff_tables.inc [master:d8.t6, slave:d8.t6]
+include/diff_tables.inc [master:d8.t5, slave:d8.t5]
+include/diff_tables.inc [master:d8.t4, slave:d8.t4]
+include/diff_tables.inc [master:d8.t3, slave:d8.t3]
+include/diff_tables.inc [master:d8.t2, slave:d8.t2]
+include/diff_tables.inc [master:d8.t1, slave:d8.t1]
+include/diff_tables.inc [master:d7.t8, slave:d7.t8]
+include/diff_tables.inc [master:d7.t7, slave:d7.t7]
+include/diff_tables.inc [master:d7.t6, slave:d7.t6]
+include/diff_tables.inc [master:d7.t5, slave:d7.t5]
+include/diff_tables.inc [master:d7.t4, slave:d7.t4]
+include/diff_tables.inc [master:d7.t3, slave:d7.t3]
+include/diff_tables.inc [master:d7.t2, slave:d7.t2]
+include/diff_tables.inc [master:d7.t1, slave:d7.t1]
+include/diff_tables.inc [master:d6.t8, slave:d6.t8]
+include/diff_tables.inc [master:d6.t7, slave:d6.t7]
+include/diff_tables.inc [master:d6.t6, slave:d6.t6]
+include/diff_tables.inc [master:d6.t5, slave:d6.t5]
+include/diff_tables.inc [master:d6.t4, slave:d6.t4]
+include/diff_tables.inc [master:d6.t3, slave:d6.t3]
+include/diff_tables.inc [master:d6.t2, slave:d6.t2]
+include/diff_tables.inc [master:d6.t1, slave:d6.t1]
+include/diff_tables.inc [master:d5.t8, slave:d5.t8]
+include/diff_tables.inc [master:d5.t7, slave:d5.t7]
+include/diff_tables.inc [master:d5.t6, slave:d5.t6]
+include/diff_tables.inc [master:d5.t5, slave:d5.t5]
+include/diff_tables.inc [master:d5.t4, slave:d5.t4]
+include/diff_tables.inc [master:d5.t3, slave:d5.t3]
+include/diff_tables.inc [master:d5.t2, slave:d5.t2]
+include/diff_tables.inc [master:d5.t1, slave:d5.t1]
+include/diff_tables.inc [master:d4.t8, slave:d4.t8]
+include/diff_tables.inc [master:d4.t7, slave:d4.t7]
+include/diff_tables.inc [master:d4.t6, slave:d4.t6]
+include/diff_tables.inc [master:d4.t5, slave:d4.t5]
+include/diff_tables.inc [master:d4.t4, slave:d4.t4]
+include/diff_tables.inc [master:d4.t3, slave:d4.t3]
+include/diff_tables.inc [master:d4.t2, slave:d4.t2]
+include/diff_tables.inc [master:d4.t1, slave:d4.t1]
+include/diff_tables.inc [master:d3.t8, slave:d3.t8]
+include/diff_tables.inc [master:d3.t7, slave:d3.t7]
+include/diff_tables.inc [master:d3.t6, slave:d3.t6]
+include/diff_tables.inc [master:d3.t5, slave:d3.t5]
+include/diff_tables.inc [master:d3.t4, slave:d3.t4]
+include/diff_tables.inc [master:d3.t3, slave:d3.t3]
+include/diff_tables.inc [master:d3.t2, slave:d3.t2]
+include/diff_tables.inc [master:d3.t1, slave:d3.t1]
+include/diff_tables.inc [master:d2.t8, slave:d2.t8]
+include/diff_tables.inc [master:d2.t7, slave:d2.t7]
+include/diff_tables.inc [master:d2.t6, slave:d2.t6]
+include/diff_tables.inc [master:d2.t5, slave:d2.t5]
+include/diff_tables.inc [master:d2.t4, slave:d2.t4]
+include/diff_tables.inc [master:d2.t3, slave:d2.t3]
+include/diff_tables.inc [master:d2.t2, slave:d2.t2]
+include/diff_tables.inc [master:d2.t1, slave:d2.t1]
+include/diff_tables.inc [master:d1.t8, slave:d1.t8]
+include/diff_tables.inc [master:d1.t7, slave:d1.t7]
+include/diff_tables.inc [master:d1.t6, slave:d1.t6]
+include/diff_tables.inc [master:d1.t5, slave:d1.t5]
+include/diff_tables.inc [master:d1.t4, slave:d1.t4]
+include/diff_tables.inc [master:d1.t3, slave:d1.t3]
+include/diff_tables.inc [master:d1.t2, slave:d1.t2]
+include/diff_tables.inc [master:d1.t1, slave:d1.t1]
+set @@global.mts_slave_parallel_workers= @save.mts_slave_parallel_workers;

=== added file 'mysql-test/suite/rpl/r/rpl_parallel_multi_db.result'
--- a/mysql-test/suite/rpl/r/rpl_parallel_multi_db.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_parallel_multi_db.result	2011-02-27 17:35:25 +0000
@@ -0,0 +1,373 @@
+include/master-slave.inc
+[connection master]
+include/stop_slave.inc
+set @save.mts_slave_parallel_workers= @@global.mts_slave_parallel_workers;
+set @@global.mts_slave_parallel_workers= 4;
+include/start_slave.inc
+Warnings:
+Note	1726	Temporary failed transaction retry is not supported in Parallel Slave. Such failure will force the slave to stop.
+create database d8;
+create table d8.t8 (a int);
+select round(rand()*8) into @var;
+insert into d8.t8 values (@var);
+create table d8.t7 (a int);
+select round(rand()*8) into @var;
+insert into d8.t7 values (@var);
+create table d8.t6 (a int);
+select round(rand()*8) into @var;
+insert into d8.t6 values (@var);
+create table d8.t5 (a int);
+select round(rand()*8) into @var;
+insert into d8.t5 values (@var);
+create table d8.t4 (a int);
+select round(rand()*8) into @var;
+insert into d8.t4 values (@var);
+create table d8.t3 (a int);
+select round(rand()*8) into @var;
+insert into d8.t3 values (@var);
+create table d8.t2 (a int);
+select round(rand()*8) into @var;
+insert into d8.t2 values (@var);
+create table d8.t1 (a int);
+select round(rand()*8) into @var;
+insert into d8.t1 values (@var);
+create database d7;
+create table d7.t8 (a int);
+select round(rand()*8) into @var;
+insert into d7.t8 values (@var);
+create table d7.t7 (a int);
+select round(rand()*8) into @var;
+insert into d7.t7 values (@var);
+create table d7.t6 (a int);
+select round(rand()*8) into @var;
+insert into d7.t6 values (@var);
+create table d7.t5 (a int);
+select round(rand()*8) into @var;
+insert into d7.t5 values (@var);
+create table d7.t4 (a int);
+select round(rand()*8) into @var;
+insert into d7.t4 values (@var);
+create table d7.t3 (a int);
+select round(rand()*8) into @var;
+insert into d7.t3 values (@var);
+create table d7.t2 (a int);
+select round(rand()*8) into @var;
+insert into d7.t2 values (@var);
+create table d7.t1 (a int);
+select round(rand()*8) into @var;
+insert into d7.t1 values (@var);
+create database d6;
+create table d6.t8 (a int);
+select round(rand()*8) into @var;
+insert into d6.t8 values (@var);
+create table d6.t7 (a int);
+select round(rand()*8) into @var;
+insert into d6.t7 values (@var);
+create table d6.t6 (a int);
+select round(rand()*8) into @var;
+insert into d6.t6 values (@var);
+create table d6.t5 (a int);
+select round(rand()*8) into @var;
+insert into d6.t5 values (@var);
+create table d6.t4 (a int);
+select round(rand()*8) into @var;
+insert into d6.t4 values (@var);
+create table d6.t3 (a int);
+select round(rand()*8) into @var;
+insert into d6.t3 values (@var);
+create table d6.t2 (a int);
+select round(rand()*8) into @var;
+insert into d6.t2 values (@var);
+create table d6.t1 (a int);
+select round(rand()*8) into @var;
+insert into d6.t1 values (@var);
+create database d5;
+create table d5.t8 (a int);
+select round(rand()*8) into @var;
+insert into d5.t8 values (@var);
+create table d5.t7 (a int);
+select round(rand()*8) into @var;
+insert into d5.t7 values (@var);
+create table d5.t6 (a int);
+select round(rand()*8) into @var;
+insert into d5.t6 values (@var);
+create table d5.t5 (a int);
+select round(rand()*8) into @var;
+insert into d5.t5 values (@var);
+create table d5.t4 (a int);
+select round(rand()*8) into @var;
+insert into d5.t4 values (@var);
+create table d5.t3 (a int);
+select round(rand()*8) into @var;
+insert into d5.t3 values (@var);
+create table d5.t2 (a int);
+select round(rand()*8) into @var;
+insert into d5.t2 values (@var);
+create table d5.t1 (a int);
+select round(rand()*8) into @var;
+insert into d5.t1 values (@var);
+create database d4;
+create table d4.t8 (a int);
+select round(rand()*8) into @var;
+insert into d4.t8 values (@var);
+create table d4.t7 (a int);
+select round(rand()*8) into @var;
+insert into d4.t7 values (@var);
+create table d4.t6 (a int);
+select round(rand()*8) into @var;
+insert into d4.t6 values (@var);
+create table d4.t5 (a int);
+select round(rand()*8) into @var;
+insert into d4.t5 values (@var);
+create table d4.t4 (a int);
+select round(rand()*8) into @var;
+insert into d4.t4 values (@var);
+create table d4.t3 (a int);
+select round(rand()*8) into @var;
+insert into d4.t3 values (@var);
+create table d4.t2 (a int);
+select round(rand()*8) into @var;
+insert into d4.t2 values (@var);
+create table d4.t1 (a int);
+select round(rand()*8) into @var;
+insert into d4.t1 values (@var);
+create database d3;
+create table d3.t8 (a int);
+select round(rand()*8) into @var;
+insert into d3.t8 values (@var);
+create table d3.t7 (a int);
+select round(rand()*8) into @var;
+insert into d3.t7 values (@var);
+create table d3.t6 (a int);
+select round(rand()*8) into @var;
+insert into d3.t6 values (@var);
+create table d3.t5 (a int);
+select round(rand()*8) into @var;
+insert into d3.t5 values (@var);
+create table d3.t4 (a int);
+select round(rand()*8) into @var;
+insert into d3.t4 values (@var);
+create table d3.t3 (a int);
+select round(rand()*8) into @var;
+insert into d3.t3 values (@var);
+create table d3.t2 (a int);
+select round(rand()*8) into @var;
+insert into d3.t2 values (@var);
+create table d3.t1 (a int);
+select round(rand()*8) into @var;
+insert into d3.t1 values (@var);
+create database d2;
+create table d2.t8 (a int);
+select round(rand()*8) into @var;
+insert into d2.t8 values (@var);
+create table d2.t7 (a int);
+select round(rand()*8) into @var;
+insert into d2.t7 values (@var);
+create table d2.t6 (a int);
+select round(rand()*8) into @var;
+insert into d2.t6 values (@var);
+create table d2.t5 (a int);
+select round(rand()*8) into @var;
+insert into d2.t5 values (@var);
+create table d2.t4 (a int);
+select round(rand()*8) into @var;
+insert into d2.t4 values (@var);
+create table d2.t3 (a int);
+select round(rand()*8) into @var;
+insert into d2.t3 values (@var);
+create table d2.t2 (a int);
+select round(rand()*8) into @var;
+insert into d2.t2 values (@var);
+create table d2.t1 (a int);
+select round(rand()*8) into @var;
+insert into d2.t1 values (@var);
+create database d1;
+create table d1.t8 (a int);
+select round(rand()*8) into @var;
+insert into d1.t8 values (@var);
+create table d1.t7 (a int);
+select round(rand()*8) into @var;
+insert into d1.t7 values (@var);
+create table d1.t6 (a int);
+select round(rand()*8) into @var;
+insert into d1.t6 values (@var);
+create table d1.t5 (a int);
+select round(rand()*8) into @var;
+insert into d1.t5 values (@var);
+create table d1.t4 (a int);
+select round(rand()*8) into @var;
+insert into d1.t4 values (@var);
+create table d1.t3 (a int);
+select round(rand()*8) into @var;
+insert into d1.t3 values (@var);
+create table d1.t2 (a int);
+select round(rand()*8) into @var;
+insert into d1.t2 values (@var);
+create table d1.t1 (a int);
+select round(rand()*8) into @var;
+insert into d1.t1 values (@var);
+include/diff_tables.inc [master:d8.t8, slave:d8.t8]
+include/diff_tables.inc [master:d8.t7, slave:d8.t7]
+include/diff_tables.inc [master:d8.t6, slave:d8.t6]
+include/diff_tables.inc [master:d8.t5, slave:d8.t5]
+include/diff_tables.inc [master:d8.t4, slave:d8.t4]
+include/diff_tables.inc [master:d8.t3, slave:d8.t3]
+include/diff_tables.inc [master:d8.t2, slave:d8.t2]
+include/diff_tables.inc [master:d8.t1, slave:d8.t1]
+include/diff_tables.inc [master:d7.t8, slave:d7.t8]
+include/diff_tables.inc [master:d7.t7, slave:d7.t7]
+include/diff_tables.inc [master:d7.t6, slave:d7.t6]
+include/diff_tables.inc [master:d7.t5, slave:d7.t5]
+include/diff_tables.inc [master:d7.t4, slave:d7.t4]
+include/diff_tables.inc [master:d7.t3, slave:d7.t3]
+include/diff_tables.inc [master:d7.t2, slave:d7.t2]
+include/diff_tables.inc [master:d7.t1, slave:d7.t1]
+include/diff_tables.inc [master:d6.t8, slave:d6.t8]
+include/diff_tables.inc [master:d6.t7, slave:d6.t7]
+include/diff_tables.inc [master:d6.t6, slave:d6.t6]
+include/diff_tables.inc [master:d6.t5, slave:d6.t5]
+include/diff_tables.inc [master:d6.t4, slave:d6.t4]
+include/diff_tables.inc [master:d6.t3, slave:d6.t3]
+include/diff_tables.inc [master:d6.t2, slave:d6.t2]
+include/diff_tables.inc [master:d6.t1, slave:d6.t1]
+include/diff_tables.inc [master:d5.t8, slave:d5.t8]
+include/diff_tables.inc [master:d5.t7, slave:d5.t7]
+include/diff_tables.inc [master:d5.t6, slave:d5.t6]
+include/diff_tables.inc [master:d5.t5, slave:d5.t5]
+include/diff_tables.inc [master:d5.t4, slave:d5.t4]
+include/diff_tables.inc [master:d5.t3, slave:d5.t3]
+include/diff_tables.inc [master:d5.t2, slave:d5.t2]
+include/diff_tables.inc [master:d5.t1, slave:d5.t1]
+include/diff_tables.inc [master:d4.t8, slave:d4.t8]
+include/diff_tables.inc [master:d4.t7, slave:d4.t7]
+include/diff_tables.inc [master:d4.t6, slave:d4.t6]
+include/diff_tables.inc [master:d4.t5, slave:d4.t5]
+include/diff_tables.inc [master:d4.t4, slave:d4.t4]
+include/diff_tables.inc [master:d4.t3, slave:d4.t3]
+include/diff_tables.inc [master:d4.t2, slave:d4.t2]
+include/diff_tables.inc [master:d4.t1, slave:d4.t1]
+include/diff_tables.inc [master:d3.t8, slave:d3.t8]
+include/diff_tables.inc [master:d3.t7, slave:d3.t7]
+include/diff_tables.inc [master:d3.t6, slave:d3.t6]
+include/diff_tables.inc [master:d3.t5, slave:d3.t5]
+include/diff_tables.inc [master:d3.t4, slave:d3.t4]
+include/diff_tables.inc [master:d3.t3, slave:d3.t3]
+include/diff_tables.inc [master:d3.t2, slave:d3.t2]
+include/diff_tables.inc [master:d3.t1, slave:d3.t1]
+include/diff_tables.inc [master:d2.t8, slave:d2.t8]
+include/diff_tables.inc [master:d2.t7, slave:d2.t7]
+include/diff_tables.inc [master:d2.t6, slave:d2.t6]
+include/diff_tables.inc [master:d2.t5, slave:d2.t5]
+include/diff_tables.inc [master:d2.t4, slave:d2.t4]
+include/diff_tables.inc [master:d2.t3, slave:d2.t3]
+include/diff_tables.inc [master:d2.t2, slave:d2.t2]
+include/diff_tables.inc [master:d2.t1, slave:d2.t1]
+include/diff_tables.inc [master:d1.t8, slave:d1.t8]
+include/diff_tables.inc [master:d1.t7, slave:d1.t7]
+include/diff_tables.inc [master:d1.t6, slave:d1.t6]
+include/diff_tables.inc [master:d1.t5, slave:d1.t5]
+include/diff_tables.inc [master:d1.t4, slave:d1.t4]
+include/diff_tables.inc [master:d1.t3, slave:d1.t3]
+include/diff_tables.inc [master:d1.t2, slave:d1.t2]
+include/diff_tables.inc [master:d1.t1, slave:d1.t1]
+create database d20;
+create table d20.t1 (a int);
+select round(rand()*8) into @var;
+insert into d20.t1 values (@var);
+create database d19;
+create table d19.t1 (a int);
+select round(rand()*8) into @var;
+insert into d19.t1 values (@var);
+create database d18;
+create table d18.t1 (a int);
+select round(rand()*8) into @var;
+insert into d18.t1 values (@var);
+create database d17;
+create table d17.t1 (a int);
+select round(rand()*8) into @var;
+insert into d17.t1 values (@var);
+create database d16;
+create table d16.t1 (a int);
+select round(rand()*8) into @var;
+insert into d16.t1 values (@var);
+create database d15;
+create table d15.t1 (a int);
+select round(rand()*8) into @var;
+insert into d15.t1 values (@var);
+create database d14;
+create table d14.t1 (a int);
+select round(rand()*8) into @var;
+insert into d14.t1 values (@var);
+create database d13;
+create table d13.t1 (a int);
+select round(rand()*8) into @var;
+insert into d13.t1 values (@var);
+create database d12;
+create table d12.t1 (a int);
+select round(rand()*8) into @var;
+insert into d12.t1 values (@var);
+create database d11;
+create table d11.t1 (a int);
+select round(rand()*8) into @var;
+insert into d11.t1 values (@var);
+create database d10;
+create table d10.t1 (a int);
+select round(rand()*8) into @var;
+insert into d10.t1 values (@var);
+create database d9;
+create table d9.t1 (a int);
+select round(rand()*8) into @var;
+insert into d9.t1 values (@var);
+create database d8;
+create table d8.t1 (a int);
+select round(rand()*8) into @var;
+insert into d8.t1 values (@var);
+create database d7;
+create table d7.t1 (a int);
+select round(rand()*8) into @var;
+insert into d7.t1 values (@var);
+create database d6;
+create table d6.t1 (a int);
+select round(rand()*8) into @var;
+insert into d6.t1 values (@var);
+create database d5;
+create table d5.t1 (a int);
+select round(rand()*8) into @var;
+insert into d5.t1 values (@var);
+create database d4;
+create table d4.t1 (a int);
+select round(rand()*8) into @var;
+insert into d4.t1 values (@var);
+create database d3;
+create table d3.t1 (a int);
+select round(rand()*8) into @var;
+insert into d3.t1 values (@var);
+create database d2;
+create table d2.t1 (a int);
+select round(rand()*8) into @var;
+insert into d2.t1 values (@var);
+create database d1;
+create table d1.t1 (a int);
+select round(rand()*8) into @var;
+insert into d1.t1 values (@var);
+include/diff_tables.inc [master:d20.t1, slave:d20.t1]
+include/diff_tables.inc [master:d19.t1, slave:d19.t1]
+include/diff_tables.inc [master:d18.t1, slave:d18.t1]
+include/diff_tables.inc [master:d17.t1, slave:d17.t1]
+include/diff_tables.inc [master:d16.t1, slave:d16.t1]
+include/diff_tables.inc [master:d15.t1, slave:d15.t1]
+include/diff_tables.inc [master:d14.t1, slave:d14.t1]
+include/diff_tables.inc [master:d13.t1, slave:d13.t1]
+include/diff_tables.inc [master:d12.t1, slave:d12.t1]
+include/diff_tables.inc [master:d11.t1, slave:d11.t1]
+include/diff_tables.inc [master:d10.t1, slave:d10.t1]
+include/diff_tables.inc [master:d9.t1, slave:d9.t1]
+include/diff_tables.inc [master:d8.t1, slave:d8.t1]
+include/diff_tables.inc [master:d7.t1, slave:d7.t1]
+include/diff_tables.inc [master:d6.t1, slave:d6.t1]
+include/diff_tables.inc [master:d5.t1, slave:d5.t1]
+include/diff_tables.inc [master:d4.t1, slave:d4.t1]
+include/diff_tables.inc [master:d3.t1, slave:d3.t1]
+include/diff_tables.inc [master:d2.t1, slave:d2.t1]
+include/diff_tables.inc [master:d1.t1, slave:d1.t1]
+set @@global.mts_slave_parallel_workers= @save.mts_slave_parallel_workers;

=== modified file 'mysql-test/suite/rpl/r/rpl_parallel_start_stop.result'
--- a/mysql-test/suite/rpl/r/rpl_parallel_start_stop.result	2010-12-27 18:54:41 +0000
+++ b/mysql-test/suite/rpl/r/rpl_parallel_start_stop.result	2011-02-27 17:35:25 +0000
@@ -60,7 +60,7 @@ Note	1726	Temporary failed transaction r
 include/stop_slave.inc
 create table t2 (a int);
 insert into t2 values (1);
-start slave until master_log_file='master-bin.000001', master_log_pos=2311;
+start slave until master_log_file='master-bin.000001', master_log_pos=MASTER_LOG_POS;
 Warnings:
 Note	1726	UNTIL condtion is not supported in Parallel Slave. Slave is started in the sequential execution mode.
 include/wait_for_slave_sql_to_stop.inc

=== added file 'mysql-test/suite/rpl/r/rpl_parallel_temp_query.result'
--- a/mysql-test/suite/rpl/r/rpl_parallel_temp_query.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_parallel_temp_query.result	2011-02-27 17:35:25 +0000
@@ -0,0 +1,51 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement accesses nontransactional table as well as transactional or temporary table.*');
+include/stop_slave.inc
+set @save.mts_slave_parallel_workers= @@global.mts_slave_parallel_workers;
+set @@global.mts_slave_parallel_workers= 4;
+include/start_slave.inc
+Warnings:
+Note	1726	Temporary failed transaction retry is not supported in Parallel Slave. Such failure will force the slave to stop.
+create database d2;
+use d2;
+create table d2.t1 (a int auto_increment primary key, b int) engine=innodb;
+insert into d2.t1 (b) select count(*) from tt_##;
+create database d1;
+use d1;
+create table d1.t1 (a int auto_increment primary key, b int) engine=innodb;
+insert into d1.t1 (b) select count(*) from tt_##;
+create database d4;
+use d4;
+create table d4.t1 (a int auto_increment primary key, b int) engine=innodb;
+insert into d4.t1 (b) select count(*) from tt_##;
+create database d3;
+use d3;
+create table d3.t1 (a int auto_increment primary key, b int) engine=innodb;
+insert into d3.t1 (b) select count(*) from tt_##;
+include/diff_tables.inc [master:d4.t1, slave:d4.t1]
+include/diff_tables.inc [master:d3.t1, slave:d3.t1]
+include/diff_tables.inc [master:d2.t1, slave:d2.t1]
+include/diff_tables.inc [master:d1.t1, slave:d1.t1]
+drop temporary table tt_8;
+drop temporary table tt_7;
+drop temporary table tt_6;
+drop temporary table tt_5;
+drop temporary table tt_4;
+drop temporary table tt_3;
+drop temporary table tt_2;
+drop temporary table tt_1;
+drop database d2;
+drop database d1;
+drop temporary table tt_8;
+drop temporary table tt_7;
+drop temporary table tt_6;
+drop temporary table tt_5;
+drop temporary table tt_4;
+drop temporary table tt_3;
+drop temporary table tt_2;
+drop temporary table tt_1;
+drop database d4;
+drop database d3;
+include/stop_slave.inc
+set @@global.mts_slave_parallel_workers= @save.mts_slave_parallel_workers;

=== modified file 'mysql-test/suite/rpl/t/rpl_packet.test'
--- a/mysql-test/suite/rpl/t/rpl_packet.test	2010-12-19 17:22:30 +0000
+++ b/mysql-test/suite/rpl/t/rpl_packet.test	2011-02-27 17:35:25 +0000
@@ -63,8 +63,20 @@ connection master;
 
 # Change the max packet size on master
 
-SET @@global.max_allowed_packet=4096;
-SET @@global.net_buffer_length=4096;
+# Todo: improve over-max_allowed_packet size events block on the slave.
+# The current size checking algorithm is not presize to allow large event
+# to slip it. Reject happens according to the guard:
+#   if (data_len > max(max_allowed_packet,
+#       opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER))
+# However, MAX_LOG_EVENT_HEADER is a conservative estimate so if the actual
+# header size is less the extra data let in the slave.
+
+# Adding the max size of the query log event status as
+# MAX_DBS_IN_QUERY_MTS * (1 + NAME_LEN) to make the master not fail to read
+# an event itself.
+
+SET @@global.max_allowed_packet=4096 + (floor(64 * 3 * 254 / 1024) + 1) * 1024;
+SET @@global.net_buffer_length=@@global.max_allowed_packet;
 
 # Restart slave for new setting to take effect
 connection slave;
@@ -82,7 +94,7 @@ sync_slave_with_master;
 
 connection master;
 
-INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048');
+INSERT INTO t1 VALUES (REPEAT('a', @@global.max_allowed_packet));
 
 
 #
@@ -169,6 +181,7 @@ if (`SELECT NOT(@max_allowed_packet_0 = 
 #
 
 connection slave;
+
 START SLAVE;
 --source include/wait_for_slave_to_start.inc
 
@@ -186,7 +199,7 @@ CREATE TABLE t1 (a TEXT) ENGINE=MyISAM;
 
 # Create big row event.
 --connection master
-INSERT INTO t1 VALUES (REPEAT('a', 2048));
+INSERT INTO t1 VALUES (REPEAT('a', @@global.max_allowed_packet));
 
 # Slave IO thread should stop with error when trying to read the big event.
 --connection slave

=== added file 'mysql-test/suite/rpl/t/rpl_parallel_benchmark-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_parallel_benchmark-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_benchmark-master.opt	2011-04-02 11:32:02 +0000
@@ -0,0 +1 @@
+--log-warnings=0

=== added file 'mysql-test/suite/rpl/t/rpl_parallel_benchmark-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_parallel_benchmark-slave.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_benchmark-slave.opt	2011-04-02 11:32:02 +0000
@@ -0,0 +1,3 @@
+--skip-log-bin --skip-log-slave-updates --log-warnings=0 --slave-transaction-retries=0
+
+

=== added file 'mysql-test/suite/rpl/t/rpl_parallel_benchmark.test'
--- a/mysql-test/suite/rpl/t/rpl_parallel_benchmark.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_benchmark.test	2011-04-02 11:32:02 +0000
@@ -0,0 +1,57 @@
+#
+# WL#5563 Prototype for Parallel Slave with db name partitioning.
+#
+# The test checks correctness of replication and is designed for 
+# benchmarking and comparision with results of its sequential
+# counterpart rpl_sequential.test.
+# Both tests leave mysqld.2/data/test/delta.out file
+# that contains a row with two columns.
+#  1. the duration (in seconds) of execution on the master
+#  2. the duration of execution on the slave
+#  The 2nd column of the rpl_parallel can be compared with the 2nd of rpl_sequential.test.
+#
+#  The duration recorded in the file accounts the SQL thread/workers work.
+#  That is benchmarking on the slave side is effectively started with
+#  `start slave sql_thread'.
+#  NOTICE, there is set @@global.slave_local_timestamp=1;
+#  
+#
+# of load that rpl_parallel_load.test represents.
+# See there how to tune load and concurrency parameters.
+#
+# Example of usage.
+# To gather a collection of figures:
+#  mysql-test$ export slave;
+#  mysql-test$ slave=parallel; for n in `seq 1 10`; 
+#  do ./mtr  --vardir=/dev/shm/var1 --mtr-build-thread=765 rpl_$slave 
+#             --mysqld=--binlog-format=statement; 
+#     find /dev/shm/var1 -name delta.out -exec cat {} \; | cat >> delta.$slave.log; 
+#  done
+#
+# mysql-test$ slave=sequential; ...
+#
+# In the end there will be mysql-test/delta.{parallel,sequential}.log files.
+#
+
+let $rpl_skip_reset_master_and_slave= 1;
+
+--source include/master-slave.inc
+
+connection slave;
+set @save.mts_slave_parallel_workers= @@global.mts_slave_parallel_workers;
+###select @@global.mts_slave_parallel_workers as 'non-zero means parallel';
+
+let $workers = `select @@global.mts_slave_parallel_workers`;
+###let $databases= $workers;
+# workers vary db:s do not
+let $databases= 16;
+
+connection master;
+source extra/rpl_tests/rpl_parallel_benchmark_load.test;
+
+connection slave;
+--disable_query_log
+set @@global.mts_slave_parallel_workers= @save.mts_slave_parallel_workers;
+--enable_result_log
+
+--source include/rpl_end.inc

=== added file 'mysql-test/suite/rpl/t/rpl_parallel_ddl.test'
--- a/mysql-test/suite/rpl/t/rpl_parallel_ddl.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_ddl.test	2011-02-27 17:35:25 +0000
@@ -0,0 +1,256 @@
+#
+# WL#5569 MTS
+#
+# The test verifies correctness of DDL Query event parallelization
+#
+
+
+--source include/master-slave.inc
+--source include/have_binlog_format_statement.inc
+
+
+# restart in Parallel
+
+let $workers= 4;
+
+connection slave;
+
+source include/stop_slave.inc;
+set @save.mts_slave_parallel_workers= @@global.mts_slave_parallel_workers;
+eval set @@global.mts_slave_parallel_workers= $workers;
+
+# Note, the number of db:s should be greater than MAX_DBS_IN_QUERY_MTS
+# in order to satisfy to the over-max final test.
+let $dbs= 32;
+let $tables= 8;
+let $queries= `select $dbs*$tables * 8`;
+
+#
+# D1. CREATE/DROP database
+#
+#
+# D2. CREATE/DROP/ALTER/RENAME table
+#
+
+--disable_query_log
+
+let $n= $dbs;
+while ($n)
+{
+  connection master;
+  eval create database d$n;
+
+  let $m= $tables;
+  while ($m)
+  {
+     eval create table d$n.t$m (a int);
+     eval select round(rand()*$tables) into @var;
+     eval insert into d$n.t$m values (@var);
+
+     dec $m;
+  }
+  dec $n;
+
+  connection master1;
+  eval create database d$n;
+
+  let $m= $tables;
+  while ($m)
+  {
+     eval create table d$n.t$m (a int);
+     eval select round(rand()*$tables) into @var;
+     eval insert into d$n.t$m values (@var);
+
+     dec $m;
+  }
+  dec $n;
+}
+
+
+let $k= $queries;
+
+while ($k)
+{
+   let $n_1 = `select floor(rand()*$dbs) + 1`;
+   let $n_2 = `select floor(rand()*$dbs) + 1`;
+   let $n1_1= `select floor(rand()*$dbs) + 1`;
+   let $n1_2= `select floor(rand()*$dbs) + 1`;
+   let $m= `select floor(rand()*$tables) + 1`;
+
+   --error 0,ER_TABLE_EXISTS_ERROR
+   eval rename table d$n_1.t$m to d$n1_1.t$m, d$n_2.t$m to d$n1_2.t$m;
+   --error 0,ER_TABLE_EXISTS_ERROR
+   eval rename table d$n1_1.t$m to d$n_1.t$m,  d$n1_2.t$m to d$n_2.t$m;
+
+   dec $k;
+}
+
+--enable_query_log
+
+#
+# D3. CREATE/DROP Stored Proc, Stored Func, Trigger, Func
+
+connection master;
+
+let $n= $dbs;
+# n'th db tables won't have any trigger to avoid circular dependency
+let $n1= $n;
+dec $n1;
+
+--disable_query_log
+
+while ($n1)
+{
+  let $m= $tables;
+
+  while ($m)
+  {
+     eval create trigger `d$n1`.`trg_t$m` before insert on `d$n1`.`t$m` for each row insert into `d$n`.`t$m` values(1);
+
+     delimiter |;
+
+     eval create function `d$n`.`func_$m` (a int) returns int
+          begin
+	  insert into `d$n`.`t$m` values(1);
+	  return 1;
+	  end|
+
+     eval create procedure `d$n`.`proc_$m`(a int)
+          begin
+	  insert into `d$n`.`t$m` values(1);
+	  end|
+	  
+     delimiter ;|
+
+     dec $m;
+  }
+  dec $n;
+  dec $n1;
+}
+
+#
+# D3. CREATE/ALTER/DROP event
+#
+
+CREATE EVENT d1.e_1 on schedule every '50:20:12:45' day_second do select 1;
+ALTER EVENT d1.e_1 RENAME to d2.e_2;
+DROP EVENT d2.e_2;
+
+#
+# D4. CREATE/DROP view
+#
+
+CREATE VIEW d1.v_1 AS SELECT 1;
+CREATE VIEW d2.v_2 AS SELECT 1;
+DROP VIEW d1.v_1, d2.v_2;
+
+--enable_query_log
+
+
+#
+# Run it on slave;
+#
+
+connection slave;
+source include/start_slave.inc;
+
+connection master;
+sync_slave_with_master;
+
+#
+# Consistency check
+#
+
+let $n = $dbs;
+while($n)
+{
+  let $m= $tables;
+  while ($m)
+  {
+    let $diff_tables=master:d$n.t$m, slave:d$n.t$m;
+    source include/diff_tables.inc;
+    dec $m;
+  }
+  dec $n;
+}
+
+#
+# Finally, over-the-max-limit updated db:s
+#
+
+connection master;
+
+# Prepare the test with dropping the triggers
+
+let $n= $dbs;
+# n'th db tables won't have any trigger to avoid circular dependency
+let $n1= $n;
+dec $n1;
+
+--disable_query_log
+
+while ($n1)
+{
+  let $m= $tables;
+
+  while ($m)
+  {
+     eval drop trigger `d$n1`.`trg_t$m`;
+
+     dec $m;
+  }
+  dec $n;
+  dec $n1;
+}
+
+let $n1= $dbs;
+dec $n1;
+let $n2= $n1;
+dec $n2;
+let $tables_2_rename= ;
+let $m= `select floor(rand()*$tables) + 1`;
+
+while ($n2)
+{
+    let $tables_2_rename= $tables_2_rename d$n1.t$m to d$n2.t$m ,;
+    eval drop table d$n2.t$m;
+    dec $n1;
+    dec $n2;
+}
+
+
+let $n= $dbs;
+let $n1= $n;
+dec $n1;
+
+--disable_warnings
+# The following query will leave so many warnings as many extra db pairs
+eval rename table $tables_2_rename d$n.t$m to d$n1.t$m;
+--enable_warnings
+
+--enable_query_log
+
+
+
+#
+# Clean-up
+#
+
+connection master;
+
+--disable_query_log
+
+let $n= $dbs;
+while ($n)
+{
+  eval drop database d$n;
+  dec $n;
+}
+
+--enable_query_log
+
+sync_slave_with_master;
+
+set @@global.mts_slave_parallel_workers= @save.mts_slave_parallel_workers;
+
+### TODO: --source include/rpl_end.inc

=== modified file 'mysql-test/suite/rpl/t/rpl_parallel_fallback.test'
--- a/mysql-test/suite/rpl/t/rpl_parallel_fallback.test	2010-12-27 18:54:41 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_fallback.test	2011-02-27 17:35:25 +0000
@@ -31,7 +31,7 @@ set @@session.binlog_format= row;
 create database d1;
 create table d1.t1 (a int auto_increment primary key) engine=innodb;
 
-#
+# (TODO: remove during refactoring)
 # Rows_query_log_event case
 #
 

=== added file 'mysql-test/suite/rpl/t/rpl_parallel_multi_db-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_parallel_multi_db-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_multi_db-master.opt	2011-02-27 17:35:25 +0000
@@ -0,0 +1 @@
+--thread_stack=512K

=== added file 'mysql-test/suite/rpl/t/rpl_parallel_multi_db-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_parallel_multi_db-slave.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_multi_db-slave.opt	2011-02-27 17:35:25 +0000
@@ -0,0 +1 @@
+--thread_stack=512K

=== added file 'mysql-test/suite/rpl/t/rpl_parallel_multi_db.test'
--- a/mysql-test/suite/rpl/t/rpl_parallel_multi_db.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_multi_db.test	2011-02-27 17:35:25 +0000
@@ -0,0 +1,342 @@
+#
+# WL#5569 MTS
+#
+# The test verifies correctness of Query event parallelization when
+# a DML Query modifies multiple databases.
+#
+
+--source include/master-slave.inc
+--source include/have_binlog_format_statement.inc
+
+--disable_query_log
+call mtr.add_suppression('.*Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.*');
+--enable_query_log
+
+# restart in Parallel
+
+let $workers= 4;
+
+connection slave;
+
+source include/stop_slave.inc;
+set @save.mts_slave_parallel_workers= @@global.mts_slave_parallel_workers;
+eval set @@global.mts_slave_parallel_workers= $workers;
+source include/start_slave.inc;
+
+
+let $dbs= 8;
+let $tables= 8;
+let $queries= `select $dbs*$tables * 4`;
+
+#
+# 1. Case of multi-update
+#
+
+connection master;
+
+# create & populate
+
+let $n= $dbs;
+while ($n)
+{
+  eval create database d$n;
+  let $m= $tables;
+  while ($m)
+  {
+     eval create table d$n.t$m (a int);
+     eval select round(rand()*$tables) into @var;
+     eval insert into d$n.t$m values (@var);
+     dec $m;
+  }
+  dec $n;
+}
+
+
+# operate to check consistency in the end
+
+let $k= $queries;
+
+--disable_query_log
+--disable_warnings
+while ($k)
+{
+   let $tables_in_query= `select 2 * (1 + floor(rand()*$dbs))`;
+   let $i= $tables_in_query;
+   let $table_list= ;
+   let $set_list= ;
+   while ($i)
+   {
+       let $n1= `select floor(rand()*$dbs + 1)`;
+       let $m1= `select floor(rand()*$tables + 1)`;
+       let $n2= `select floor(rand()*$dbs + 1)`;
+       let $m2= `select floor(rand()*$tables + 1)`;
+       let $table_list= $table_list d$n1.t$m1 as t_$i, ;
+       let $set_list= $set_list t_$i.a= ;
+       dec $i;
+
+       let $table_list= $table_list d$n2.t$m2 as t_$i, ;
+       let $set_list= $set_list t_$i.a + round(rand(10)), ;
+
+       dec $i;
+   }
+   let $n1= `select floor(rand()*$dbs + 1)`;
+   let $m1= `select floor(rand()*$tables + 1)`;   
+   let $n2= `select floor(rand()*$dbs + 1)`;
+   let $m2= `select floor(rand()*$tables + 1)`;
+
+##   --disable_warnings
+     
+     eval update $table_list d$n1.t$m1 as t_1_$i, d$n2.t$m2 as t_2_$i
+                 set $set_list t_1_$i.a=t_2_$i.a + round(rand(10));
+##   --enable_warnings
+
+   dec $k;
+}
+--enable_warnings
+--enable_query_log
+
+sync_slave_with_master; 
+
+#
+# 2. Case of invoked routines
+#
+
+# A. Functions
+
+# create functions & run load
+let $n= $dbs;
+# n'th db func is defined through n-1'th except n == 1
+let $n1= $n;
+dec $n1;
+
+connection master;
+
+--disable_query_log
+
+while ($n1)
+{
+  let $m= `select floor(rand()*$tables) + 1`;
+
+  delimiter |;
+
+  eval create function `d$n`.`func` (a int) returns int
+     begin
+     insert into `d$n`.`t$m` values (`d$n1`.`func`(1));
+     return 1;
+     end|
+
+  delimiter ;|
+
+  dec $n;
+  dec $n1;
+}
+
+delimiter |;
+
+eval create function `d1`.`func` (a int) returns int
+     begin
+     insert into `d1`.`t$m` values (0);
+     return 1;
+     end|
+
+delimiter ;|
+
+
+# invoke...
+
+let $k= $queries;
+
+while ($k)
+{
+   let $n= `select floor(rand()*$dbs) + 1`;
+   let $m= `select floor(rand()*$tables) + 1`;
+   let $n1= $n;
+   dec $n1;
+   if ($n1)
+   {
+       eval insert into d$n.t$m values (`d$n1`.`func`(1));
+   }
+   dec $k;
+}
+
+--enable_query_log
+
+sync_slave_with_master;
+
+# B. Triggers
+
+connection master;
+
+# create triggers & run load
+let $n= $dbs;
+# n'th db tables won't have any trigger to avoid circular dependency
+let $n1= $n;
+dec $n1;
+
+--disable_query_log
+while ($n1)
+{
+  let $m= $tables;
+
+  while ($m)
+  {
+     eval create trigger `d$n1`.`trg_t$m` before insert on `d$n1`.`t$m` for each row insert into `d$n`.`t$m` values(1);
+     dec $m;
+  }
+  dec $n;
+  dec $n1;
+}
+--enable_query_log
+
+# invoke...
+
+let $k= $queries;
+
+--disable_query_log
+--disable_warnings
+while ($k)
+{
+   let $n= `select floor(rand()*$dbs + 1)`;
+   let $m= `select floor(rand()*$tables + 1)`;
+   eval insert into d$n.t$n values (2);
+   dec $k;
+}
+--enable_warnings
+--enable_query_log
+
+
+sync_slave_with_master;
+
+#
+# Consistency check
+#
+
+let $n = $dbs;
+while($n)
+{
+  let $m= $tables;
+  while ($m)
+  {
+    let $diff_tables=master:d$n.t$m, slave:d$n.t$m;
+    source include/diff_tables.inc;
+    dec $m;
+  }
+  dec $n;
+}
+
+#
+# Clean-up of the regular case tests
+#
+
+connection master;
+
+--disable_query_log
+
+let $n= $dbs;
+while ($n)
+{
+  eval drop database d$n;
+  dec $n;
+}
+
+--enable_query_log
+
+sync_slave_with_master;
+
+#
+# Over MAX_DBS_IN_QUERY_MTS
+#
+
+let $dbs= 20;
+let $queries= `select $dbs* 4`;
+
+connection master;
+
+let $n= $dbs;
+let $m= 1;
+while ($n)
+{
+  eval create database d$n;
+  eval create table d$n.t$m (a int);
+  eval select round(rand()*$tables) into @var;
+  eval insert into d$n.t$m values (@var);
+
+  dec $n;
+}
+
+--disable_query_log
+--disable_warnings
+
+let $k= $queries;
+
+while ($k)
+{
+   let $tables_in_query= `select 2 * (1 + floor(rand()*$dbs))`;
+   let $i= $tables_in_query;
+   let $table_list= ;
+   let $set_list= ;
+   while ($i)
+   {
+       let $n1= `select floor(rand()*$dbs + 1)`;
+       let $m1= 1;
+       let $n2= `select floor(rand()*$dbs + 1)`;
+       let $m2= 1;
+       let $table_list= $table_list d$n1.t$m1 as t_$i, ;
+       let $set_list= $set_list t_$i.a= ;
+       dec $i;
+
+       let $table_list= $table_list d$n2.t$m2 as t_$i, ;
+       let $set_list= $set_list t_$i.a + round(rand(10)), ;
+
+       dec $i;
+   }
+   let $n1= `select floor(rand()*$dbs + 1)`;
+   let $m1= 1;
+   let $n2= `select floor(rand()*$dbs + 1)`;
+   let $m2= 1;
+
+     eval update $table_list d$n1.t$m1 as t_1_$i, d$n2.t$m2 as t_2_$i
+                 set $set_list t_1_$i.a=t_2_$i.a + round(rand(10));
+   dec $k;
+}
+--enable_warnings
+--enable_query_log
+
+sync_slave_with_master;
+
+#
+# Consistency check
+#
+
+let $n = $dbs;
+let $m= 1;
+while($n)
+{
+  let $diff_tables=master:d$n.t$m, slave:d$n.t$m;
+  source include/diff_tables.inc;
+  dec $n;
+}
+
+#
+# The final clean-up
+#
+
+connection master;
+
+--disable_query_log
+
+let $n= $dbs;
+while ($n)
+{
+  eval drop database d$n;
+  dec $n;
+}
+
+--enable_query_log
+
+sync_slave_with_master;
+
+
+set @@global.mts_slave_parallel_workers= @save.mts_slave_parallel_workers;
+
+### TODO: --source include/rpl_end.inc

=== 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-27 18:54:41 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_start_stop.test	2011-02-27 17:35:25 +0000
@@ -244,6 +244,7 @@ let $master_log_pos= query_get_value(SHO
 insert into t2 values (1);
 
 connection slave;
+--replace_regex /master_log_pos=[0-9]+/master_log_pos=MASTER_LOG_POS/
 eval start slave until master_log_file='$master_log_file', master_log_pos=$master_log_pos;
 
 source include/wait_for_slave_sql_to_stop.inc;

=== added file 'mysql-test/suite/rpl/t/rpl_parallel_temp_query.test'
--- a/mysql-test/suite/rpl/t/rpl_parallel_temp_query.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_parallel_temp_query.test	2011-02-27 17:35:25 +0000
@@ -0,0 +1,169 @@
+#
+# WL#5569 MTS
+#
+# The test verifies correctness of Query events parallelization.
+#
+
+--source include/master-slave.inc
+--source include/have_binlog_format_statement.inc
+
+call mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement accesses nontransactional table as well as transactional or temporary table.*');
+
+let $temp_tables= 16;
+let $workers= 4;
+
+connection slave;
+
+# restart in Parallel
+source include/stop_slave.inc;
+set @save.mts_slave_parallel_workers= @@global.mts_slave_parallel_workers;
+eval set @@global.mts_slave_parallel_workers= $workers;
+
+source include/start_slave.inc;
+
+# Two connections each create 2 db:s a regular table and a set of temp tables.
+# The temp tables contribute content to the regular tables.
+# In the end there must be consistent data on both sides.
+
+connection master;
+
+let $n= `select round($workers/2)`;
+let $n1= `select $n`;
+while ($n)
+{
+  eval create database d$n1;
+  eval use d$n1;
+  eval create table d$n1.t1 (a int auto_increment primary key, b int) engine=innodb;
+  let $i= $temp_tables;
+
+--disable_query_log
+  while($i)
+  {
+    let $temp_rows= `select round(rand()*$temp_tables) + 1`;
+    let $k= $temp_rows;
+    eval create temporary table tt_$i (a int auto_increment primary key);
+    while($k)
+    {
+	eval insert into tt_$i values (null);
+	dec $k;
+    }
+    dec $i;
+  }
+--enable_query_log
+
+  let $j= `select floor(rand()*$temp_tables) + 1`;
+--replace_regex /tt_.*/tt_##/
+  eval insert into d$n1.t1 (b) select count(*) from tt_$j;
+  dec $n;
+  dec $n1;
+}
+
+connection master1;
+
+let $n= `select round($workers/2)`;
+let $n1= `select 2*$n`;
+while ($n)
+{
+  eval create database d$n1;
+  eval use d$n1;
+  eval create table d$n1.t1 (a int auto_increment primary key, b int) engine=innodb;
+  let $i= $temp_tables;
+
+--disable_query_log
+  while($i)
+  {
+    let $temp_rows= `select round(rand()*$temp_tables) + 1`;
+    let $k= $temp_rows;
+    eval create temporary table tt_$i (a int auto_increment primary key);
+    while($k)
+    {
+	eval insert into tt_$i values (null);
+	dec $k;
+    }
+    dec $i;
+  }
+--enable_query_log
+
+  let $j= `select floor(rand()*$temp_tables) + 1`;
+--replace_regex /tt_.*/tt_##/
+  eval insert into d$n1.t1 (b) select count(*) from tt_$j;
+  dec $n;
+  dec $n1;
+}
+
+sync_slave_with_master;
+
+#
+# Consistency check
+#
+
+let $n = $workers;
+while($n)
+{
+  let $diff_tables=master:d$n.t1, slave:d$n.t1;
+  source include/diff_tables.inc;
+
+  dec $n;
+}
+
+#
+# cleanup
+#
+# Temp tables are removed two ways explicitly and implicitly by disconnecting.
+#
+
+connection master;
+
+let $i= `select round($temp_tables/2)`;
+while($i)
+{
+  eval drop temporary table tt_$i;
+  dec $i;
+}
+
+let $n= `select round($workers/2)`;
+let $n1= `select $n`;
+while ($n)
+{
+  eval drop database d$n1;
+  dec $n;
+  dec $n1;
+}
+
+
+connection master1;
+
+let $i= `select round($temp_tables/2)`;
+while($i)
+{
+  eval drop temporary table tt_$i;
+  dec $i;
+}
+
+sync_slave_with_master;
+#connection slave;
+
+connection master1;
+disconnect master1;
+
+#
+# Clean-up
+#
+
+connection master;
+
+let $n= `select round($workers/2)`;
+let $n1= `select 2*$n`;
+while ($n)
+{
+  eval drop database d$n1;
+  dec $n;
+  dec $n1;
+}
+
+sync_slave_with_master;
+source include/stop_slave.inc;
+
+set @@global.mts_slave_parallel_workers= @save.mts_slave_parallel_workers;
+
+### TODO: --source include/rpl_end.inc

=== modified file 'mysql-test/suite/sys_vars/r/all_vars.result'
--- a/mysql-test/suite/sys_vars/r/all_vars.result	2010-12-27 18:54:41 +0000
+++ b/mysql-test/suite/sys_vars/r/all_vars.result	2011-02-27 17:35:25 +0000
@@ -12,45 +12,45 @@ There should be *no* long test name list
 select variable_name as `There should be *no* variables listed below:` from t2
 left join t1 on variable_name=test_name where test_name is null;
 There should be *no* variables listed below:
+MTS_SLAVE_WORKER_QUEUE_LEN_MAX
 INNODB_STATS_TRANSIENT_SAMPLE_PAGES
 MTS_PARTITION_HASH_SOFT_MAX
-MTS_PENDING_JOBS_SIZE_MAX
 MTS_EXP_SLAVE_LOCAL_TIMESTAMP
-MTS_EXP_SLAVE_RUN_QUERY_IN_PARALLEL
 INNODB_STATS_PERSISTENT_SAMPLE_PAGES
 RELAY_LOG_BASENAME
 LOG_BIN_BASENAME
 INNODB_ANALYZE_IS_PERSISTENT
 INNODB_PRINT_ALL_DEADLOCKS
+MTS_MASTER_UPDATED_DBS_MAX
 INNODB_RESET_MONITOR_COUNTER
 MTS_SLAVE_PARALLEL_WORKERS
 MTS_WORKER_UNDERRUN_LEVEL
-MTS_SLAVE_WORKER_QUEUE_LEN_MAX
 INNODB_RESET_ALL_MONITOR_COUNTER
 LOG_BIN_INDEX
 INNODB_DISABLE_MONITOR_COUNTER
 INNODB_ENABLE_MONITOR_COUNTER
 INNODB_FILE_FORMAT_MAX
+MTS_PENDING_JOBS_SIZE_MAX
 MTS_COORDINATOR_BASIC_NAP
+MTS_SLAVE_WORKER_QUEUE_LEN_MAX
 INNODB_STATS_TRANSIENT_SAMPLE_PAGES
 MTS_PARTITION_HASH_SOFT_MAX
-MTS_PENDING_JOBS_SIZE_MAX
 MTS_EXP_SLAVE_LOCAL_TIMESTAMP
-MTS_EXP_SLAVE_RUN_QUERY_IN_PARALLEL
 INNODB_STATS_PERSISTENT_SAMPLE_PAGES
 RELAY_LOG_BASENAME
 LOG_BIN_BASENAME
 INNODB_ANALYZE_IS_PERSISTENT
 INNODB_PRINT_ALL_DEADLOCKS
+MTS_MASTER_UPDATED_DBS_MAX
 INNODB_RESET_MONITOR_COUNTER
 MTS_SLAVE_PARALLEL_WORKERS
 MTS_WORKER_UNDERRUN_LEVEL
-MTS_SLAVE_WORKER_QUEUE_LEN_MAX
 INNODB_RESET_ALL_MONITOR_COUNTER
 LOG_BIN_INDEX
 INNODB_DISABLE_MONITOR_COUNTER
 INNODB_ENABLE_MONITOR_COUNTER
 INNODB_FILE_FORMAT_MAX
+MTS_PENDING_JOBS_SIZE_MAX
 MTS_COORDINATOR_BASIC_NAP
 drop table t1;
 drop table t2;

=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2010-12-27 18:54:41 +0000
+++ b/sql/binlog.cc	2011-02-27 17:35:25 +0000
@@ -4535,6 +4535,59 @@ THD::binlog_set_pending_rows_event(Rows_
 }
 
 /**
+   @param db    db name c-string to be inserted into abc-sorted
+                THD::binlog_updated_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()).
+*/
+void
+THD::add_to_binlog_updated_dbs(const char *db)
+{
+  char *after_db;
+  if (binlog_updated_db_names->elements >  MAX_DBS_IN_QUERY_MTS)
+  {
+    push_warning_printf(this, MYSQL_ERROR::WARN_LEVEL_WARN,
+                        ER_UPDATED_DBS_GREATER_MAX,
+                        ER(ER_UPDATED_DBS_GREATER_MAX),
+                        MAX_DBS_IN_QUERY_MTS);
+    return;
+  }
+
+  after_db= strdup_root(mem_root, db);
+  if (binlog_updated_db_names->elements != 0)
+  {
+    List_iterator<char> it(*get_binlog_updated_db_names());
+
+    while (it++)
+    {
+      char *swap= NULL;
+      char **ref_cur_db= it.ref();
+      int cmp= strcmp(after_db, *ref_cur_db);
+
+      DBUG_ASSERT(!swap || cmp < 0);
+      
+      if (cmp == 0)
+      {
+        after_db= NULL;  /* dup to ignore */
+        break;
+      }
+      else if (swap || cmp > 0)
+      {
+        swap= *ref_cur_db;
+        *ref_cur_db= after_db;
+        after_db= swap;
+      }
+    }
+  }
+  if (after_db)
+    binlog_updated_db_names->push_back(after_db);
+}
+
+
+/**
   Decide on logging format to use for the statement and issue errors
   or warnings as needed.  The decision depends on the following
   parameters:
@@ -4755,6 +4808,28 @@ int THD::decide_logging_format(TABLE_LIS
          multi_access_engine= TRUE;
 
       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_QUERY_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_updated_db_names)
+      {
+        binlog_updated_db_names= new List<char>; /* 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));

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2010-11-18 16:34:56 +0000
+++ b/sql/events.cc	2011-02-27 17:35:25 +0000
@@ -384,6 +384,7 @@ Events::create_event(THD *thd, Event_par
       }
       else
       {
+        thd->add_one_db_to_binlog_updated_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. */
         ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
@@ -502,6 +503,12 @@ Events::update_event(THD *thd, Event_par
                                   new_element);
       /* Binlog the alter event. */
       DBUG_ASSERT(thd->query() && thd->query_length());
+
+      thd->set_binlog_updated_db_names(new List<char>);
+      thd->add_to_binlog_updated_dbs(parse_data->dbname.str);
+      if (new_dbname)
+        thd->add_to_binlog_updated_dbs(new_dbname->str);
+
       ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
     }
   }
@@ -568,6 +575,8 @@ Events::drop_event(THD *thd, LEX_STRING 
       event_queue->drop_event(thd, dbname, name);
     /* Binlog the drop event. */
     DBUG_ASSERT(thd->query() && thd->query_length());
+
+    thd->add_one_db_to_binlog_updated_dbs(dbname.str);
     ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
   }
   /* Restore the state of binlog format */

=== modified file 'sql/field.cc'
--- a/sql/field.cc	2010-12-29 00:38:59 +0000
+++ b/sql/field.cc	2011-02-27 17:35:25 +0000
@@ -3736,7 +3736,12 @@ longlong Field_long::val_int(void)
   ASSERT_COLUMN_MARKED_FOR_READ;
   int32 j;
   /* See the comment in Field_long::store(long long) */
-  DBUG_ASSERT(table->in_use == current_thd);
+  /* 
+     In case the method is executed not by the table's owner
+     that one must be a Slave worker thread.
+  */
+  DBUG_ASSERT(table->in_use == current_thd || (current_thd)->slave_thread);
+
 #ifdef WORDS_BIGENDIAN
   if (table->s->db_low_byte_first)
     j=sint4korr(ptr);
@@ -6308,8 +6313,8 @@ int Field_string::store(const char *from
   const char *cannot_convert_error_pos;
   const char *from_end_pos;
 
-  /* See the comment for Field_long::store(long long) */
-  DBUG_ASSERT(table->in_use == current_thd);
+  /* See the comment for Field_long::store(long long) and Field_long::val_int */
+  DBUG_ASSERT(table->in_use == current_thd || (current_thd)->slave_thread);
 
   copy_length= well_formed_copy_nchars(field_charset,
                                        (char*) ptr, field_length,
@@ -6458,8 +6463,8 @@ String *Field_string::val_str(String *va
 			      String *val_ptr)
 {
   ASSERT_COLUMN_MARKED_FOR_READ;
-  /* See the comment for Field_long::store(long long) */
-  DBUG_ASSERT(table->in_use == current_thd);
+  /* See the comment for Field_long::store(long long) and Field_long::val_int */
+  DBUG_ASSERT(table->in_use == current_thd || (current_thd)->slave_thread);
   uint length;
   if (table->in_use->variables.sql_mode &
       MODE_PAD_CHAR_TO_FULL_LENGTH)

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2011-01-11 11:45:02 +0000
+++ b/sql/handler.cc	2011-02-27 17:35:25 +0000
@@ -2127,7 +2127,13 @@ void **handler::ha_data(THD *thd) const
 
 THD *handler::ha_thd(void) const
 {
-  DBUG_ASSERT(!table || !table->in_use || table->in_use == current_thd);
+  /* 
+     About current_thd->slave_thread alternative,
+     MTS coordinator open/closes a temp table while the rest of operation
+     is done by Workers.
+  */
+  DBUG_ASSERT(!table || !table->in_use || table->in_use == current_thd ||
+              current_thd->slave_thread);
   return (table && table->in_use) ? table->in_use : current_thd;
 }
 

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2011-01-11 23:01:02 +0000
+++ b/sql/log_event.cc	2011-03-30 14:11:24 +0000
@@ -2408,7 +2408,7 @@ bool Log_event::contains_partition_info(
    r - a mini-group internal "regular" event that follows its g-parent
       (Write, Update, Delete -rows)
    S - sequentially applied event (may not be a part of any group).
-       Events of this type are determined via @c only_sequential_exec()
+       Events of this type are determined via @c mts_sequential_exec()
        earlier and don't cause calling this method .
    T - terminator of the group (XID, COMMIT, ROLLBACK)
 
@@ -2434,7 +2434,7 @@ Slave_worker *Log_event::get_slave_worke
 
   /* checking properties and perform corresponding actions */
 
-  // B or a DDL
+  // Beginning of a group or a DDL
   if ((is_b_event= starts_group()) || !rli->curr_group_seen_begin)
   {
     ulong gaq_idx;
@@ -2477,42 +2477,55 @@ Slave_worker *Log_event::get_slave_worke
       const_cast<Relay_log_info*>(rli)->curr_group_seen_begin= TRUE;
       return NULL;
     } 
-    else 
-    { 
-      DBUG_ASSERT(!rli->curr_group_seen_begin);
-
-      // Parallel single event proceeds to partiting etc ...
-    }
   }
 
-  //else // g
+  // mini-group representative
 
   if (contains_partition_info())
   {
-    // a lot of things inside `get_slave_worker_id'
-    const_cast<Relay_log_info *>(rli)->last_assigned_worker=
-      worker= get_slave_worker(get_db(), const_cast<Relay_log_info *>(rli));
-    get_dynamic(&rli->gaq->Q, (uchar*) &g, rli->gaq->assigned_group_index);
-    if (g.worker_id == (ulong) -1)  // assign "offically" the current group
+    List_iterator<char> it(*mts_get_dbs(rli->info_thd->mem_root));
+
+    it++;
+    do
     {
-      g.worker_id= worker->id;       // todo/fixme: think of Slave_worker* here
-      set_dynamic(&rli->gaq->Q, (uchar*) &g, rli->gaq->assigned_group_index);
+      char **ref_cur_db= it.ref();
+      // a lot of things inside `get_slave_worker_id'
+      const_cast<Relay_log_info *>(rli)->last_assigned_worker=
+        worker= get_slave_worker(*ref_cur_db, const_cast<Relay_log_info *>(rli));
+      get_dynamic(&rli->gaq->Q, (uchar*) &g, rli->gaq->assigned_group_index);
+      if (g.worker_id == (ulong) -1)  // assign "offically" the current group
+      {
+        g.worker_id= worker->id;       // todo/fixme: think of Slave_worker* here
+        set_dynamic(&rli->gaq->Q, (uchar*) &g, rli->gaq->assigned_group_index);
+        
+        DBUG_ASSERT(g.group_relay_log_name == NULL);
+      }
+    } while (mts_number_dbs() != OVER_MAX_DBS_IN_QUERY_MTS && it++);
 
-      DBUG_ASSERT(g.group_relay_log_name == NULL);
-    }
+    // TODO: convert to C's private mem_root.
+
+    // 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));
   }
-  else // r
+  else // a mini-group internal "regular" event
     if (rli->last_assigned_worker)
     {
       worker= rli->last_assigned_worker;
       
       DBUG_ASSERT(rli->curr_group_assigned_parts.elements > 0); // g must've done
     }
-    else // p
+    else // int_, rand_, user_ var:s
     {
       Log_event *ptr_curr_ev= this;
 
-      // TODO: assert possible event types
+      DBUG_ASSERT(get_type_code() == INTVAR_EVENT ||
+                  get_type_code() == RAND_EVENT ||
+                  get_type_code() == USER_VAR_EVENT ||
+
+                  // (TODO: remove) temprory placed:
+                  get_type_code() ==  ROWS_QUERY_LOG_EVENT);
 
       insert_dynamic(&const_cast<Relay_log_info*>(rli)->curr_group_da,
                      (uchar*) &ptr_curr_ev);
@@ -2520,7 +2533,7 @@ Slave_worker *Log_event::get_slave_worke
       DBUG_ASSERT(rli->curr_group_da.elements > 0);
     }
 
-  // T
+  // the group terminal event (Commit, Xid or a DDL query)
   if (ends_group() || !rli->curr_group_seen_begin)
   {
     uint i;
@@ -2782,53 +2795,70 @@ int Log_event::apply_event(Relay_log_inf
   Slave_worker *w= NULL;
   Slave_job_item item= {NULL}, *job_item= &item;
   Relay_log_info *c_rli= const_cast<Relay_log_info*>(rli);  // constless alias
-  bool parallel;
-  bool seq_event;
-  bool term_event;
+  bool parallel, seq_event, term_event;
+
+  if (rli->is_mts_recovery())
+  {
+    bool skip= _bitmap_is_set(&c_rli->recovery_groups, c_rli->mts_recovery_index);
+
+    if (ends_group()) // TODO: || ! seen_begin
+    {
+      c_rli->mts_recovery_index++;
+      if (--c_rli->mts_recovery_group_cnt == 0)
+      {
+        c_rli->recovery_parallel_workers= c_rli->slave_parallel_workers;
+        c_rli->mts_recovery_index= 0;
+      }
+    }
+    if (skip)
+      DBUG_RETURN(0);
+    else 
+      DBUG_RETURN(do_apply_event(rli));
+  }
 
   if (!(parallel= rli->is_parallel_exec()) ||
-      rli->mts_recovery_group_cnt != 0 ||
-      ((seq_event=
-        only_sequential_exec(rli->run_query_in_parallel,
-                             rli->curr_group_seen_begin /* todo: obs 2nd arg */))
-       // rli->curr_group_seen_begin && ends_group() => rli->last_assigned_worker
-       && (!rli->curr_group_seen_begin || parallel_exec_by_coordinator(::server_id))))
+      ((seq_event= mts_sequential_exec()) &&
+       (!rli->curr_group_seen_begin ||
+        mts_async_exec_by_coordinator(::server_id))))
   {
     if (parallel)
     {
-      // This `only-sequential' case relates to a DDL Query case
-      // or a group split apart by FD event
-      DBUG_ASSERT(seq_event &&
-                  (rli->curr_group_da.elements == 0 || rli->curr_group_seen_begin));
-      
-      if (!parallel_exec_by_coordinator(::server_id))
+      /* 
+         There are two classes of events that Coordinator executes
+         itself. One requires all Workers to finish up their assignments.
+         The other does not need (actually can not have) this synchronization.
+      */
+
+      if (!mts_async_exec_by_coordinator(::server_id))
       {
+        /*
+          this  event does not split the current group but is indeed
+          a separator beetwen two master's binlog therefore requiring
+          Workers to sync.
+        */
+
         DBUG_ASSERT(!rli->curr_group_seen_begin);
 
-        c_rli->curr_group_is_parallel= FALSE;   // Coord will destruct events
+        /*
+          marking the event as not being executed in parallel that affects
+          memory deallocation in the following execution path.
+        */
+        c_rli->curr_group_is_parallel= FALSE;
         (void) wait_for_workers_to_finish(rli);
       }
       else
       {
-        c_rli->curr_event_is_not_in_group= TRUE;
-      }
-    }
-    else if (rli->is_mts_recovery())
-    {
-      // recovery
-      bool skip= _bitmap_is_set(&c_rli->recovery_groups, c_rli->mts_recovery_index);
-
-      if (ends_group()) // todo: || rli->run_query_in_parallel && ! seen_begin
-      {
-        c_rli->mts_recovery_index++;
-        if (--c_rli->mts_recovery_group_cnt == 0)
+        if (rli->curr_group_is_parallel)
         {
-          c_rli->recovery_parallel_workers= c_rli->slave_parallel_workers;
-          c_rli->mts_recovery_index= 0;
+          /* 
+             the event is artifical to splits the current group into separate
+             relay-logs. Differently to the previous events of the group this one
+             is applied by Coordinator and w/o any synchronization with Workers.
+          */
+          c_rli->curr_group_split= TRUE;
+          c_rli->curr_group_is_parallel= FALSE;
         }
       }
-      if (skip)
-        DBUG_RETURN(0);
     }
     DBUG_RETURN(do_apply_event(rli));
   }
@@ -2837,10 +2867,6 @@ int Log_event::apply_event(Relay_log_inf
               rli->last_assigned_worker);
 
   /* 
-     Work-around:s for B, T,..., Q case and ROWS_QUERY_LOG_EVENT
-     A worker has been assigned but it needs sequential environment.
-
-     Todo: support Query parallelization.
      Todo: disassociate Rows_* events from the central rli.
   */
   if (seq_event)
@@ -2857,9 +2883,10 @@ int Log_event::apply_event(Relay_log_inf
         my_sleep(10);
       }
       c_rli->rows_query_ev= (Rows_query_log_event*) this;
-    }
-  }
+     }
+   }
 
+  // getting Worker's id
   if ((!(w= get_slave_worker_id(rli)) ||
        DBUG_EVALUATE_IF("fault_injection_get_slave_worker", 1, 0)))
     DBUG_RETURN(rli->curr_group_assigned_parts.elements == 0 ? FALSE : TRUE);
@@ -2870,8 +2897,10 @@ int Log_event::apply_event(Relay_log_inf
 
   if (rli->curr_group_da.elements > 0)
   {
-    // the current event sorted out which partion the current group belongs to.
-    // It's time now to processed deferred array events.
+    /*
+      the current event sorted out which partion the current group belongs to.
+      It's time now to processed deferred array events.
+    */
     for (i= 0; i < rli->curr_group_da.elements; i++)
     { 
       Slave_job_item da_item;
@@ -2987,25 +3016,29 @@ int slave_worker_exec_job(Slave_worker *
   {
     if (ev->contains_partition_info())
     {
+      List_iterator<char> it(*ev->mts_get_dbs(thd->mem_root));
       DYNAMIC_ARRAY *ep= &(w->curr_group_exec_parts->dynamic_ids);
-      uint i;
-      char key[NAME_LEN + 2];
-      bool found= FALSE;
-      const char *dbname= ev->get_db();
-      uchar dblength= (uint) strlen(dbname);
       
-      for (i= 0; i < ep->elements && !found; i++)
+      while (it++)
       {
-        get_dynamic(ep, (uchar*) key, i);
-        found=
-          (key[0] == dblength) &&
-          (strncmp(key + 1, const_cast<char*>(dbname), dblength) == 0);
-      }
-      if (!found)
-      {
-        key[0]= dblength;
-        memcpy(key + 1, dbname, dblength + 1);
-        insert_dynamic(ep, (uchar*) key);
+        bool found= FALSE;
+        char key[NAME_LEN + 2];
+        const char *dbname= *it.ref();
+        uchar dblength= (uint) strlen(dbname);
+
+        for (uint i= 0; i < ep->elements && !found; i++)
+        {
+          get_dynamic(ep, (uchar*) key, i);
+          found=
+            (key[0] == dblength) &&
+            (strncmp(key + 1, const_cast<char*>(dbname), dblength) == 0);
+        }
+        if (!found)
+        {
+          key[0]= dblength;
+          memcpy(key + 1, dbname, dblength + 1);
+          insert_dynamic(ep, (uchar*) key);
+        }
       }
     }
   }
@@ -3354,6 +3387,38 @@ bool Query_log_event::write(IO_CACHE* fi
       start+= host.length;
     }
   }
+
+  if (thd && thd->get_binlog_updated_db_names() != NULL)
+  {
+    uchar dbs;
+    *start++= Q_UPDATED_DB_NAMES;
+
+    compile_time_assert(MAX_DBS_IN_QUERY_MTS <= OVER_MAX_DBS_IN_QUERY_MTS);
+
+    /* 
+       in case of the number of db:s exceeds  MAX_DBS_IN_QUERY_MTS
+       no db:s is written and event will require the sequential applying on slave.
+    */
+    dbs= *start++=
+      (thd->get_binlog_updated_db_names()->elements <= MAX_DBS_IN_QUERY_MTS) ?
+      thd->get_binlog_updated_db_names()->elements : OVER_MAX_DBS_IN_QUERY_MTS;
+
+    DBUG_ASSERT(dbs != 0);
+
+    if (dbs <= MAX_DBS_IN_QUERY_MTS)
+    {
+      List_iterator_fast<char> it(*thd->get_binlog_updated_db_names());
+      char *db_name;
+
+      while ((db_name= it++))
+      {
+        strcpy((char*) start, db_name);
+        start += strlen(db_name) + 1;
+      }
+    }
+    thd->clear_binlog_updated_db_names();
+  }
+
   /*
     NOTE: When adding new status vars, please don't forget to update
     the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function
@@ -3437,7 +3502,7 @@ Query_log_event::Query_log_event(THD* th
    lc_time_names_number(thd_arg->variables.lc_time_names->number),
    charset_database_number(0),
    table_map_for_update((ulonglong)thd_arg->table_map_for_update),
-   master_data_written(0)
+   master_data_written(0), mts_updated_dbs(0)
 {
   time_t end_time;
 
@@ -3638,6 +3703,7 @@ code_name(int code)
   case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
   case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
   case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE";
+  case Q_UPDATED_DB_NAMES: return "Q_UPDATED_DB_NAMES";
   }
   sprintf(buf, "CODE#%d", code);
   return buf;
@@ -3675,7 +3741,8 @@ Query_log_event::Query_log_event(const c
    flags2_inited(0), sql_mode_inited(0), charset_inited(0),
    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)
+   table_map_for_update(0), master_data_written(0),
+   mts_updated_dbs(OVER_MAX_DBS_IN_QUERY_MTS)
 {
   ulong data_len;
   uint32 tmp;
@@ -3854,6 +3921,31 @@ Query_log_event::Query_log_event(const c
       CHECK_SPACE(pos, end, host.length);
       host.str= (char *)pos;
       pos+= host.length;
+      break;
+    }
+    case Q_UPDATED_DB_NAMES:
+    {
+      CHECK_SPACE(pos, end, 1);
+      mts_updated_dbs= *pos++;
+      /* 
+         Notice, the following check is positive also in case of
+         the master's MAX_DBS_IN_QUERY_MTS > the slave's one and the event 
+         contains e.g the master's MAX_DBS_IN_QUERY_MTS db:s.
+      */
+      if (mts_updated_dbs > MAX_DBS_IN_QUERY_MTS)
+      {
+        mts_updated_dbs= OVER_MAX_DBS_IN_QUERY_MTS;
+        break;
+      }
+
+      DBUG_ASSERT(mts_updated_dbs != 0);
+
+      for (uchar i= 0; i < mts_updated_dbs; i++)
+      {
+        strcpy(mts_updated_db_names[i], (char*) pos);
+        pos+= 1 + strlen((const char*) pos);
+      }
+      break;
     }
     default:
       /* That's why you must write status vars in growing order of code */

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2011-01-11 23:01:02 +0000
+++ b/sql/log_event.h	2011-02-27 17:35:25 +0000
@@ -258,6 +258,18 @@ struct sql_ex_info
 #define INCIDENT_HEADER_LEN    2
 #define HEARTBEAT_HEADER_LEN   0
 #define IGNORABLE_HEADER_LEN   0
+
+/*
+   The maximum number of updated databases that a status of Query-log-event can carry.
+   In can redefined still to not be bigger than OVER_MAX_DBS_IN_QUERY_MTS.
+*/
+#define MAX_DBS_IN_QUERY_MTS 16
+/*
+   When the actual number of db:s exceeds MAX_DBS_IN_QUERY_MTS
+   the value of OVER_MAX_DBS_IN_QUERY_MTS is is put into the mts_updated_dbs status.
+*/
+#define OVER_MAX_DBS_IN_QUERY_MTS 254
+
 /* 
   Max number of possible extra bytes in a replication event compared to a
   packet (i.e. a query) sent from client to master;
@@ -273,6 +285,8 @@ struct sql_ex_info
                                    1 + 2          /* type, charset_database_number */ + \
                                    1 + 8          /* type, table_map_for_update */ + \
                                    1 + 4          /* type, master_data_written */ + \
+                                                  /* type, db_1, db_2, ... */  \
+                                   1 + (MAX_DBS_IN_QUERY_MTS * (1 + NAME_LEN)) + \
                                    1 + 16 + 1 + 60/* type, user_len, user, host_len, host */)
 #define MAX_LOG_EVENT_HEADER   ( /* in order of Query_log_event::write */ \
   LOG_EVENT_HEADER_LEN + /* write_header */ \
@@ -344,6 +358,13 @@ struct sql_ex_info
 
 #define Q_INVOKER 11
 
+/*
+  Q_UPDATED_DB_NAMES status variable collects of the updated db:s
+  total number and their names to be propagated to the slave in order
+  to facilitate the parallel applying of the Query events.
+*/
+#define Q_UPDATED_DB_NAMES 12
+
 /* Intvar event post-header */
 
 /* Intvar event data */
@@ -1069,6 +1090,24 @@ 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<char>* mts_get_dbs(MEM_ROOT *mem_root)
+  {
+    List<char> *res= new List<char>;
+    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; }
+
 #else
   Log_event() : temp_buf(0) {}
     /* avoid having to link mysqlbinlog against libpthread */
@@ -1192,28 +1231,21 @@ public:
 
   /**
      MST: to execute serially due to technical or conceptual limitation
-
+     
      @return TRUE if despite permanent parallel execution mode an event
                   needs applying in a real isolation that is sequentially.
   */
-  bool only_sequential_exec(bool query_in_parallel, bool group_term_in_parallel)
+  bool mts_sequential_exec()
   {
     return
-       /* 
+      /* 
          the 4 types below are limitly parallel-supported (the default 
          session db not the actual db).
-         Decision on BEGIN is deferred till the following event.
-         Decision on Commit or Xid is forced by the one for BEGIN.
+         Decision on BEGIN, COMMIT, Xid is the parallel.
       */
-      
-      (!query_in_parallel &&
-       ((get_type_code() == QUERY_EVENT
-         && !starts_group() && !ends_group())    ||
-        get_type_code() == INTVAR_EVENT          ||
-        get_type_code() == USER_VAR_EVENT        ||
-        get_type_code() == RAND_EVENT))          ||
-
-      (!group_term_in_parallel && ends_group())  ||
+      (get_type_code() == QUERY_EVENT &&
+       !starts_group() && !ends_group() &&
+       (mts_number_dbs() ==  OVER_MAX_DBS_IN_QUERY_MTS)) ||
 
       get_type_code() == START_EVENT_V3          ||
       get_type_code() == STOP_EVENT              ||
@@ -1232,7 +1264,7 @@ public:
       get_type_code() == PRE_GA_UPDATE_ROWS_EVENT||
       get_type_code() == PRE_GA_DELETE_ROWS_EVENT||
 
-      get_type_code() == ROWS_QUERY_LOG_EVENT    || /* todo: make parallel */
+      get_type_code() == ROWS_QUERY_LOG_EVENT    || /* TODO: make parallel */
 
       get_type_code() == INCIDENT_EVENT;
   }
@@ -1243,7 +1275,7 @@ public:
      @return TRUE  if that's the case,
              FALSE otherwise.
   */
-  bool parallel_exec_by_coordinator(ulong slave_server_id)
+  bool mts_async_exec_by_coordinator(ulong slave_server_id)
   {
     return
       (get_type_code() == FORMAT_DESCRIPTION_EVENT ||
@@ -1851,12 +1883,38 @@ public:
     Q_MASTER_DATA_WRITTEN_CODE to the slave's server binlog.
   */
   uint32 master_data_written;
+  /*
+    number of updated db:s by the query and their names. This info
+    is requested by both Coordinator and Worker.
+  */
+  uchar mts_updated_dbs;
+  char mts_updated_db_names[MAX_DBS_IN_QUERY_MTS][NAME_LEN];
 
 #ifdef MYSQL_SERVER
 
   Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
                   bool using_trans, bool direct, bool suppress_use, int error);
   const char* get_db() { return db; }
+
+  /**
+     Returns a list of updated db:s or the default db single item list
+     in case of over-MAX_DBS_IN_QUERY_MTS actual db:s.
+  */
+  virtual List<char>* mts_get_dbs(MEM_ROOT *mem_root)
+  {
+    List<char> *res= new (mem_root) List<char>;
+    if (mts_updated_dbs == OVER_MAX_DBS_IN_QUERY_MTS)
+      res->push_back((char*) get_db());
+    else
+      for (uchar i= 0; i < mts_updated_dbs; i++)
+        res->push_back(mts_updated_db_names[i]);
+    return res;
+  }
+
+  virtual uchar mts_number_dbs() { return mts_updated_dbs; }
+
+  virtual uchar mts_number_of_updated_dbs() { return mts_updated_dbs; }
+
 #ifdef HAVE_REPLICATION
   void pack_info(Protocol* protocol);
 #endif /* HAVE_REPLICATION */

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2011-01-11 23:01:02 +0000
+++ b/sql/mysqld.cc	2011-02-27 17:35:25 +0000
@@ -468,7 +468,6 @@ ulonglong slave_type_conversions_options
 ulong opt_mts_slave_parallel_workers;
 ulong opt_mts_slave_worker_queue_len_max;
 my_bool opt_mts_slave_local_timestamp;
-my_bool opt_mts_slave_run_query_in_parallel;
 ulong opt_mts_partition_hash_soft_max;
 ulonglong opt_mts_pending_jobs_size_max;
 ulong opt_mts_coordinator_basic_nap;

=== modified file 'sql/mysqld.h'
--- a/sql/mysqld.h	2010-12-27 18:54:41 +0000
+++ b/sql/mysqld.h	2011-02-27 17:35:25 +0000
@@ -182,7 +182,6 @@ extern uint  slave_net_timeout;
 extern ulong opt_mts_slave_parallel_workers;
 extern ulong opt_mts_slave_worker_queue_len_max;
 extern my_bool opt_mts_slave_local_timestamp;
-extern my_bool opt_mts_slave_run_query_in_parallel;
 extern ulong opt_mts_partition_hash_soft_max;
 extern ulonglong opt_mts_pending_jobs_size_max;
 extern ulong opt_mts_coordinator_basic_nap;

=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc	2010-12-27 18:54:41 +0000
+++ b/sql/rpl_rli.cc	2011-02-27 17:35:25 +0000
@@ -52,6 +52,7 @@ static PSI_cond_info *worker_conds= NULL
 
 PSI_mutex_key *key_mutex_slave_parallel_worker= NULL;
 PSI_mutex_key key_mutex_slave_parallel_pend_jobs;
+PSI_mutex_key key_mutex_mts_temp_tables_lock;
 
 PSI_cond_key *key_cond_slave_parallel_worker= NULL;
 PSI_cond_key key_cond_slave_parallel_pend_jobs;
@@ -72,7 +73,7 @@ Relay_log_info::Relay_log_info(bool is_s
    this_worker(NULL), slave_parallel_workers(0),
    recovery_parallel_workers(0),
    checkpoint_group(mts_checkpoint_group), mts_recovery_group_cnt(0),
-   mts_recovery_index(0), curr_event_is_not_in_group(0),
+   mts_recovery_index(0),
    sql_delay(0), sql_delay_end(0), m_flags(0)
 {
   DBUG_ENTER("Relay_log_info::Relay_log_info");
@@ -130,6 +131,8 @@ void Relay_log_info::init_workers(ulong 
   mysql_mutex_init(key_mutex_slave_parallel_pend_jobs, &pending_jobs_lock,
                    MY_MUTEX_INIT_FAST);
   mysql_cond_init(key_cond_slave_parallel_pend_jobs, &pending_jobs_cond, NULL);
+  mysql_mutex_init(key_mutex_mts_temp_tables_lock, &mts_temp_tables_lock,
+                   MY_MUTEX_INIT_FAST);
   my_init_dynamic_array(&workers, sizeof(Slave_worker *), slave_parallel_workers, 4);
 }
 
@@ -140,6 +143,7 @@ void Relay_log_info::deinit_workers()
 {
   mysql_mutex_destroy(&pending_jobs_lock);
   mysql_cond_destroy(&pending_jobs_cond);
+  mysql_mutex_destroy(&mts_temp_tables_lock);
 
   if (!this_worker)
     delete_dynamic(&workers);

=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h	2011-01-11 22:54:12 +0000
+++ b/sql/rpl_rli.h	2011-02-27 17:35:25 +0000
@@ -448,7 +448,6 @@ 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 run_query_in_parallel;   // Query's default db not the actual db as part
   bool curr_group_isolated;     // Trans is exec:d by Worker but in exclusive env
   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
@@ -459,7 +458,8 @@ public:
   Slave_worker* this_worker; // used by w_rli. The cental rli has it as NULL.
   ulonglong mts_total_groups; // total event groups distributed in current session
  
-  bool curr_group_is_parallel; // a mark for Coord to indicate on T-event of the curr group at delete
+  bool curr_group_is_parallel; // an event to process by Coordinator
+  bool curr_group_split;       // an event split the current group forcing C to exec it
   ulong opt_slave_parallel_workers; // auxiliary cache for ::opt_slave_parallel_workers
   ulong slave_parallel_workers;     // the one slave session time number of workers
   ulong recovery_parallel_workers; // number of workers while recovering.
@@ -475,7 +475,18 @@ public:
   MY_BITMAP recovery_groups;  // bitmap used during recovery.
   ulong mts_recovery_group_cnt; // number of groups to execute at recovery
   ulong mts_recovery_index;     // running index of recoverable groups
-  bool curr_event_is_not_in_group; // a special case of group split apart by FD
+  /*
+    temporary tables are held by Coordinator though are created and dropped
+    explicilty by Workers. The following lock has to be taken by either party
+    in order to conduct any operation in the temp tables placeholder, incl.
+    find, drop, create, open.
+  */
+  mysql_mutex_t mts_temp_tables_lock;
+  /*
+    While Worker utilize its thd->mem_root, Coordinator adopts a specific mem-root:
+  */
+  MEM_ROOT mts_coor_mem_root;
+
   /* most of allocation in the coordinator rli is there */
   void init_workers(ulong);
 
@@ -724,4 +735,5 @@ private:
 };
 
 bool mysql_show_relaylog_events(THD* thd);
+
 #endif /* RPL_RLI_H */

=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc	2011-01-11 22:54:12 +0000
+++ b/sql/rpl_slave.cc	2011-03-30 14:11:24 +0000
@@ -143,7 +143,7 @@ failed read"
 };
 
 
-typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL, SLAVE_THD_WORKER, SLAVE_THD_CHECKPOINT } SLAVE_THD_TYPE;
+typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL, SLAVE_THD_CHECKPOINT } SLAVE_THD_TYPE;
 
 static int process_io_rotate(Master_info* mi, Rotate_log_event* rev);
 static int process_io_create_file(Master_info* mi, Create_file_log_event* cev);
@@ -2847,17 +2847,8 @@ int apply_event_and_update_pos(Log_event
       See sql/rpl_rli.h for further details.
     */
     int error= 0;
-    if (skip_event || 
-        (!rli->is_parallel_exec() ||
-         (!rli->curr_group_is_parallel)))
-    {
-      DBUG_ASSERT(skip_event || !rli->is_parallel_exec() ||
-                  (!rli->curr_group_is_parallel ||
-                   rli->curr_event_is_not_in_group) ||
-                  (ev->only_sequential_exec(rli->run_query_in_parallel,
-                                            (rli->curr_group_seen_begin ||
-                                             rli->last_assigned_worker != NULL))
-                   && !rli->curr_group_seen_begin));
+    if (skip_event || !rli->is_parallel_exec() || !rli->curr_group_is_parallel)
+    {
 #ifndef DBUG_OFF
       /*
         This only prints information to the debug trace.
@@ -3056,40 +3047,38 @@ static int exec_relay_log_event(THD* thd
     */
     // if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
     {
-      if ((!rli->is_parallel_exec() ||
-           !rli->curr_group_is_parallel || rli->curr_event_is_not_in_group)
-          && ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
-      {
-        DBUG_ASSERT(!rli->is_parallel_exec() 
-                    ||
-                    (ev->only_sequential_exec(rli->run_query_in_parallel,
-                                              // rli->curr_group_is_parallel
-                                              (rli->curr_group_seen_begin ||
-                                               rli->last_assigned_worker != NULL))
-                     && (!rli->curr_group_seen_begin ||
-                         ev->parallel_exec_by_coordinator(::server_id)))
-                    || (ev->shall_skip(rli) != Log_event::EVENT_SKIP_NOT));
-      /* MTS:  Observation/todo.
-
-         ROWS_QUERY_LOG_EVENT could be supported easier if
-         destructing part of handle_rows_query_log_event would be merged
-         with rli->cleanup_context() and the rest move into 
-         ROWS...::do_apply_event
-      */
-        
-        if (!rli->is_parallel_exec())
-          if (thd->variables.binlog_rows_query_log_events)
-            handle_rows_query_log_event(ev, rli);
+      if ((!rli->is_parallel_exec() || !rli->curr_group_is_parallel))
+      {
+        DBUG_ASSERT(!rli->is_parallel_exec() || !rli->curr_group_is_parallel ||
+                    ev->shall_skip(rli) != Log_event::EVENT_SKIP_NOT);
 
-        if (ev->get_type_code() != ROWS_QUERY_LOG_EVENT)
+        if (rli->curr_group_split)
+        {
+         // the current group split status is reset
+          rli->curr_group_is_parallel= TRUE;
+          rli->curr_group_split= FALSE;
+        }
+        if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
         {
-          DBUG_PRINT("info", ("Deleting the event after it has been executed"));
-          delete ev;
-          ev= NULL;
+          /* MTS/ TODO.
+
+             ROWS_QUERY_LOG_EVENT could be supported easier if
+             destructing part of handle_rows_query_log_event would be merged
+             with rli->cleanup_context() and the rest move into 
+             ROWS...::do_apply_event
+          */
+          if (!rli->is_parallel_exec())
+            if (thd->variables.binlog_rows_query_log_events)
+              handle_rows_query_log_event(ev, rli);
+          
+          if (ev->get_type_code() != ROWS_QUERY_LOG_EVENT)
+          {
+            DBUG_PRINT("info", ("Deleting the event after it has been executed"));
+            delete ev;
+            ev= NULL;
+          }
         }
       }
-      if (rli->curr_event_is_not_in_group)
-        rli->curr_event_is_not_in_group= FALSE;
     }
 
     /*
@@ -3730,14 +3719,13 @@ pthread_handler_t handle_slave_worker(vo
     sql_print_error("Failed during slave worker initialization");
     goto err;
   }
-
   w->info_thd= thd;
   w->w_rli->info_thd= thd;
 
   thd->thread_stack = (char*)&thd;
   
   pthread_detach_this_thread();
-  if (init_slave_thread(thd, SLAVE_THD_WORKER))
+  if (init_slave_thread(thd, SLAVE_THD_SQL))  // todo: make thd->sys_thr= worker
   {
     // todo make SQL thread killed
     sql_print_error("Failed during slave worker initialization");
@@ -3805,6 +3793,11 @@ err:
   {
     mysql_mutex_lock(&LOCK_thread_count);
     THD_CHECK_SENTRY(thd);
+    /*
+      to avoid close_temporary_tables() closing temp tables as those
+      are Coordinator's burden.
+    */
+    thd->system_thread= NON_SYSTEM_THREAD;
     delete thd;
     mysql_mutex_unlock(&LOCK_thread_count);
   }
@@ -3953,7 +3946,6 @@ bool mts_recovery_groups(Relay_log_info 
         DBUG_ASSERT(ev->is_valid());
         DBUG_ASSERT(rli->mts_recovery_group_cnt < rli->checkpoint_group);
 
-        // TODO: relax condition to allow --mts_exp_run_query_in_parallel= 1
         if (ev->starts_group())
           curr_group_seen_begin= TRUE;
         else
@@ -4351,13 +4343,16 @@ int slave_start_workers(Relay_log_info *
   rli->mts_coordinator_basic_nap= ::opt_mts_coordinator_basic_nap;
   rli->mts_worker_underrun_level= ::opt_mts_worker_underrun_level;
   rli->mts_total_groups= 0;
-  rli->curr_group_seen_begin= FALSE; // initial presumtion, will change
-  rli->curr_group_is_parallel= FALSE; // initial presumtion, will change
+  rli->curr_group_seen_begin= FALSE;
+  rli->curr_group_is_parallel= FALSE;
   rli->curr_group_isolated= FALSE;
-  rli->run_query_in_parallel= opt_mts_slave_run_query_in_parallel;
+  rli->curr_group_split= FALSE;
   rli->checkpoint_seqno= 0;
-  rli->curr_event_is_not_in_group= FALSE;
-  //rli->worker_bitmap_buf= my_malloc(n/8 + 1,MYF(MY_WME));
+  /*
+    dyn memory to consume by Coordinator per event
+  */
+  init_alloc_root(&rli->mts_coor_mem_root, NAME_LEN,
+                  (MAX_DBS_IN_QUERY_MTS / 2) * NAME_LEN);
 
   for (i= 0; i < n; i++)
   {
@@ -4450,9 +4445,9 @@ void slave_stop_workers(Relay_log_info *
   delete_dynamic(&rli->least_occupied_workers);    // least occupied
   delete_dynamic(&rli->curr_group_da);             // GCDA
   delete_dynamic(&rli->curr_group_assigned_parts); // GCAP
-  //my_free(rli->worker_bitmap_buf);
   rli->deinit_workers();
   rli->slave_parallel_workers= 0;
+  free_root(&rli->mts_coor_mem_root, MYF(0));
 }
 
 /**
@@ -7115,6 +7110,59 @@ err:
   DBUG_RETURN(ret);
 }
 
+
+/******************************************/
+/*   MTS temporary table support section  */
+
+
+/**
+   @return   a mutex that guards access to the SQL thread controlled
+             temporary tables list.
+*/
+mysql_mutex_t* mts_get_temp_table_mutex()
+{
+  return &active_mi->rli->mts_temp_tables_lock;
+}
+
+/**
+   @return a reference to THD of the Coordinator thread or NULL
+           in case of no replication is set up or it's in the sequential mode.
+*/
+THD* mts_get_coordinator_thd()
+{
+  Slave_worker *w= NULL;
+  return (!active_mi || !active_mi->rli || !active_mi->rli->is_parallel_exec()) ?
+    NULL : !(w= active_mi->rli->get_current_worker()) ?
+    NULL : w->c_rli->info_thd;
+}
+
+/**
+   @return a reference to THD of a Worker thread or NULL
+           in case of no replication is set up or it's in the sequential mode.
+*/
+THD* mts_get_worker_thd()
+{
+  Slave_worker *w= NULL;
+  return (!active_mi || !active_mi->rli || !active_mi->rli->is_parallel_exec()) ?
+    NULL : !(w= active_mi->rli->get_current_worker()) ?
+    NULL : w->w_rli->info_thd;
+}
+
+/**
+   @param  thd a reference to THD
+
+   @return TRUE if thd belongs to a Worker thread and FALSE otherwise.
+*/
+bool mts_is_worker(THD *thd)
+{
+  return
+    thd->slave_thread &&
+    thd->system_thread == SYSTEM_THREAD_SLAVE_SQL &&
+    (mts_get_worker_thd() != NULL);
+}
+
+/* end of MTS temp table support section */
+
 /**
   @} (end of group Replication)
 */

=== modified file 'sql/rpl_slave.h'
--- a/sql/rpl_slave.h	2010-12-27 18:54:41 +0000
+++ b/sql/rpl_slave.h	2011-02-27 17:35:25 +0000
@@ -242,6 +242,10 @@ extern I_List<THD> threads;
 bool mts_recovery_groups(Relay_log_info *rli, MY_BITMAP *groups);
 bool mts_checkpoint_routine(Relay_log_info *rli, ulonglong period,
                             bool force, bool locked);
+THD* mts_get_coordinator_thd();
+THD* mts_get_worker_thd();
+mysql_mutex_t* mts_get_temp_table_mutex();
+bool mts_is_worker(THD *thd);
 
 #endif /* HAVE_REPLICATION */
 

=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2010-12-27 18:54:41 +0000
+++ b/sql/share/errmsg-utf8.txt	2011-02-27 17:35:25 +0000
@@ -6458,3 +6458,5 @@ ER_BINLOG_STMT_CACHE_SIZE_GREATER_THAN_M
 
 ER_NO_FEATURE_ON_PARALLEL_SLAVE
   eng "%s is not supported in Parallel Slave. %s"
+ER_UPDATED_DBS_GREATER_MAX
+  eng "Modified database names number exceeds the maximum %d; the names are not written into the replication event."

=== modified file 'sql/sp.cc'
--- a/sql/sp.cc	2010-12-16 18:18:20 +0000
+++ b/sql/sp.cc	2011-02-27 17:35:25 +0000
@@ -1150,6 +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);
       /* 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(),
@@ -1223,6 +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);
     if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
       ret= SP_INTERNAL_ERROR;
     sp_cache_invalidate();

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2011-01-11 11:45:02 +0000
+++ b/sql/sql_base.cc	2011-02-27 17:35:25 +0000
@@ -40,6 +40,7 @@
 #include "sql_handler.h" // mysql_ha_flush
 #include "sql_partition.h"                      // ALTER_PARTITION_PARAM_TYPE
 #include "log_event.h"                          // Query_log_event
+#include "rpl_slave.h"                          // MTS temp table support
 #include "sql_select.h"
 #include "sp_head.h"
 #include "sp.h"
@@ -58,7 +59,6 @@
 #include <io.h>
 #endif
 
-
 bool
 No_such_table_error_handler::handle_condition(THD *,
                                               uint sql_errno,
@@ -1192,11 +1192,25 @@ bool close_cached_connection_tables(THD 
 
 static void mark_temp_tables_as_free_for_reuse(THD *thd)
 {
-  for (TABLE *table= thd->temporary_tables ; table ; table= table->next)
+#ifndef EMBEDDED_LIBRARY
+  bool mts_slave= mts_is_worker(thd);
+  TABLE *temporary_tables= mts_slave ?
+    mts_get_coordinator_thd()->temporary_tables : thd->temporary_tables;
+  if (mts_slave)
+    mysql_mutex_lock(mts_get_temp_table_mutex());
+#else
+  TABLE *temporary_tables= thd->temporary_tables;
+#endif
+
+  for (TABLE *table= temporary_tables; table ; table=table->next)
   {
     if ((table->query_id == thd->query_id) && ! table->open_by_handler)
       mark_tmp_table_for_reuse(table);
   }
+#ifndef EMBEDDED_LIBRARY
+  if (mts_slave)
+    mysql_mutex_unlock(mts_get_temp_table_mutex());
+#endif
 }
 
 
@@ -1588,6 +1602,8 @@ bool close_temporary_tables(THD *thd)
   bool was_quote_show= TRUE;
   bool error= 0;
 
+  DBUG_ASSERT(!thd->slave_thread || thd->temporary_tables == NULL);
+
   if (!thd->temporary_tables)
     DBUG_RETURN(FALSE);
 
@@ -2025,16 +2041,29 @@ TABLE *find_temporary_table(THD *thd,
                             const char *table_key,
                             uint table_key_length)
 {
-  for (TABLE *table= thd->temporary_tables; table; table= table->next)
+  TABLE *table= NULL;
+#ifndef EMBEDDED_LIBRARY
+  bool mts_slave= mts_is_worker(thd);
+  TABLE *temporary_tables= mts_slave ?
+    mts_get_coordinator_thd()->temporary_tables : thd->temporary_tables;
+  if (mts_slave)
+    mysql_mutex_lock(mts_get_temp_table_mutex());  
+#else
+  TABLE *temporary_tables= thd->temporary_tables;
+#endif
+  for (table= temporary_tables; table; table= table->next)
   {
     if (table->s->table_cache_key.length == table_key_length &&
         !memcmp(table->s->table_cache_key.str, table_key, table_key_length))
     {
-      return table;
+      break;
     }
   }
-
-  return NULL;
+#ifndef EMBEDDED_LIBRARY
+  if (mts_slave)
+    mysql_mutex_unlock(mts_get_temp_table_mutex());
+#endif
+  return table;
 }
 
 
@@ -2072,6 +2101,11 @@ TABLE *find_temporary_table(THD *thd,
 int drop_temporary_table(THD *thd, TABLE_LIST *table_list, bool *is_trans)
 {
   TABLE *table;
+#ifndef EMBEDDED_LIBRARY
+  bool mts_slave= mts_is_worker(thd);
+#endif
+  THD *thd_temp= NULL;
+
   DBUG_ENTER("drop_temporary_table");
   DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'",
                           table_list->db, table_list->table_name));
@@ -2094,7 +2128,26 @@ int drop_temporary_table(THD *thd, TABLE
     unlock the table and remove the table from this list.
   */
   mysql_lock_remove(thd, thd->lock, table);
-  close_temporary_table(thd, table, 1, 1);
+
+#ifndef EMBEDDED_LIBRARY
+  if (mts_slave)
+  {
+    thd_temp= mts_get_coordinator_thd();
+    mysql_mutex_lock(mts_get_temp_table_mutex());
+  }
+  else
+#endif
+  {
+    thd_temp= thd;
+  }
+
+  close_temporary_table(thd_temp, table, 1, 1);
+
+#ifndef EMBEDDED_LIBRARY
+  if (mts_slave)
+     mysql_mutex_unlock(mts_get_temp_table_mutex());
+#endif
+
   DBUG_RETURN(0);
 }
 
@@ -2125,7 +2178,7 @@ void close_temporary_table(THD *thd, TAB
       passing non-zero value to end_slave via rli->save_temporary_tables
       when no temp tables opened, see an invariant below.
     */
-    thd->temporary_tables= table->next;
+    thd->temporary_tables= table->next; // mts: see drop_temporary_table()
     if (thd->temporary_tables)
       table->next->prev= 0;
   }
@@ -2631,7 +2684,17 @@ bool open_table(THD *thd, TABLE_LIST *ta
   if (table_list->open_type != OT_BASE_ONLY &&
       ! (flags & MYSQL_OPEN_SKIP_TEMPORARY))
   {
-    for (table= thd->temporary_tables; table ; table=table->next)
+#ifndef EMBEDDED_LIBRARY
+    bool mts_slave= mts_is_worker(thd);
+    TABLE *temporary_tables= mts_slave ?
+      mts_get_coordinator_thd()->temporary_tables : thd->temporary_tables;
+    if (mts_slave)
+      mysql_mutex_lock(mts_get_temp_table_mutex());
+#else
+    TABLE *temporary_tables= thd->temporary_tables;
+#endif
+
+    for (table= temporary_tables; table ; table=table->next)
     {
       if (table->s->table_cache_key.length == key_length +
           TMP_TABLE_KEY_EXTRA &&
@@ -2651,14 +2714,26 @@ bool open_table(THD *thd, TABLE_LIST *ta
                       (ulong) table->query_id, (uint) thd->server_id,
                       (ulong) thd->variables.pseudo_thread_id));
 	  my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
+#ifndef EMBEDDED_LIBRARY
+          if (mts_slave)
+            mysql_mutex_unlock(mts_get_temp_table_mutex());
+#endif
 	  DBUG_RETURN(TRUE);
 	}
 	table->query_id= thd->query_id;
 	thd->thread_specific_used= TRUE;
         DBUG_PRINT("info",("Using temporary table"));
+#ifndef EMBEDDED_LIBRARY
+        if (mts_slave)
+          mysql_mutex_unlock(mts_get_temp_table_mutex());
+#endif
         goto reset;
       }
     }
+#ifndef EMBEDDED_LIBRARY
+    if (mts_slave)
+      mysql_mutex_unlock(mts_get_temp_table_mutex());
+#endif
   }
 
   if (table_list->open_type == OT_TEMPORARY_ONLY ||
@@ -5851,14 +5926,28 @@ TABLE *open_table_uncached(THD *thd, con
 
   if (add_to_temporary_tables_list)
   {
+#ifndef EMBEDDED_LIBRARY
+    TABLE **ptr_temporary_tables;
+    bool mts_slave= mts_is_worker(thd);
+    ptr_temporary_tables= mts_slave? 
+      &mts_get_coordinator_thd()->temporary_tables : &thd->temporary_tables;
+    if (mts_slave)
+      mysql_mutex_lock(mts_get_temp_table_mutex());
+#else
+    TABLE **ptr_temporary_tables= &thd->temporary_tables;
+#endif
     /* growing temp list at the head */
-    tmp_table->next= thd->temporary_tables;
+    tmp_table->next= *ptr_temporary_tables;
     if (tmp_table->next)
       tmp_table->next->prev= tmp_table;
-    thd->temporary_tables= tmp_table;
-    thd->temporary_tables->prev= 0;
+    *ptr_temporary_tables= tmp_table;
+    (*ptr_temporary_tables)->prev= 0;
     if (thd->slave_thread)
       slave_open_temp_tables++;
+#ifndef EMBEDDED_LIBRARY
+    if (mts_slave)
+       mysql_mutex_unlock(mts_get_temp_table_mutex());
+#endif
   }
   tmp_table->pos_in_table_list= 0;
   DBUG_PRINT("tmptable", ("opened table: '%s'.'%s' 0x%lx", tmp_table->s->db.str,

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2010-12-17 16:14:15 +0000
+++ b/sql/sql_class.cc	2011-02-27 17:35:25 +0000
@@ -503,6 +503,7 @@ THD::THD()
    user_time(0), in_sub_stmt(0),
    binlog_unsafe_warning_flags(0),
    binlog_table_maps(0),
+   binlog_updated_db_names(NULL),
    table_map_for_update(0),
    arg_of_last_insert_id_function(FALSE),
    first_successful_insert_id_in_prev_stmt(0),
@@ -1397,6 +1398,7 @@ void THD::cleanup_after_query()
     stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
     auto_inc_intervals_in_cur_stmt_for_binlog.empty();
     rand_used= 0;
+    binlog_updated_db_names= NULL;
   }
   if (first_successful_insert_id_in_cur_stmt > 0)
   {

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2011-01-11 23:01:02 +0000
+++ b/sql/sql_class.h	2011-02-27 17:35:25 +0000
@@ -1721,6 +1721,11 @@ private:
     transaction cache.
   */
   uint binlog_table_maps;
+  /*
+    MTS: db names listing to be updated by the query databases
+  */
+  List<char> *binlog_updated_db_names;
+
 public:
   void issue_unsafe_warnings();
 
@@ -1730,6 +1735,41 @@ public:
   void clear_binlog_table_maps() {
     binlog_table_maps= 0;
   }
+
+  /*
+    MTS: accessor to binlog_updated_db_names list
+  */
+  List<char> * get_binlog_updated_db_names() {
+    return binlog_updated_db_names;
+  }
+
+  /*
+     MTS: initializer of binlog_updated_db_names list
+  */
+  void set_binlog_updated_db_names(List<char>* arg)
+  {
+    binlog_updated_db_names= arg;
+  }
+
+  /*
+     MTS: resetter of binlog_updated_db_names list normally
+     at the end of the query execution
+  */
+  void clear_binlog_updated_db_names() { binlog_updated_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_updated_db_names(new List<char>);
+    binlog_updated_db_names->push_back(strdup_root(mem_root, db));
+  }
+
 #endif /* MYSQL_CLIENT */
 
 public:

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2010-12-10 12:52:55 +0000
+++ b/sql/sql_db.cc	2011-02-27 17:35:25 +0000
@@ -660,7 +660,7 @@ not_silent:
       */
       qinfo.db     = db;
       qinfo.db_len = strlen(db);
-
+      thd->add_one_db_to_binlog_updated_dbs(db);
       /*
         These DDL methods and logging are protected with the exclusive
         metadata lock on the schema
@@ -964,6 +964,7 @@ update_binlog:
 
     if (query_pos != query_data_start)
     {
+      thd->add_one_db_to_binlog_updated_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	2010-11-18 16:34:56 +0000
+++ b/sql/sql_rename.cc	2011-02-27 17:35:25 +0000
@@ -317,6 +317,14 @@ do_rename(THD *thd, TABLE_LIST *ren_tabl
       my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
       break;
   }
+
+  if (!thd->get_binlog_updated_db_names())
+  {
+    thd->set_binlog_updated_db_names(new List<char>);
+  }
+  thd->add_to_binlog_updated_dbs(ren_table->db);
+  thd->add_to_binlog_updated_dbs(new_db);
+
   if (rc && !skip_error)
     DBUG_RETURN(1);
 

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2010-12-17 18:43:38 +0000
+++ b/sql/sql_table.cc	2011-02-27 17:35:25 +0000
@@ -2236,6 +2236,13 @@ 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_updated_db_names())
+    {
+      thd->set_binlog_updated_db_names(new List<char>);
+    }
+    thd->add_to_binlog_updated_dbs(table->db);
+
     /*
       drop_temporary_table may return one of the following error codes:
       .  0 - a temporary table was successfully dropped.
@@ -4562,7 +4569,10 @@ bool mysql_create_table(THD *thd, TABLE_
       (!thd->is_current_stmt_binlog_format_row() ||
        (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);
     result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans);
+  }
 
 end:
   DBUG_RETURN(result);
@@ -5942,6 +5952,15 @@ bool mysql_alter_table(THD *thd,char *ne
   db=table_list->db;
   if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
     new_db= db;
+
+  if (!thd->get_binlog_updated_db_names())
+  {
+    thd->set_binlog_updated_db_names(new List<char>);
+  }
+  thd->add_to_binlog_updated_dbs(db);
+  if (new_db != db)
+    thd->add_to_binlog_updated_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	2010-11-29 16:27:58 +0000
+++ b/sql/sql_trigger.cc	2011-02-27 17:35:25 +0000
@@ -521,6 +521,8 @@ bool mysql_create_or_drop_trigger(THD *t
 end:
   if (!result)
   {
+    if (tables)
+      thd->add_one_db_to_binlog_updated_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	2010-12-14 11:15:13 +0000
+++ b/sql/sql_view.cc	2011-02-27 17:35:25 +0000
@@ -689,6 +689,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);
     if (thd->binlog_query(THD::STMT_QUERY_TYPE,
                           buff.ptr(), buff.length(), FALSE, FALSE, FALSE, errcode))
       res= TRUE;
@@ -1682,6 +1683,11 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
       }
       continue;
     }
+    if (!thd->get_binlog_updated_db_names())
+    {
+      thd->set_binlog_updated_db_names(new List<char>);
+    }
+    thd->add_to_binlog_updated_dbs(view->db);
     if (mysql_file_delete(key_file_frm, path, MYF(MY_WME)))
       error= TRUE;
 

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2011-01-11 23:01:02 +0000
+++ b/sql/sys_vars.cc	2011-02-27 17:35:25 +0000
@@ -3198,12 +3198,6 @@ static Sys_var_mybool Sys_slave_local_ti
        "time value to implicitly affected timestamp columms. Otherwise (default) "
        "it installs prescribed by the master value",
        GLOBAL_VAR(opt_mts_slave_local_timestamp), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
-static Sys_var_mybool Sys_slave_run_query_in_parallel(
-       "mts_exp_slave_run_query_in_parallel",
-       "The default not an actual database name is used as partition info "
-       "for parallel execution of Query_log_event ",
-       GLOBAL_VAR(opt_mts_slave_run_query_in_parallel), CMD_LINE(OPT_ARG),
-       DEFAULT(FALSE));
 static Sys_var_ulong Sys_mts_partition_hash_soft_max(
        "mts_partition_hash_soft_max",
        "Number of records in the mts partition hash below which "


Attachment: [text/bzr-bundle] bzr/andrei.elkin@oracle.com-20110402113202-65e12tpteebi39g3.bundle
Thread
bzr push into mysql-next-mr-wl5569 branch (andrei.elkin:3269 to 3272) WL#5569Andrei Elkin2 Apr