From: Andrei Elkin Date: February 27 2011 5:20pm Subject: bzr commit into mysql-next-mr-wl5569 branch (andrei.elkin:3271) WL#5754 List-Archive: http://lists.mysql.com/commits/132081 Message-Id: <201102271720.p1RHKhfa022431@mysql1000.dsl.inet.fi> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1144996275==" --===============1144996275== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/andrei/MySQL/BZR/2a-23May/WL/mysql-next-mr-wl5569/ based on revid:andrei.elkin@stripped 3271 Andrei Elkin 2011-02-27 wl#5754 Query parallel execution The last review mail issues are addressed. @ mysql-test/r/mysqld--help-notwin.result results gets updated. @ mysql-test/suite/rpl/t/rpl_parallel_ddl.test added remained DDL set members to test. @ sql/binlog.cc Comments are added, other changes are due to MAX_DBS_IN_QUERY_MTS + 1 ceased to be the over-max mark. @ sql/field.cc improved comments. @ sql/log_event.cc 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 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.h A memroot for the Coordiator is placed into rli. @ sql/rpl_slave.cc 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/sql_base.cc simplified the temp table support related addons. The double ref to thd->temporary_table is needed only in one place. @ sql/sql_class.cc removed dead-comments. @ sql/sql_class.h added more comments, removed dead-codes. @ sql/sql_view.cc support for CREATE/DROP views is added. @ sql/sys_vars.cc removed ealier added variable. modified: mysql-test/r/mysqld--help-notwin.result mysql-test/suite/rpl/t/rpl_parallel_ddl.test sql/binlog.cc sql/field.cc sql/log_event.cc sql/log_event.h sql/mysqld.cc sql/mysqld.h sql/rpl_rli.h sql/rpl_slave.cc sql/rpl_slave.h sql/sql_base.cc sql/sql_class.cc sql/sql_class.h sql/sql_view.cc sql/sys_vars.cc === modified file 'mysql-test/r/mysqld--help-notwin.result' --- a/mysql-test/r/mysqld--help-notwin.result 2011-02-21 15:43:57 +0000 +++ b/mysql-test/r/mysqld--help-notwin.result 2011-02-27 17:20:32 +0000 @@ -362,10 +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-master-updated-dbs-max=# - The maximum number of databases that a query log event - can contain in its header in order to faciliate the - parallel applying on the slave. --mts-partition-hash-soft-max=# Number of records in the mts partition hash below which entries with zero usage are tolerated @@ -911,7 +907,6 @@ mts-checkpoint-group 512 mts-checkpoint-period 300 mts-coordinator-basic-nap 5 mts-exp-slave-local-timestamp FALSE -mts-master-updated-dbs-max 16 mts-partition-hash-soft-max 16 mts-pending-jobs-size-max 16777216 mts-slave-parallel-workers 0 === modified file 'mysql-test/suite/rpl/t/rpl_parallel_ddl.test' --- a/mysql-test/suite/rpl/t/rpl_parallel_ddl.test 2011-02-21 15:43:57 +0000 +++ b/mysql-test/suite/rpl/t/rpl_parallel_ddl.test 2011-02-27 17:20:32 +0000 @@ -19,6 +19,8 @@ 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`; @@ -126,6 +128,22 @@ while ($n1) 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 === modified file 'sql/binlog.cc' --- a/sql/binlog.cc 2011-02-21 15:43:57 +0000 +++ b/sql/binlog.cc 2011-02-27 17:20:32 +0000 @@ -4537,12 +4537,17 @@ 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 + 1) + 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, @@ -4782,7 +4787,6 @@ int THD::decide_logging_format(TABLE_LIS prev_write_table= table->table; } - flags_access_some_set |= flags; if (lex->sql_command != SQLCOM_CREATE_TABLE || === modified file 'sql/field.cc' --- a/sql/field.cc 2011-02-21 15:43:57 +0000 +++ b/sql/field.cc 2011-02-27 17:20:32 +0000 @@ -3737,9 +3737,8 @@ longlong Field_long::val_int(void) int32 j; /* See the comment in Field_long::store(long long) */ /* - About (current_thd)->slave_thread alternative, - MTS coordinator open/closes a temp table while the rest of operation - is done by Workers. + 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); === modified file 'sql/log_event.cc' --- a/sql/log_event.cc 2011-02-21 15:43:57 +0000 +++ b/sql/log_event.cc 2011-02-27 17:20:32 +0000 @@ -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; @@ -2479,11 +2479,11 @@ Slave_worker *Log_event::get_slave_worke } } - // g + // mini-group representative if (contains_partition_info()) { - List_iterator it(*mts_get_dbs()); + List_iterator it(*mts_get_dbs(rli->info_thd->mem_root)); it++; do @@ -2500,25 +2500,32 @@ Slave_worker *Log_event::get_slave_worke DBUG_ASSERT(g.group_relay_log_name == NULL); } - } while (it++ && mts_number_dbs() != MAX_DBS_IN_QUERY_MTS + 1); + } while (mts_number_dbs() != OVER_MAX_DBS_IN_QUERY_MTS && it++); + + // 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(rli)->curr_group_da, (uchar*) &ptr_curr_ev); @@ -2526,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; @@ -2535,8 +2542,6 @@ Slave_worker *Log_event::get_slave_worke (Slave_job_group *) dynamic_array_ptr(&rli->gaq->Q, rli->gaq->assigned_group_index); - if (!rli->curr_group_is_parallel) - sleep(1000); DBUG_ASSERT(rli->curr_group_is_parallel); // TODO: throw an error when relay-log reading starts from inside of a group!! @@ -2818,11 +2823,20 @@ int Log_event::apply_event(Relay_log_inf { if (parallel) { + // 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)) { - // current isn't group split and therefore requires Workers to sync + // 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); + // 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); } @@ -2830,6 +2844,9 @@ int Log_event::apply_event(Relay_log_inf { if (rli->curr_group_is_parallel) { + // 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; } @@ -2989,7 +3006,7 @@ int slave_worker_exec_job(Slave_worker * { if (ev->contains_partition_info()) { - List_iterator it(*ev->mts_get_dbs()); + List_iterator it(*ev->mts_get_dbs(thd->mem_root)); DYNAMIC_ARRAY *ep= &(w->curr_group_exec_parts->dynamic_ids); while (it++) @@ -3095,7 +3112,10 @@ err: if (ev && ev->get_type_code() != ROWS_QUERY_LOG_EVENT) delete ev; // after ev->update_pos() event is garbage - free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC)); + // thd->mem_root of the Worker is engaged either + // inside of the event execution or for holding the updated db:s list. + // It's safe to release it now mem-root now when the applying is over and + // the updated dbs won't be in use any longer. DBUG_RETURN(error); } @@ -3367,20 +3387,24 @@ bool Query_log_event::write(IO_CACHE* fi { uchar dbs; *start++= Q_UPDATED_DB_NAMES; - dbs= *start++= thd->get_binlog_updated_db_names()->elements; - DBUG_ASSERT(dbs != 0); + compile_time_assert(MAX_DBS_IN_QUERY_MTS <= OVER_MAX_DBS_IN_QUERY_MTS); + /* - MAX_DBS_IN_QUERY_MTS + 1 is special no db:s is written - and event requires the sequential applying on slave. + 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. */ - if (dbs != MAX_DBS_IN_QUERY_MTS + 1) + 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 it(*thd->get_binlog_updated_db_names()); char *db_name; - DBUG_ASSERT(dbs <= MAX_DBS_IN_QUERY_MTS); - while ((db_name= it++)) { strcpy((char*) start, db_name); @@ -3713,7 +3737,7 @@ Query_log_event::Query_log_event(const c auto_increment_increment(1), auto_increment_offset(1), time_zone_len(0), lc_time_names_number(0), charset_database_number(0), table_map_for_update(0), master_data_written(0), - mts_updated_dbs(MAX_DBS_IN_QUERY_MTS + 1) + mts_updated_dbs(OVER_MAX_DBS_IN_QUERY_MTS) { ulong data_len; uint32 tmp; @@ -3721,7 +3745,6 @@ Query_log_event::Query_log_event(const c Log_event::Byte *start; const Log_event::Byte *end; bool catalog_nz= 1; - DBUG_ENTER("Query_log_event::Query_log_event(char*,...)"); memset(&user, 0, sizeof(user)); @@ -3899,8 +3922,16 @@ Query_log_event::Query_log_event(const c { CHECK_SPACE(pos, end, 1); mts_updated_dbs= *pos++; - if (mts_updated_dbs == MAX_DBS_IN_QUERY_MTS + 1) + /* + 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); === modified file 'sql/log_event.h' --- a/sql/log_event.h 2011-02-21 15:43:57 +0000 +++ b/sql/log_event.h 2011-02-27 17:20:32 +0000 @@ -259,12 +259,16 @@ struct sql_ex_info #define HEARTBEAT_HEADER_LEN 0 #define IGNORABLE_HEADER_LEN 0 -/** - The maximum value for @@global.mts_max_updated_dbs server variable. - When the actual number of db:s exceeds @@global.mts_max_updated_dbs, the max + 1 - is put into the mts_updated_dbs status. +/* + 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 @@ -355,8 +359,9 @@ struct sql_ex_info #define Q_INVOKER 11 /* - Number of the updated db:s and their names to be propagated to the slave - in order to facilitate the parallel applying of the Query events + 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 @@ -1090,14 +1095,18 @@ public: The method returns a list of updated by the event databases. Other than in the case of Query-log-event the list is just one item. */ - virtual List* mts_get_dbs() + virtual List* mts_get_dbs(MEM_ROOT *mem_root) { List *res= new List; - res->push_back(strdup(get_db())); + res->push_back(strdup_root(mem_root, get_db())); return res; } - virtual uchar mts_number_dbs() { return 1; } + /* + 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) {} @@ -1220,13 +1229,9 @@ public: #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) public: - virtual uchar mts_number_of_updated_dbs() { return 1; } - /** MST: to execute serially due to technical or conceptual limitation - TODO: add version of the server check to fall back to seq in the OM case. - @return TRUE if despite permanent parallel execution mode an event needs applying in a real isolation that is sequentially. */ @@ -1240,7 +1245,7 @@ public: */ (get_type_code() == QUERY_EVENT && !starts_group() && !ends_group() && - (mts_number_of_updated_dbs() == MAX_DBS_IN_QUERY_MTS + 1)) || + (mts_number_dbs() == OVER_MAX_DBS_IN_QUERY_MTS)) || get_type_code() == START_EVENT_V3 || get_type_code() == STOP_EVENT || @@ -1895,11 +1900,10 @@ public: 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* mts_get_dbs() + virtual List* mts_get_dbs(MEM_ROOT *mem_root) { - //compile_time_assert(mts_updated_dbs <= MAX_DBS_IN_QUERY_MTS + 1); - List *res= new List; - if (mts_updated_dbs == MAX_DBS_IN_QUERY_MTS + 1) + List *res= new (mem_root) List; + 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++) @@ -4365,12 +4369,6 @@ bool event_checksum_test(uchar *buf, ulo uint8 get_checksum_alg(const char* buf, ulong len); extern TYPELIB binlog_checksum_typelib; -// MTS temp table support needed by sql_base.cc -THD* mts_get_coordinator_thd(); -THD* mts_get_worker_thd(); -mysql_mutex_t* mts_get_temp_table_mutex(); -bool mts_is_worker(THD *thd); - /** @} (end of group Replication) */ === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2011-02-21 15:43:57 +0000 +++ b/sql/mysqld.cc 2011-02-27 17:20:32 +0000 @@ -472,7 +472,6 @@ ulong opt_mts_partition_hash_soft_max; ulonglong opt_mts_pending_jobs_size_max; ulong opt_mts_coordinator_basic_nap; ulong opt_mts_worker_underrun_level; -ulong opt_mts_master_updated_dbs_max; ulong thread_cache_size=0; ulong binlog_cache_size=0; ulonglong max_binlog_cache_size=0; === modified file 'sql/mysqld.h' --- a/sql/mysqld.h 2011-02-21 15:43:57 +0000 +++ b/sql/mysqld.h 2011-02-27 17:20:32 +0000 @@ -186,7 +186,6 @@ extern ulong opt_mts_partition_hash_soft extern ulonglong opt_mts_pending_jobs_size_max; extern ulong opt_mts_coordinator_basic_nap; extern ulong opt_mts_worker_underrun_level; -extern ulong opt_mts_master_updated_dbs_max; extern uint max_user_connections; extern ulong what_to_log,flush_time; === modified file 'sql/rpl_rli.h' --- a/sql/rpl_rli.h 2011-02-21 15:43:57 +0000 +++ b/sql/rpl_rli.h 2011-02-27 17:20:32 +0000 @@ -482,7 +482,10 @@ public: 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); === modified file 'sql/rpl_slave.cc' --- a/sql/rpl_slave.cc 2011-02-21 15:43:57 +0000 +++ b/sql/rpl_slave.cc 2011-02-27 17:20:32 +0000 @@ -3052,8 +3052,9 @@ static int exec_relay_log_event(THD* thd DBUG_ASSERT(!rli->is_parallel_exec() || !rli->curr_group_is_parallel || ev->shall_skip(rli) != Log_event::EVENT_SKIP_NOT); - if (rli->curr_group_split) // an artifical FD requires some handling + if (rli->curr_group_split) { + // the current group split status is reset rli->curr_group_is_parallel= TRUE; rli->curr_group_split= FALSE; } @@ -4345,7 +4346,11 @@ int slave_start_workers(Relay_log_info * rli->curr_group_isolated= FALSE; rli->curr_group_split= FALSE; rli->checkpoint_seqno= 0; - //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++) { @@ -4438,9 +4443,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)); } /** @@ -7104,29 +7109,48 @@ err: } -/* MTS temp table support */ +/******************************************/ +/* 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; + 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; + 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 @@ -7135,6 +7159,8 @@ bool mts_is_worker(THD *thd) (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:20:32 +0000 @@ -242,6 +242,10 @@ extern I_List 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/sql_base.cc' --- a/sql/sql_base.cc 2011-02-21 15:43:57 +0000 +++ b/sql/sql_base.cc 2011-02-27 17:20:32 +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" @@ -1193,15 +1194,15 @@ static void mark_temp_tables_as_free_for { #ifndef EMBEDDED_LIBRARY bool mts_slave= mts_is_worker(thd); - TABLE **ptr_temporary_tables= mts_slave ? - &mts_get_coordinator_thd()->temporary_tables : &thd->temporary_tables; + 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 **ptr_temporary_tables= &thd->temporary_tables; + TABLE *temporary_tables= thd->temporary_tables; #endif - for (TABLE *table= *ptr_temporary_tables; table ; table=table->next) + 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); @@ -1601,7 +1602,7 @@ bool close_temporary_tables(THD *thd) bool was_quote_show= TRUE; bool error= 0; - /* TODO mts: assert if Woker then thd->temporary_tables == NULL */ + DBUG_ASSERT(!thd->slave_thread || thd->temporary_tables == NULL); if (!thd->temporary_tables) DBUG_RETURN(FALSE); @@ -2043,14 +2044,14 @@ TABLE *find_temporary_table(THD *thd, TABLE *table= NULL; #ifndef EMBEDDED_LIBRARY bool mts_slave= mts_is_worker(thd); - TABLE **ptr_temporary_tables= mts_slave ? - &mts_get_coordinator_thd()->temporary_tables : &thd->temporary_tables; + 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 **ptr_temporary_tables= &thd->temporary_tables; + TABLE *temporary_tables= thd->temporary_tables; #endif - for (table= *ptr_temporary_tables; table; table= table->next) + 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)) @@ -2103,7 +2104,7 @@ int drop_temporary_table(THD *thd, TABLE #ifndef EMBEDDED_LIBRARY bool mts_slave= mts_is_worker(thd); #endif - THD *thd_temp; + THD *thd_temp= NULL; DBUG_ENTER("drop_temporary_table"); DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'", @@ -2685,15 +2686,15 @@ bool open_table(THD *thd, TABLE_LIST *ta { #ifndef EMBEDDED_LIBRARY bool mts_slave= mts_is_worker(thd); - TABLE **ptr_temporary_tables= mts_slave ? - &mts_get_coordinator_thd()->temporary_tables : &thd->temporary_tables; + 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 **ptr_temporary_tables= &thd->temporary_tables; + TABLE *temporary_tables= thd->temporary_tables; #endif - for (table= *ptr_temporary_tables; table ; table=table->next) + for (table= temporary_tables; table ; table=table->next) { if (table->s->table_cache_key.length == key_length + TMP_TABLE_KEY_EXTRA && === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2011-02-21 15:43:57 +0000 +++ b/sql/sql_class.cc 2011-02-27 17:20:32 +0000 @@ -3396,7 +3396,6 @@ void THD::reset_sub_statement_state(Sub_ first_successful_insert_id_in_prev_stmt; backup->first_successful_insert_id_in_cur_stmt= first_successful_insert_id_in_cur_stmt; - //backup->binlog_updated_db_names= binlog_updated_db_names; if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) && !is_current_stmt_binlog_format_row()) @@ -3417,7 +3416,6 @@ void THD::reset_sub_statement_state(Sub_ cuted_fields= 0; transaction.savepoints= 0; first_successful_insert_id_in_cur_stmt= 0; - //binlog_updated_db_names= NULL; } @@ -3480,8 +3478,6 @@ void THD::restore_sub_statement_state(Su */ examined_row_count+= backup->examined_row_count; cuted_fields+= backup->cuted_fields; - //if (binlog_updated_db_names) - // binlog_updated_db_names->concat(backup->binlog_updated_db_names); DBUG_VOID_RETURN; } === modified file 'sql/sql_class.h' --- a/sql/sql_class.h 2011-02-21 15:43:57 +0000 +++ b/sql/sql_class.h 2011-02-27 17:20:32 +0000 @@ -1184,7 +1184,6 @@ public: bool last_insert_id_used; SAVEPOINT *savepoints; enum enum_check_fields count_cuted_fields; - //List *binlog_updated_db_names; }; @@ -1738,17 +1737,33 @@ public: } /* - MTS: collection of methods to operate on binlog_updated_db_names + MTS: accessor to binlog_updated_db_names list */ List * 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* 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); === 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:20:32 +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); + } + 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-02-21 15:43:57 +0000 +++ b/sql/sys_vars.cc 2011-02-27 17:20:32 +0000 @@ -3198,13 +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_ulong Sys_master_updated_dbs_max( - "mts_master_updated_dbs_max", - "The maximum number of databases that a query log event can contain in its header " - "in order to faciliate the parallel applying on the slave.", - GLOBAL_VAR(opt_mts_master_updated_dbs_max), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, MAX_DBS_IN_QUERY_MTS), - DEFAULT(16), BLOCK_SIZE(1)); 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 " --===============1144996275== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/andrei.elkin@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: andrei.elkin@stripped # target_branch: file:///home/andrei/MySQL/BZR/2a-23May/WL/mysql-next-\ # mr-wl5569/ # testament_sha1: 88e030038a884156db039aa25ac4945cd3dcaaf9 # timestamp: 2011-02-27 19:20:43 +0200 # source_branch: file:///home/andrei/MySQL/BZR/2a-23May/mysql-trunk/ # base_revision_id: andrei.elkin@stripped\ # u33nra68prp9y3uw # # Begin bundle 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 0P/xdyRThQkGLYPhAA== --===============1144996275==--