List:Internals« Previous MessageNext Message »
From:tomas Date:July 23 2005 4:11pm
Subject:bk commit into 5.1 tree (tomas:1.1884) BUG#12117
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of tomas. When tomas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1884 05/07/23 18:11:10 tomas@stripped +9 -0
  Bug #12117 create/drop/alter combinations with several mysql servers can cause server crash

  storage/ndb/src/ndbapi/NdbEventOperation.cpp
    1.7 05/07/23 18:11:04 tomas@stripped +5 -0
    Bug #12117 create/drop/alter combinations with several mysql servers can cause server crash

  storage/ndb/src/kernel/blocks/suma/Suma.cpp
    1.22 05/07/23 18:11:04 tomas@stripped +9 -6
    Bug #12117 create/drop/alter combinations with several mysql servers can cause server crash

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
    1.52 05/07/23 18:11:04 tomas@stripped +8 -0
    Bug #12117 create/drop/alter combinations with several mysql servers can cause server crash

  storage/ndb/include/ndbapi/NdbEventOperation.hpp
    1.15 05/07/23 18:11:04 tomas@stripped +2 -0
    Bug #12117 create/drop/alter combinations with several mysql servers can cause server crash

  storage/ndb/include/kernel/signaldata/SumaImpl.hpp
    1.6 05/07/23 18:11:04 tomas@stripped +4 -1
    Bug #12117 create/drop/alter combinations with several mysql servers can cause server crash

  sql/ha_ndbcluster.h
    1.91 05/07/23 18:11:04 tomas@stripped +2 -0
    Bug #12117 create/drop/alter combinations with several mysql servers can cause server crash

  sql/ha_ndbcluster.cc
    1.202 05/07/23 18:11:04 tomas@stripped +76 -24
    Bug #12117 create/drop/alter combinations with several mysql servers can cause server crash

  mysql-test/t/ndb_alter_table.test
    1.24 05/07/23 18:11:04 tomas@stripped +0 -3
    Bug #12117 create/drop/alter combinations with several mysql servers can cause server crash

  mysql-test/r/ndb_alter_table.result
    1.30 05/07/23 18:11:03 tomas@stripped +0 -7
    Bug #12117 create/drop/alter combinations with several mysql servers can cause server crash

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tomas
# Host:	poseidon.ndb.mysql.com
# Root:	/home/tomas/mysql-5.1-wl2325-a

--- 1.29/mysql-test/r/ndb_alter_table.result	2005-07-21 20:35:02 +02:00
+++ 1.30/mysql-test/r/ndb_alter_table.result	2005-07-23 18:11:03 +02:00
@@ -179,13 +179,6 @@
 2	two	two
 alter table t1 drop index c;
 select * from t1 where b = 'two';
-ERROR HY000: Table definition has changed, please retry transaction
-show warnings;
-Level	Code	Message
-Error	1296	Got error 284 'Table not defined in transaction coordinator' from NDB
-Error	1412	Table definition has changed, please retry transaction
-Error	1105	Unknown error
-select * from t1 where b = 'two';
 a	b	c
 2	two	two
 drop table t1;

--- 1.23/mysql-test/t/ndb_alter_table.test	2005-07-21 20:35:03 +02:00
+++ 1.24/mysql-test/t/ndb_alter_table.test	2005-07-23 18:11:04 +02:00
@@ -151,9 +151,6 @@
 connection server1;
 alter table t1 drop index c;
 connection server2;
---error 1412
-select * from t1 where b = 'two';
-show warnings;
 select * from t1 where b = 'two';
 connection server1;
 drop table t1;

--- 1.5/storage/ndb/include/kernel/signaldata/SumaImpl.hpp	2005-07-21 20:35:05 +02:00
+++ 1.6/storage/ndb/include/kernel/signaldata/SumaImpl.hpp	2005-07-23 18:11:04 +02:00
@@ -302,7 +302,10 @@
   Uint32 senderData;
   Uint32 gci;
   Uint32 tableId;
-  Uint32 operation;
+  Uint8  operation;
+  Uint8  req_nodeid;
+  Uint8  not_used2;
+  Uint8  not_used3;
   Uint32 logType;
 };
 

--- 1.14/storage/ndb/include/ndbapi/NdbEventOperation.hpp	2005-07-21 20:35:06 +02:00
+++ 1.15/storage/ndb/include/ndbapi/NdbEventOperation.hpp	2005-07-23 18:11:04 +02:00
@@ -202,6 +202,8 @@
 
   void clearError();
   int hasError() const;
+
+  int getReqNodeId() const;
 #endif
 
 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL

--- 1.51/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2005-07-22 17:08:45 +02:00
+++ 1.52/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2005-07-23 18:11:04 +02:00
@@ -3877,6 +3877,10 @@
   conf->requestType = AlterTabReq::AlterTableCommit;
   {
     AlterTabConf tmp= *conf;
+    if (coordinatorRef == reference())
+      conf->senderRef = alterTabPtr.p->m_senderRef;
+    else
+      conf->senderRef = 0;
     EXECUTE_DIRECT(SUMA, GSN_ALTER_TAB_CONF, signal,
 		   AlterTabConf::SignalLength);
     jamEntry();
@@ -5913,6 +5917,10 @@
   conf->tableId = dropTabPtr.p->m_request.tableId;
   {
     DropTabConf tmp= *conf;
+    if (dropTabPtr.p->m_coordinatorRef == reference())
+      conf->senderRef = dropTabPtr.p->m_request.senderRef;
+    else
+      conf->senderRef = 0;
     EXECUTE_DIRECT(SUMA, GSN_DROP_TAB_CONF, signal,
 		   DropTabConf::SignalLength);
     jamEntry();

--- 1.21/storage/ndb/src/kernel/blocks/suma/Suma.cpp	2005-07-21 20:35:08 +02:00
+++ 1.22/storage/ndb/src/kernel/blocks/suma/Suma.cpp	2005-07-23 18:11:04 +02:00
@@ -3205,6 +3205,7 @@
   ndbassert(signal->getNoOfSections() == 0);
 
   DropTabConf * const conf = (DropTabConf*)signal->getDataPtr();
+  Uint32 senderRef= conf->senderRef;
   Uint32 tableId= conf->tableId;
 
   TablePtr tabPtr;
@@ -3225,17 +3226,18 @@
   tabPtr.p->m_triggerIds[1] = ILLEGAL_TRIGGER_ID;
   tabPtr.p->m_triggerIds[2] = ILLEGAL_TRIGGER_ID;
 
-  if (get_responsible_node(0) != refToNode(reference()))
+  if (senderRef == 0)
   {
     DBUG_VOID_RETURN;
   }
-  // responsible for bucket 0 sends info to API
+  // dict coordinator sends info to API
   
   SubTableData * data = (SubTableData*)signal->getDataPtrSend();
   data->gci            = m_last_complete_gci+1;
   data->tableId        = tableId;
   data->operation      = NdbDictionary::Event::_TE_DROP;
- 
+  data->req_nodeid     = refToNode(senderRef);
+  
   {
     LocalDLList<Subscriber> subbs(c_subscriberPool,tabPtr.p->c_subscribers);
     SubscriberPtr subbPtr;
@@ -3253,7 +3255,6 @@
 	//continue in for-loop if the table is not part of 
 	//the subscription. Otherwise, send data to subscriber.
       }
-
       data->senderData= subbPtr.p->m_senderData;
       sendSignal(subbPtr.p->m_senderRef, GSN_SUB_TABLE_DATA, signal,
 		 SubTableData::SignalLength, JBB);
@@ -3271,6 +3272,7 @@
   ndbassert(signal->getNoOfSections() == 0);
 
   AlterTabConf * const conf = (AlterTabConf*)signal->getDataPtr();
+  Uint32 senderRef= conf->senderRef;
   Uint32 tableId= conf->tableId;
 
   TablePtr tabPtr;
@@ -3286,16 +3288,17 @@
   tabPtr.p->m_state = Table::ALTERED;
   // triggers must be removed, waiting for sub stop req for that
 
-  if (get_responsible_node(0) != refToNode(reference()))
+  if (senderRef == 0)
   {
     DBUG_VOID_RETURN;
   }
-  // responsible for bucket 0 sends info to API
+  // dict coordinator sends info to API
   
   SubTableData * data = (SubTableData*)signal->getDataPtrSend();
   data->gci            = m_last_complete_gci+1;
   data->tableId        = tableId;
   data->operation      = NdbDictionary::Event::_TE_ALTER;
+  data->req_nodeid     = refToNode(senderRef);
  
   {
     LocalDLList<Subscriber> subbs(c_subscriberPool,tabPtr.p->c_subscribers);

--- 1.6/storage/ndb/src/ndbapi/NdbEventOperation.cpp	2005-07-21 20:35:09 +02:00
+++ 1.7/storage/ndb/src/ndbapi/NdbEventOperation.cpp	2005-07-23 18:11:04 +02:00
@@ -152,6 +152,11 @@
   return m_impl.m_custom_data;
 }
 
+int NdbEventOperation::getReqNodeId() const
+{
+  return m_impl.m_data_item->sdata->req_nodeid;
+}
+
 /*
  * Private members
  */

--- 1.201/sql/ha_ndbcluster.cc	2005-07-22 03:03:59 +02:00
+++ 1.202/sql/ha_ndbcluster.cc	2005-07-23 18:11:04 +02:00
@@ -121,7 +121,7 @@
 static int handle_trailing_share(NDB_SHARE *share);
 static int rename_share(NDB_SHARE *share, const char *new_key);
 #endif
-static void free_share(NDB_SHARE **share);
+static void free_share(NDB_SHARE **share, bool have_lock= FALSE);
 static void real_free_share(NDB_SHARE **share);
 static void ndb_set_fragmentation(NDBTAB & tab, TABLE *table, uint pk_len);
 
@@ -520,29 +520,38 @@
     #   The mapped error code
 */
 
-void ha_ndbcluster::invalidate_dictionary_cache(bool global)
+void
+ha_ndbcluster::invalidate_dictionary_cache(TABLE *table, Ndb *ndb,
+					   const char *tabname, bool global)
 {
-  NDBDICT *dict= get_ndb()->getDictionary();
+  NDBDICT *dict= ndb->getDictionary();
   DBUG_ENTER("invalidate_dictionary_cache");
-  DBUG_PRINT("info", ("invalidating %s", m_tabname));
+  DBUG_PRINT("info", ("invalidating %s", tabname));
 
   if (global)
   {
-    const NDBTAB *tab= dict->getTable(m_tabname);
+    const NDBTAB *tab= dict->getTable(tabname);
     if (!tab)
       DBUG_VOID_RETURN;
     if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
     {
       // Global cache has already been invalidated
-      dict->removeCachedTable(m_tabname);
+      dict->removeCachedTable(tabname);
       global= FALSE;
     }
     else
-      dict->invalidateTable(m_tabname);
+      dict->invalidateTable(tabname);
   }
   else
-    dict->removeCachedTable(m_tabname);
+    dict->removeCachedTable(tabname);
   table->s->version=0L;			/* Free when thread is ready */
+  DBUG_VOID_RETURN;
+}
+
+void ha_ndbcluster::invalidate_dictionary_cache(bool global)
+{
+  NDBDICT *dict= get_ndb()->getDictionary();
+  invalidate_dictionary_cache(table, get_ndb(), m_tabname, global);
   /* Invalidate indexes */
   for (uint i= 0; i < table->s->keys; i++)
   {
@@ -574,7 +583,6 @@
       break;
     }
   }
-  DBUG_VOID_RETURN;
 }
 
 int ha_ndbcluster::ndb_err(NdbTransaction *trans)
@@ -4024,7 +4032,7 @@
 #ifdef HAVE_NDB_BINLOG
     ndbcluster_create_binlog_setup(get_ndb(), name2, m_dbname, m_tabname,
 				   ndb_binlog_thread_running > 0 &&
-				   m_tabname[0] != '#');
+				   !is_prefix(m_tabname,tmp_file_prefix));
 #endif /* HAVE_NDB_BINLOG */
     DBUG_RETURN(my_errno);
   } // if (create_from_engine)
@@ -4165,7 +4173,7 @@
       sql_print_error("NDB: allocating table share for %s failed", name2);
     }
 
-    while (m_tabname[0] != '#') // FIXME tabname hack
+    while (!is_prefix(m_tabname,tmp_file_prefix))
     {
       const NDBTAB *t= dict->getTable(m_tabname);
       String event_name(INJECTOR_EVENT_LEN);
@@ -4333,14 +4341,14 @@
     dict->forceGCPWait();
   }
   // handle old table
-  if ( m_tabname[0] != '#' ) // FIXME tabname hack
+  if ( !is_prefix(m_tabname,tmp_file_prefix) )
   {
     String event_name(INJECTOR_EVENT_LEN);
     ndb_rep_event_name(&event_name,from+sizeof(share_prefix)-1,0);
     ndb_binlog_handle_drop_table(ndb, event_name.c_ptr(), share);
   }
 
-  if( !result && new_tabname[0] != '#')
+  if( !result &&  !is_prefix(new_tabname,tmp_file_prefix) )
   {
     /* always create an event for the table */
     String event_name(INJECTOR_EVENT_LEN);
@@ -4439,12 +4447,14 @@
 #ifdef HAVE_NDB_BINLOG
     if (share)
     {
+      pthread_mutex_lock(&ndbcluster_mutex);
       if (share->state != NSS_DROPPED)
       {
 	share->state= NSS_DROPPED;
-	free_share(&share);
+	free_share(&share,TRUE);
       }
-      free_share(&share);
+      free_share(&share,TRUE);
+      pthread_mutex_unlock(&ndbcluster_mutex);
     }
 #endif
     DBUG_RETURN(r);
@@ -4464,7 +4474,7 @@
     dict->forceGCPWait();
   }
 
-  if ( table_name[0] != '#' ) // FIXME tabname hack
+  if ( !is_prefix(table_name,tmp_file_prefix) )
   {
     String event_name(INJECTOR_EVENT_LEN);
     ndb_rep_event_name(&event_name,path+sizeof(share_prefix)-1,0);
@@ -4475,12 +4485,14 @@
 
   if (share)
   {
+    pthread_mutex_lock(&ndbcluster_mutex);
     if (share->state != NSS_DROPPED)
     {
       share->state= NSS_DROPPED;
-      free_share(&share);
+      free_share(&share,TRUE);
     }
-    free_share(&share);
+    free_share(&share,TRUE);
+    pthread_mutex_unlock(&ndbcluster_mutex);
   }
 #endif
   DBUG_RETURN(0);
@@ -5037,7 +5049,7 @@
 	 */
 	ndbcluster_create_binlog_setup(ndb, key, t.database, t.name,
 				       ndb_binlog_thread_running > 0 &&
-				       t.name[0] != '#');
+				       !is_prefix(t.name,tmp_file_prefix));
       }
 #endif
     }
@@ -5165,7 +5177,8 @@
 	// attempt to do it
 	
 	pthread_mutex_unlock(&ndbcluster_mutex);
-	ndbcluster_create_binlog_setup(ndb, name, db, file_name, file_name[0] != '#');
+	ndbcluster_create_binlog_setup(ndb, name, db, file_name,
+				       !is_prefix(file_name,tmp_file_prefix));
 	pthread_mutex_lock(&ndbcluster_mutex);
       }
     }
@@ -5966,6 +5979,19 @@
   static ulong trailing_share_id= 0;
   DBUG_ENTER("handle_trailing_share");
 
+  ++share->use_count;
+  pthread_mutex_unlock(&ndbcluster_mutex);
+
+  close_cached_tables((THD*) 0,0,(TABLE_LIST*) 0);
+
+  pthread_mutex_lock(&ndbcluster_mutex);
+  if (!--share->use_count)
+  {
+    DBUG_PRINT("info", ("NDB_SHARE: close_cashed_tables %s freed share.", share->key)); 
+    real_free_share(&share);
+    DBUG_RETURN(0);
+  }
+
   if (share->state != NSS_DROPPED && !--share->use_count)
   {
     DBUG_PRINT("info", ("NDB_SHARE: %s already exists, use_count=%d, state != NSS_DROPPED.",
@@ -6254,9 +6280,10 @@
   dbug_print_open_tables();
 }
 
-static void free_share(NDB_SHARE **share)
+static void free_share(NDB_SHARE **share, bool have_lock)
 {
-  pthread_mutex_lock(&ndbcluster_mutex);
+  if (!have_lock)
+    pthread_mutex_lock(&ndbcluster_mutex);
   if ((*share)->util_lock == current_thd)
     (*share)->util_lock= 0;
   if (!--(*share)->use_count)
@@ -6274,7 +6301,8 @@
 		(*share)->db, (*share)->table_name,
 		(*share)->use_count, (*share)->commit_count));
   }
-  pthread_mutex_unlock(&ndbcluster_mutex);
+  if (!have_lock)
+    pthread_mutex_unlock(&ndbcluster_mutex);
 }
 
 
@@ -9195,6 +9223,7 @@
   NDB_SHARE *share= (NDB_SHARE *)pOp->getCustomData();
   const NDBTAB *ndbtab= pOp->getTable();
   NDBEVENT::TableEvent type= pOp->getEventType();
+  int remote_drop_table= 0, do_close_cached_tables= 0;
   switch (type)
   {
   case NDBEVENT::TE_CLUSTER_FAILURE:
@@ -9225,6 +9254,15 @@
     DBUG_PRINT("info",("TABLE %s EVENT: %s received share: 0x%lx op: %lx share op: %lx op_old: %lx",
 		       type == NDBEVENT::TE_DROP ? "DROP" : "ALTER",
 		       ndbtab->getMysqlName(), share, pOp, share->op, share->op_old));
+    if (pOp->getReqNodeId() != ndb_cluster_node_id)
+    {
+      ndb->setDatabaseName(share->table->s->db);
+      ha_ndbcluster::invalidate_dictionary_cache(share->table,
+						 ndb,
+						 share->table->s->table_name,
+						 TRUE);
+      remote_drop_table= 1;
+    }
     break;
   default:
     sql_print_error("NDB Binlog: unknown non data event %d for %s. "
@@ -9244,7 +9282,18 @@
   (void) pthread_mutex_unlock(&share->mutex);
   (void) pthread_cond_signal(&injector_cond);
 
-  free_share(&share);
+  pthread_mutex_lock(&ndbcluster_mutex);
+  free_share(&share,TRUE);
+  if (remote_drop_table && share && share->state != NSS_DROPPED)
+  {
+    DBUG_PRINT("info",("remote drop table"));
+    if (share->use_count != 1)
+      do_close_cached_tables= 1;
+    share->state= NSS_DROPPED;
+    free_share(&share,TRUE);
+  }
+  pthread_mutex_unlock(&ndbcluster_mutex);
+
   share= 0;
   pOp->setCustomData(0);
           
@@ -9252,6 +9301,9 @@
   ndb->dropEventOperation(pOp);
   pOp= 0;
   pthread_mutex_unlock(&injector_mutex);
+
+  if(do_close_cached_tables)
+    close_cached_tables((THD*) 0,0,(TABLE_LIST*) 0);
 
   return 0;
 }

--- 1.90/sql/ha_ndbcluster.h	2005-07-21 20:35:03 +02:00
+++ 1.91/sql/ha_ndbcluster.h	2005-07-23 18:11:04 +02:00
@@ -569,6 +569,8 @@
                                      uint key_length,
                                      qc_engine_callback *engine_callback,
                                      ulonglong *engine_data);
+  static void invalidate_dictionary_cache(TABLE *table, Ndb *ndb,
+					  const char *tabname, bool global);
 private:
   friend int ndbcluster_drop_database(const char *path);
   int alter_table_name(const char *to);
Thread
bk commit into 5.1 tree (tomas:1.1884) BUG#12117tomas23 Jul