List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:February 27 2011 5:20pm
Subject:bzr commit into mysql-next-mr-wl5569 branch (andrei.elkin:3271) WL#5754
View as plain text  
#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<char> it(*mts_get_dbs());
+    List_iterator<char> 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<Relay_log_info*>(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<char> it(*ev->mts_get_dbs());
+      List_iterator<char> 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<char> 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<char>* mts_get_dbs()
+  virtual List<char>* mts_get_dbs(MEM_ROOT *mem_root)
   {
     List<char> *res= new List<char>;
-    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<char>* mts_get_dbs()
+  virtual List<char>* mts_get_dbs(MEM_ROOT *mem_root)
   {
-    //compile_time_assert(mts_updated_dbs <= MAX_DBS_IN_QUERY_MTS + 1);
-    List<char> *res= new List<char>;
-    if (mts_updated_dbs == MAX_DBS_IN_QUERY_MTS + 1)
+    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++)
@@ -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<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/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<char> *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<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>);

=== 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<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-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 "


Attachment: [text/bzr-bundle] bzr/andrei.elkin@oracle.com-20110227172032-d40unx5ouud1ds9y.bundle
Thread
bzr commit into mysql-next-mr-wl5569 branch (andrei.elkin:3271) WL#5754Andrei Elkin27 Feb