List:Commits« Previous MessageNext Message »
From:Jonas Oreland Date:September 15 2010 6:26pm
Subject:bzr commit into mysql-5.1-telco-6.3 branch (jonas:3295)
View as plain text  
#At file:///home/jonas/src/telco-6.3/ based on revid:frazer@stripped

 3295 Jonas Oreland	2010-09-15
      ndb - fix race in ndb_multi, add more extra-logging printouts add assert if schema distribution times out (debug)

    modified:
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      sql/ha_ndbcluster_binlog.cc
      sql/handler.cc
      sql/handler.h
      sql/sql_table.cc
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2010-09-14 15:32:39 +0000
+++ b/sql/ha_ndbcluster.cc	2010-09-15 18:26:11 +0000
@@ -8854,9 +8854,20 @@ static void ndbcluster_drop_database(han
   ndbcluster_drop_database_impl(thd, path);
   char db[FN_REFLEN];
   ha_ndbcluster::set_dbname(path, db);
+  uint32 table_id= 0, table_version= 0;
+  /*
+    Since databases aren't real ndb schema object
+    they don't have any id/version
+
+    But since that id/version is used to make sure that event's on SCHEMA_TABLE
+    is correct, we set random numbers
+  */
+  table_id = (uint32)rand();
+  table_version = (uint32)rand();
   ndbcluster_log_schema_op(thd,
                            thd->query(), thd->query_length(),
-                           db, "", 0, 0, SOT_DROP_DB, 0, 0, 0);
+                           db, "", table_id, table_version,
+                           SOT_DROP_DB, 0, 0, 0);
   DBUG_VOID_RETURN;
 }
 
@@ -12716,42 +12727,84 @@ int ha_ndbcluster::alter_table_phase2(TH
     /* ndb_share reference schema free */
     DBUG_PRINT("NDB_SHARE", ("%s binlog schema free  use_count: %u",
                              m_share->key, m_share->use_count));
+    delete alter_data;
+    alter_info->data= 0;
   }
   set_ndb_share_state(m_share, NSS_INITIAL);
   free_share(&m_share); // Decrease ref_count
-  delete alter_data;
   DBUG_RETURN(error);
 }
 
-int ha_ndbcluster::alter_table_phase3(THD *thd, TABLE *table)
+int ha_ndbcluster::alter_table_phase3(THD *thd, TABLE *table,
+                                      HA_CREATE_INFO *create_info,
+                                      HA_ALTER_INFO *alter_info,
+                                      HA_ALTER_FLAGS *alter_flags)
 {
   DBUG_ENTER("alter_table_phase3");
 
+  NDB_ALTER_DATA *alter_data= (NDB_ALTER_DATA *) alter_info->data;
   if (!ndbcluster_has_global_schema_lock(get_thd_ndb(thd)))
+  {
+    delete alter_data;
+    alter_info->data= 0;
     DBUG_RETURN(ndbcluster_no_global_schema_lock_abort
                 (thd, "ha_ndbcluster::alter_table_phase3"));
+  }
 
   const char *db= table->s->db.str;
   const char *name= table->s->table_name.str;
+
   /*
     all mysqld's will read frms from disk and setup new
     event operation for the table (new_op)
   */
+  uint32 table_id= 0, table_version= 0;
+  DBUG_ASSERT(alter_data != 0);
+  if (alter_data)
+  {
+    table_id= alter_data->table_id;
+    table_version= alter_data->old_table_version;
+  }
   ndbcluster_log_schema_op(thd, thd->query(), thd->query_length(),
                            db, name,
-                           0, 0,
+                           table_id, table_version,
                            SOT_ONLINE_ALTER_TABLE_PREPARE,
                            0, 0, 0);
+
+  /*
+    Get table id/version for new table
+  */
+  table_id= 0;
+  table_version= 0;
+  {
+    Ndb* ndb= get_ndb(thd);
+    DBUG_ASSERT(ndb != 0);
+    if (ndb)
+    {
+      ndb->setDatabaseName(db);
+      Ndb_table_guard ndbtab(ndb->getDictionary(), name);
+      const NDBTAB *new_tab= ndbtab.get_table();
+      DBUG_ASSERT(new_tab != 0);
+      if (new_tab)
+      {
+        table_id= new_tab->getObjectId();
+        table_version= new_tab->getObjectVersion();
+      }
+    }
+  }
+
   /*
     all mysqld's will switch to using the new_op, and delete the old
     event operation
   */
   ndbcluster_log_schema_op(thd, thd->query(), thd->query_length(),
                            db, name,
-                           0, 0,
+                           table_id, table_version,
                            SOT_ONLINE_ALTER_TABLE_COMMIT,
                            0, 0, 0);
 
+  delete alter_data;
+  alter_info->data= 0;
   DBUG_RETURN(0);
 }
 
@@ -12815,6 +12868,7 @@ int ndbcluster_alter_tablespace(handlert
   }
   dict= ndb->getDictionary();
 
+  uint32 table_id= 0, table_version= 0;
   switch (alter_info->ts_cmd_type){
   case (CREATE_TABLESPACE):
   {
@@ -12837,6 +12891,8 @@ int ndbcluster_alter_tablespace(handlert
       DBUG_PRINT("error", ("createTablespace returned %d", error));
       goto ndberror;
     }
+    table_id = objid.getObjectId();
+    table_version = objid.getObjectVersion();
     if (dict->getWarningFlags() &
         NdbDictionary::Dictionary::WarnExtentRoundUp)
     {
@@ -12889,10 +12945,13 @@ int ndbcluster_alter_tablespace(handlert
 	DBUG_RETURN(1);
       }
       errmsg= " CREATE DATAFILE";
-      if (dict->createDatafile(ndb_df))
+      NdbDictionary::ObjectId objid;
+      if (dict->createDatafile(ndb_df, &objid))
       {
 	goto ndberror;
       }
+      table_id= objid.getObjectId();
+      table_version= objid.getObjectVersion();
       if (dict->getWarningFlags() &
           NdbDictionary::Dictionary::WarnDatafileRoundUp)
       {
@@ -12915,6 +12974,8 @@ int ndbcluster_alter_tablespace(handlert
       NdbDictionary::Datafile df= dict->getDatafile(0, alter_info->data_file_name);
       NdbDictionary::ObjectId objid;
       df.getTablespaceId(&objid);
+      table_id = df.getObjectId();
+      table_version = df.getObjectVersion();
       if (ts.getObjectId() == objid.getObjectId() && 
 	  strcmp(df.getPath(), alter_info->data_file_name) == 0)
       {
@@ -12962,6 +13023,8 @@ int ndbcluster_alter_tablespace(handlert
     {
       goto ndberror;
     }
+    table_id = objid.getObjectId();
+    table_version = objid.getObjectVersion();
     if (dict->getWarningFlags() &
         NdbDictionary::Dictionary::WarnUndobufferRoundUp)
     {
@@ -13012,10 +13075,13 @@ int ndbcluster_alter_tablespace(handlert
       DBUG_RETURN(1);
     }
     errmsg= "CREATE UNDOFILE";
-    if (dict->createUndofile(ndb_uf))
+    NdbDictionary::ObjectId objid;
+    if (dict->createUndofile(ndb_uf, &objid))
     {
       goto ndberror;
     }
+    table_id = objid.getObjectId();
+    table_version = objid.getObjectVersion();
     if (dict->getWarningFlags() &
         NdbDictionary::Dictionary::WarnUndofileRoundDown)
     {
@@ -13029,7 +13095,11 @@ int ndbcluster_alter_tablespace(handlert
   {
     error= ER_DROP_FILEGROUP_FAILED;
     errmsg= "TABLESPACE";
-    if (dict->dropTablespace(dict->getTablespace(alter_info->tablespace_name)))
+    NdbDictionary::Tablespace ts=
+      dict->getTablespace(alter_info->tablespace_name);
+    table_id= ts.getObjectId();
+    table_version= ts.getObjectVersion();
+    if (dict->dropTablespace(ts))
     {
       goto ndberror;
     }
@@ -13040,7 +13110,11 @@ int ndbcluster_alter_tablespace(handlert
   {
     error= ER_DROP_FILEGROUP_FAILED;
     errmsg= "LOGFILE GROUP";
-    if (dict->dropLogfileGroup(dict->getLogfileGroup(alter_info->logfile_group_name)))
+    NdbDictionary::LogfileGroup lg=
+      dict->getLogfileGroup(alter_info->logfile_group_name);
+    table_id= lg.getObjectId();
+    table_version= lg.getObjectVersion();
+    if (dict->dropLogfileGroup(lg))
     {
       goto ndberror;
     }
@@ -13063,13 +13137,13 @@ int ndbcluster_alter_tablespace(handlert
     ndbcluster_log_schema_op(thd,
                              thd->query(), thd->query_length(),
                              "", alter_info->tablespace_name,
-                             0, 0,
+                             table_id, table_version,
                              SOT_TABLESPACE, 0, 0, 0);
   else
     ndbcluster_log_schema_op(thd,
                              thd->query(), thd->query_length(),
                              "", alter_info->logfile_group_name,
-                             0, 0,
+                             table_id, table_version,
                              SOT_LOGFILE_GROUP, 0, 0, 0);
   DBUG_RETURN(FALSE);
 

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2010-09-14 15:32:39 +0000
+++ b/sql/ha_ndbcluster.h	2010-09-15 18:26:11 +0000
@@ -108,13 +108,17 @@ public:
 		 const NdbDictionary::Table *table) :
     dictionary(dict),
     old_table(table),
-    new_table(new NdbDictionary::Table(*table))
+    new_table(new NdbDictionary::Table(*table)),
+      table_id(table->getObjectId()),
+      old_table_version(table->getObjectVersion())
   {}
   ~NDB_ALTER_DATA()
   { delete new_table; }
   NdbDictionary::Dictionary *dictionary;
   const  NdbDictionary::Table *old_table;
   NdbDictionary::Table *new_table;
+  Uint32 table_id;
+  Uint32 old_table_version;
 };
 
 typedef union { const NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue;
@@ -572,7 +576,10 @@ static void set_tabname(const char *path
                          HA_ALTER_INFO *alter_info,
                          HA_ALTER_FLAGS *alter_flags);
 
-  int alter_table_phase3(THD *thd, TABLE *table);
+  int alter_table_phase3(THD *thd, TABLE *table,
+                         HA_CREATE_INFO *create_info,
+                         HA_ALTER_INFO *alter_info,
+                         HA_ALTER_FLAGS *alter_flags);
 
 private:
 #ifdef HAVE_NDB_BINLOG

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2010-09-14 10:58:58 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2010-09-15 18:26:11 +0000
@@ -142,6 +142,8 @@ typedef struct st_ndb_schema_object {
   uint use_count;
   MY_BITMAP slock_bitmap;
   uint32 slock[256/32]; // 256 bits for lock status of table
+  uint32 table_id;
+  uint32 table_version;
 } NDB_SCHEMA_OBJECT;
 static NDB_SCHEMA_OBJECT *ndb_get_schema_object(const char *key,
                                                 my_bool create_if_not_exists,
@@ -672,6 +674,16 @@ ndbcluster_binlog_log_query(handlerton *
                        db, table_name, query));
   enum SCHEMA_OP_TYPE type;
   int log= 0;
+  uint32 table_id= 0, table_version= 0;
+  /*
+    Since databases aren't real ndb schema object
+    they don't have any id/version
+
+    But since that id/version is used to make sure that event's on SCHEMA_TABLE
+    is correct, we set random numbers
+  */
+  table_id = (uint32)rand();
+  table_version = (uint32)rand();
   switch (binlog_command)
   {
   case LOGCOM_CREATE_TABLE:
@@ -706,7 +718,7 @@ ndbcluster_binlog_log_query(handlerton *
   if (log)
   {
     ndbcluster_log_schema_op(thd, query, query_length,
-                             db, table_name, 0, 0, type,
+                             db, table_name, table_id, table_version, type,
                              0, 0, 0);
   }
   DBUG_VOID_RETURN;
@@ -941,6 +953,10 @@ static int ndbcluster_global_schema_lock
 
   if (thd_ndb->global_schema_lock_trans)
   {
+    if (ndb_extra_logging > 19)
+    {
+      sql_print_information("NDB: Global schema lock acquired");
+    }
     DBUG_RETURN(0);
   }
 
@@ -1005,6 +1021,10 @@ static int ndbcluster_global_schema_unlo
                           "ndb. Releasing global schema lock");
       DBUG_RETURN(-1);
     }
+    if (ndb_extra_logging > 19)
+    {
+      sql_print_information("NDB: Global schema lock release");
+    }
   }
   DBUG_RETURN(0);
 }
@@ -1670,7 +1690,9 @@ char *ndb_pack_varchar(const NDBCOL *col
 static int
 ndbcluster_update_slock(THD *thd,
                         const char *db,
-                        const char *table_name)
+                        const char *table_name,
+                        uint32 table_id,
+                        uint32 table_version)
 {
   DBUG_ENTER("ndbcluster_update_slock");
   if (!ndb_schema_share)
@@ -1749,7 +1771,23 @@ ndbcluster_update_slock(THD *thd,
     if (trans->execute(NdbTransaction::NoCommit))
       goto err;
 
-    bitmap_clear_bit(&slock, node_id);
+    if (ndb_extra_logging > 19)
+    {
+      uint32 copy[SCHEMA_SLOCK_SIZE/4];
+      memcpy(copy, bitbuf, sizeof(copy));
+      bitmap_clear_bit(&slock, node_id);
+      sql_print_information("NDB: reply to %s.%s(%u/%u) from %x%x to %x%x",
+                            db, table_name,
+                            table_id, table_version,
+                            copy[0], copy[1],
+                            slock.bitmap[0],
+                            slock.bitmap[1]);
+    }
+    else
+    {
+      bitmap_clear_bit(&slock, node_id);
+    }
+
     {
       NdbOperation *op= 0;
       int r= 0;
@@ -1824,7 +1862,8 @@ ndbcluster_update_slock(THD *thd,
 static void ndb_report_waiting(const char *key,
                                int the_time,
                                const char *op,
-                               const char *obj)
+                               const char *obj,
+                               const MY_BITMAP * map)
 {
   ulonglong ndb_latest_epoch= 0;
   const char *proc_info= "<no info>";
@@ -1834,19 +1873,79 @@ static void ndb_report_waiting(const cha
   if (injector_thd)
     proc_info= injector_thd->proc_info;
   pthread_mutex_unlock(&injector_mutex);
-  sql_print_information("NDB %s:"
-                        " waiting max %u sec for %s %s."
-                        "  epochs: (%u/%u,%u/%u,%u/%u)"
-                        "  injector proc_info: %s"
-                        ,key, the_time, op, obj
-                        ,(uint)(ndb_latest_handled_binlog_epoch >> 32)
-                        ,(uint)(ndb_latest_handled_binlog_epoch)
-                        ,(uint)(ndb_latest_received_binlog_epoch >> 32)
-                        ,(uint)(ndb_latest_received_binlog_epoch)
-                        ,(uint)(ndb_latest_epoch >> 32)
-                        ,(uint)(ndb_latest_epoch)
-                        ,proc_info
-                        );
+  if (map == 0)
+  {
+    sql_print_information("NDB %s:"
+                          " waiting max %u sec for %s %s."
+                          "  epochs: (%u/%u,%u/%u,%u/%u)"
+                          "  injector proc_info: %s"
+                          ,key, the_time, op, obj
+                          ,(uint)(ndb_latest_handled_binlog_epoch >> 32)
+                          ,(uint)(ndb_latest_handled_binlog_epoch)
+                          ,(uint)(ndb_latest_received_binlog_epoch >> 32)
+                          ,(uint)(ndb_latest_received_binlog_epoch)
+                          ,(uint)(ndb_latest_epoch >> 32)
+                          ,(uint)(ndb_latest_epoch)
+                          ,proc_info
+                          );
+  }
+  else
+  {
+    sql_print_information("NDB %s:"
+                          " waiting max %u sec for %s %s."
+                          "  epochs: (%u/%u,%u/%u,%u/%u)"
+                          "  injector proc_info: %s map: %x%x"
+                          ,key, the_time, op, obj
+                          ,(uint)(ndb_latest_handled_binlog_epoch >> 32)
+                          ,(uint)(ndb_latest_handled_binlog_epoch)
+                          ,(uint)(ndb_latest_received_binlog_epoch >> 32)
+                          ,(uint)(ndb_latest_received_binlog_epoch)
+                          ,(uint)(ndb_latest_epoch >> 32)
+                          ,(uint)(ndb_latest_epoch)
+                          ,proc_info
+                          ,map->bitmap[0]
+                          ,map->bitmap[1]
+                          );
+  }
+}
+
+static
+const char*
+get_schema_type_name(uint type)
+{
+  switch(type){
+  case SOT_DROP_TABLE:
+    return "DROP_TABLE";
+  case SOT_CREATE_TABLE:
+    return "CREATE_TABLE";
+  case SOT_RENAME_TABLE_NEW:
+    return "RENAME_TABLE_NEW";
+  case SOT_ALTER_TABLE_COMMIT:
+    return "ALTER_TABLE_COMMIT";
+  case SOT_DROP_DB:
+    return "DROP_DB";
+  case SOT_CREATE_DB:
+    return "CREATE_DB";
+  case SOT_ALTER_DB:
+    return "ALTER_DB";
+  case SOT_CLEAR_SLOCK:
+    return "CLEAR_SLOCK";
+  case SOT_TABLESPACE:
+    return "TABLESPACE";
+  case SOT_LOGFILE_GROUP:
+    return "LOGFILE_GROUP";
+  case SOT_RENAME_TABLE:
+    return "RENAME_TABLE";
+  case SOT_TRUNCATE_TABLE:
+    return "TRUNCATE_TABLE";
+  case SOT_RENAME_TABLE_PREPARE:
+    return "RENAME_TABLE_PREPARE";
+  case SOT_ONLINE_ALTER_TABLE_PREPARE:
+    return "ONLINE_ALTER_TABLE_PREPARE";
+  case SOT_ONLINE_ALTER_TABLE_COMMIT:
+    return "ONLINE_ALTER_TABLE_COMMIT";
+  }
+  return "<unknown>";
 }
 
 int ndbcluster_log_schema_op(THD *thd,
@@ -1881,6 +1980,7 @@ int ndbcluster_log_schema_op(THD *thd,
   char tmp_buf2[FN_REFLEN];
   const char *type_str;
   int also_internal= 0;
+  uint32 log_type= (uint32)type;
   switch (type)
   {
   case SOT_DROP_TABLE:
@@ -1950,20 +2050,16 @@ int ndbcluster_log_schema_op(THD *thd,
     char key[FN_REFLEN + 1];
     build_table_filename(key, sizeof(key) - 1, db, table_name, "", 0);
     ndb_schema_object= ndb_get_schema_object(key, TRUE, FALSE);
+    ndb_schema_object->table_id= ndb_table_id;
+    ndb_schema_object->table_version= ndb_table_version;
   }
 
   const NdbError *ndb_error= 0;
   uint32 node_id= g_ndb_cluster_connection->node_id();
   Uint64 epoch= 0;
-  MY_BITMAP schema_subscribers;
-  uint32 bitbuf[sizeof(ndb_schema_object->slock)/4];
-  char bitbuf_e[sizeof(bitbuf)];
-  bzero(bitbuf_e, sizeof(bitbuf_e));
   {
     int i;
     int no_storage_nodes= g_ndb_cluster_connection->no_db_nodes();
-    bitmap_init(&schema_subscribers, bitbuf, sizeof(bitbuf)*8, FALSE);
-    bitmap_clear_all(&schema_subscribers);
 
     /* begin protect ndb_schema_share */
     pthread_mutex_lock(&ndb_schema_share_mutex);
@@ -1977,29 +2073,20 @@ int ndbcluster_log_schema_op(THD *thd,
     pthread_mutex_lock(&ndb_schema_share->mutex);
     for (i= 0; i < no_storage_nodes; i++)
     {
-      bitmap_union(&schema_subscribers,&ndb_schema_share->subscriber_bitmap[i]);
+      bitmap_union(&ndb_schema_object->slock_bitmap,
+                   &ndb_schema_share->subscriber_bitmap[i]);
     }
     pthread_mutex_unlock(&ndb_schema_share->mutex);
     pthread_mutex_unlock(&ndb_schema_share_mutex);
     /* end protect ndb_schema_share */
 
     if (also_internal)
-      bitmap_set_bit(&schema_subscribers, node_id);        
+      bitmap_set_bit(&ndb_schema_object->slock_bitmap, node_id);
     else
-      bitmap_clear_bit(&schema_subscribers, node_id);
+      bitmap_clear_bit(&ndb_schema_object->slock_bitmap, node_id);
 
-    if (ndb_schema_object)
-    {
-      pthread_mutex_lock(&ndb_schema_object->mutex);
-      memcpy(ndb_schema_object->slock, schema_subscribers.bitmap,
-             sizeof(ndb_schema_object->slock));
-      pthread_mutex_unlock(&ndb_schema_object->mutex);
-    }
-
-    DBUG_DUMP("schema_subscribers", (uchar*)schema_subscribers.bitmap,
-              no_bytes_in_map(&schema_subscribers));
-    DBUG_PRINT("info", ("bitmap_is_clear_all(&schema_subscribers): %d",
-                        bitmap_is_clear_all(&schema_subscribers)));
+    DBUG_DUMP("schema_subscribers", (uchar*)&ndb_schema_object->slock,
+              no_bytes_in_map(&ndb_schema_object->slock_bitmap));
   }
 
   Ndb *ndb= thd_ndb->ndb;
@@ -2044,8 +2131,7 @@ int ndbcluster_log_schema_op(THD *thd,
   {
     const char *log_db= db;
     const char *log_tab= table_name;
-    const char *log_subscribers= (char*)schema_subscribers.bitmap;
-    uint32 log_type= (uint32)type;
+    const char *log_subscribers= (char*)ndb_schema_object->slock;
     if ((trans= ndb->startTransaction()) == 0)
       goto err;
     while (1)
@@ -2067,7 +2153,8 @@ int ndbcluster_log_schema_op(THD *thd,
       r|= op->equal(SCHEMA_NAME_I, tmp_buf);
       DBUG_ASSERT(r == 0);
       /* slock */
-      DBUG_ASSERT(sz[SCHEMA_SLOCK_I] == sizeof(bitbuf));
+      DBUG_ASSERT(sz[SCHEMA_SLOCK_I] ==
+                  no_bytes_in_map(&ndb_schema_object->slock_bitmap));
       r|= op->setValue(SCHEMA_SLOCK_I, log_subscribers);
       DBUG_ASSERT(r == 0);
       /* query */
@@ -2124,16 +2211,6 @@ int ndbcluster_log_schema_op(THD *thd,
 
       r|= op->setAnyValue(anyValue);
       DBUG_ASSERT(r == 0);
-#if 0
-      if (log_db != new_db && new_db && new_table_name)
-      {
-        log_db= new_db;
-        log_tab= new_table_name;
-        log_subscribers= bitbuf_e; // no ack expected on this
-        log_type= (uint32)SOT_RENAME_TABLE_NEW;
-        continue;
-      }
-#endif
       break;
     }
     if (trans->execute(NdbTransaction::Commit, NdbOperation::DefaultAbortOption,
@@ -2171,11 +2248,24 @@ end:
     ndb->closeTransaction(trans);
   ndb->setDatabaseName(save_db);
 
+  if (ndb_extra_logging > 19)
+  {
+    sql_print_information("NDB: distributed %s.%s(%u/%u) type: %s(%u) query: \'%s\' to %x%x",
+                          db,
+                          table_name,
+                          ndb_table_id,
+                          ndb_table_version,
+                          get_schema_type_name(log_type),
+                          log_type,
+                          query,
+                          ndb_schema_object->slock_bitmap.bitmap[0],
+                          ndb_schema_object->slock_bitmap.bitmap[1]);
+  }
+
   /*
     Wait for other mysqld's to acknowledge the table operation
   */
-  if (ndb_error == 0 &&
-      !bitmap_is_clear_all(&schema_subscribers))
+  if (ndb_error == 0 && !bitmap_is_clear_all(&ndb_schema_object->slock_bitmap))
   {
     int max_timeout= opt_ndb_sync_timeout;
     pthread_mutex_lock(&ndb_schema_object->mutex);
@@ -2206,6 +2296,7 @@ end:
       MY_BITMAP servers;
       bitmap_init(&servers, 0, 256, FALSE);
       bitmap_clear_all(&servers);
+      bitmap_set_bit(&servers, node_id); // "we" are always alive
       pthread_mutex_lock(&ndb_schema_share->mutex);
       for (i= 0; i < no_storage_nodes; i++)
       {
@@ -2213,18 +2304,13 @@ end:
         MY_BITMAP *tmp= &ndb_schema_share->subscriber_bitmap[i];
         bitmap_union(&servers, tmp);
       }
-      bitmap_intersect(&schema_subscribers, &servers);
       pthread_mutex_unlock(&ndb_schema_share->mutex);
       pthread_mutex_unlock(&ndb_schema_share_mutex);
       /* end protect ndb_schema_share */
-      bitmap_free(&servers);
 
       /* remove any unsubscribed from ndb_schema_object->slock */
-      bitmap_intersect(&ndb_schema_object->slock_bitmap, &schema_subscribers);
-
-      DBUG_DUMP("ndb_schema_object->slock_bitmap.bitmap",
-                (uchar*)ndb_schema_object->slock_bitmap.bitmap,
-                no_bytes_in_map(&ndb_schema_object->slock_bitmap));
+      bitmap_intersect(&ndb_schema_object->slock_bitmap, &servers);
+      bitmap_free(&servers);
 
       if (bitmap_is_clear_all(&ndb_schema_object->slock_bitmap))
         break;
@@ -2236,11 +2322,13 @@ end:
         {
           sql_print_error("NDB %s: distributing %s timed out. Ignoring...",
                           type_str, ndb_schema_object->key);
+          DBUG_ASSERT(false);
           break;
         }
         if (ndb_extra_logging)
           ndb_report_waiting(type_str, max_timeout,
-                             "distributing", ndb_schema_object->key);
+                             "distributing", ndb_schema_object->key,
+                             &ndb_schema_object->slock_bitmap);
       }
     }
     if (have_lock_open)
@@ -2249,10 +2337,34 @@ end:
     }
     pthread_mutex_unlock(&ndb_schema_object->mutex);
   }
+  else if (ndb_error)
+  {
+    sql_print_error("NDB %s: distributing %s err: %u",
+                    type_str, ndb_schema_object->key,
+                    ndb_error->code);
+  }
+  else if (ndb_extra_logging > 19)
+  {
+    sql_print_information("NDB %s: not waiting for distributing %s",
+                          type_str, ndb_schema_object->key);
+  }
 
   if (ndb_schema_object)
     ndb_free_schema_object(&ndb_schema_object, FALSE);
 
+  if (ndb_extra_logging > 19)
+  {
+    sql_print_information("NDB: distribution of %s.%s(%u/%u) type: %s(%u) query: \'%s\'"
+                          " - complete!",
+                          db,
+                          table_name,
+                          ndb_table_id,
+                          ndb_table_version,
+                          get_schema_type_name(log_type),
+                          log_type,
+                          query);
+  }
+
   DBUG_RETURN(0);
 }
 
@@ -2449,6 +2561,19 @@ ndb_binlog_thread_handle_schema_event(TH
                   schema->db, schema->name,
                   schema->query_length, schema->query,
                   schema_type));
+
+      if (ndb_extra_logging > 19)
+      {
+        sql_print_information("NDB: got schema event on %s.%s(%u/%u) query: '%s' type: %s(%d) node: %u slock: %x%x",
+                              schema->db, schema->name,
+                              schema->id, schema->version,
+                              schema->query,
+                              get_schema_type_name(schema_type),
+                              schema_type,
+                              schema->node_id,
+                              slock.bitmap[0], slock.bitmap[1]);
+      }
+
       if ((schema->db[0] == 0) && (schema->name[0] == 0))
         DBUG_RETURN(0);
       switch (schema_type)
@@ -2658,7 +2783,8 @@ ndb_binlog_thread_handle_schema_event(TH
           if (post_epoch_unlock)
             post_epoch_unlock_list->push_back(schema, mem_root);
           else
-            ndbcluster_update_slock(thd, schema->db, schema->name);
+            ndbcluster_update_slock(thd, schema->db, schema->name,
+                                    schema->id, schema->version);
         }
       }
       DBUG_RETURN(0);
@@ -2808,9 +2934,21 @@ ndb_binlog_thread_handle_schema_event_po
         NDB_SCHEMA_OBJECT *ndb_schema_object=
           (NDB_SCHEMA_OBJECT*) my_hash_search(&ndb_schema_objects,
                                               (const uchar*) key, strlen(key));
-        if (ndb_schema_object)
+        if (ndb_schema_object &&
+            (ndb_schema_object->table_id == schema->id &&
+             ndb_schema_object->table_version == schema->version))
         {
           pthread_mutex_lock(&ndb_schema_object->mutex);
+          if (ndb_extra_logging > 19)
+          {
+            sql_print_information("NDB: CLEAR_SLOCK key: %s(%u/%u) from"
+                                  " %x%x to %x%x",
+                                  key, schema->id, schema->version,
+                                  ndb_schema_object->slock[0],
+                                  ndb_schema_object->slock[1],
+                                  schema->slock[0],
+                                  schema->slock[1]);
+          }
           memcpy(ndb_schema_object->slock, schema->slock,
                  sizeof(ndb_schema_object->slock));
           DBUG_DUMP("ndb_schema_object->slock_bitmap.bitmap",
@@ -2819,6 +2957,24 @@ ndb_binlog_thread_handle_schema_event_po
           pthread_mutex_unlock(&ndb_schema_object->mutex);
           pthread_cond_signal(&injector_cond);
         }
+        else if (ndb_extra_logging > 19)
+        {
+          if (ndb_schema_object == 0)
+          {
+            sql_print_information("NDB: Discarding event...no obj: %s (%u/%u)",
+                                  key, schema->id, schema->version);
+          }
+          else
+          {
+            sql_print_information("NDB: Discarding event...key: %s "
+                                  "non matching id/version [%u/%u] != [%u/%u]",
+                                  key,
+                                  ndb_schema_object->table_id,
+                                  ndb_schema_object->table_version,
+                                  schema->id,
+                                  schema->version);
+          }
+        }
         pthread_mutex_unlock(&ndbcluster_mutex);
         continue;
       }
@@ -3143,7 +3299,8 @@ ndb_binlog_thread_handle_schema_event_po
   }
   while ((schema= post_epoch_unlock_list->pop()))
   {
-    ndbcluster_update_slock(thd, schema->db, schema->name);
+    ndbcluster_update_slock(thd, schema->db, schema->name,
+                            schema->id, schema->version);
   }
   DBUG_VOID_RETURN;
 }
@@ -4751,11 +4908,12 @@ ndbcluster_handle_alter_table(THD *thd, 
       {
         sql_print_error("NDB %s: %s timed out. Ignoring...",
                         type_str, share->key);
+        DBUG_ASSERT(false);
         break;
       }
       if (ndb_extra_logging)
         ndb_report_waiting(type_str, max_timeout,
-                           type_str, share->key);
+                           type_str, share->key, 0);
     }
   }
   pthread_mutex_unlock(&share->mutex);
@@ -4824,11 +4982,12 @@ ndbcluster_handle_drop_table(THD *thd, N
       {
         sql_print_error("NDB %s: %s timed out. Ignoring...",
                         type_str, share->key);
+        DBUG_ASSERT(false);
         break;
       }
       if (ndb_extra_logging)
         ndb_report_waiting(type_str, max_timeout,
-                           type_str, share->key);
+                           type_str, share->key, 0);
     }
   }
   pthread_mutex_lock(&LOCK_open);

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2010-08-20 14:07:55 +0000
+++ b/sql/handler.cc	2010-09-15 18:26:11 +0000
@@ -3565,7 +3565,10 @@ handler::alter_table_phase2(THD *thd,
 }
 
 int
-handler::alter_table_phase3(THD *thd, TABLE *table)
+handler::alter_table_phase3(THD *thd, TABLE *table,
+                            HA_CREATE_INFO *create_info,
+                            HA_ALTER_INFO *alter_info,
+                            HA_ALTER_FLAGS *alter_flags)
 {
   DBUG_ENTER("alter_table_phase3");
   DBUG_RETURN(0);

=== modified file 'sql/handler.h'
--- a/sql/handler.h	2010-08-20 13:04:07 +0000
+++ b/sql/handler.h	2010-09-15 18:26:11 +0000
@@ -1879,7 +1879,7 @@ public:
    @param     altered_table     A temporary table show what table is to
                                 change to
    @param     alter_info        Storage place for data used during phase1
-                                and phase2
+                                and phase2 and phase3
    @param     alter_flags       Bitmask that shows what will be changed
 
    @retval   0      OK
@@ -1897,8 +1897,10 @@ public:
     @param    thd               The thread handle
     @param    altered_table     A temporary table show what table is to
                                 change to
+    @param    create_info       Information from the parsing phase about new
+                                table properties.
     @param    alter_info        Storage place for data used during phase1
-                                and phase2
+                                and phase2 and phase3
     @param    alter_flags       Bitmask that shows what will be changed
 
     @retval  0      OK
@@ -1921,8 +1923,16 @@ public:
 
     @param    thd               The thread handle
     @param    table             The altered table, re-opened
+    @param    create_info       Information from the parsing phase about new
+                                table properties.
+    @param    alter_info        Storage place for data used during phase1
+                                and phase2 and phase3
+    @param    alter_flags       Bitmask that shows what has been changed
  */
- virtual int alter_table_phase3(THD *thd, TABLE *table);
+ virtual int alter_table_phase3(THD *thd, TABLE *table,
+                                HA_CREATE_INFO *create_info,
+                                HA_ALTER_INFO *alter_info,
+                                HA_ALTER_FLAGS *alter_flags);
 
   /**
     use_hidden_primary_key() is called in case of an update/delete when

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2010-08-20 13:04:07 +0000
+++ b/sql/sql_table.cc	2010-09-15 18:26:11 +0000
@@ -6442,7 +6442,10 @@ int mysql_fast_or_online_alter_table(THD
       Tell the handler that the changed frm is on disk and table
       has been re-opened
    */
-    if ((error= t_table->file->alter_table_phase3(thd, t_table)))
+    if ((error= t_table->file->alter_table_phase3(thd, t_table,
+                                                  create_info,
+                                                  alter_info,
+                                                  ha_alter_flags)))
     {
       goto err;
     }


Attachment: [text/bzr-bundle] bzr/jonas@mysql.com-20100915182611-yy0xp2vmtj5qtv9d.bundle
Thread
bzr commit into mysql-5.1-telco-6.3 branch (jonas:3295) Jonas Oreland15 Sep