Commit c53b0c43 authored by unknown's avatar unknown
Browse files

Merge mskold@bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/usr/local/home/marty/MySQL/mysql-4.1

parents 57d9c6d0 c97859b3
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -13,6 +13,26 @@ a
show status like 'handler_discover%';
Variable_name	Value
Handler_discover	0
select * from t1;
a
2
drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
select * from t1;
a
2
show status like 'handler_discover%';
Variable_name	Value
Handler_discover	0
drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
select * from t1;
ERROR HY000: Got error 241 'Invalid schema object version' from ndbcluster
select * from t1;
a
2
flush status;
select * from t1;
a
@@ -20,7 +40,7 @@ a
update t1 set a=3 where a=2;
show status like 'handler_discover%';
Variable_name	Value
Handler_discover	1
Handler_discover	0
create table t3 (a int not null primary key, b varchar(22),
c int, last_col text) engine=ndb;
insert into t3 values(1, 'Hi!', 89, 'Longtext column');
+24 −0
Original line number Diff line number Diff line
@@ -18,6 +18,30 @@ select * from t1;
select * from t2;
show status like 'handler_discover%';

# Check dropping and recreating table on same server
connect (con1,localhost,,,test);
connect (con2,localhost,,,test);
connection con1;
select * from t1;
connection con2;
drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
connection con1;
select * from t1;

# Check dropping and recreating table on different server
connection server2;
show status like 'handler_discover%';
drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
connection server1;
# Currently a retry is required remotely
--error 1296
select * from t1;
select * from t1;

# Connect to server2 and use the tables from there
connection server2;
flush status;
+4 −1
Original line number Diff line number Diff line
@@ -75,8 +75,11 @@ public:
      Changed,                ///< The object has been modified in memory 
                              ///< and has to be commited in NDB Kernel for 
                              ///< changes to take effect
      Retrieved               ///< The object exist and has been read 
      Retrieved,              ///< The object exist and has been read 
                              ///< into main memory from NDB Kernel
      Invalid                 ///< The object has been invalidated
                              ///< and should not be used
      
    };

    /**
+7 −4
Original line number Diff line number Diff line
@@ -1448,6 +1448,7 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
      // If in local cache it must be in global
      if (!cachedImpl)
	abort();
      cachedImpl->m_status = NdbDictionary::Object::Invalid;
      m_globalHash->drop(cachedImpl);
      m_globalHash->unlock();
    }
@@ -1747,8 +1748,8 @@ NdbDictionaryImpl::dropTable(const char * name)

    DBUG_PRINT("info",("INCOMPATIBLE_VERSION internal_name: %s", internalTableName));
    m_localHash.drop(internalTableName);
    
    m_globalHash->lock();
    tab->m_status = NdbDictionary::Object::Invalid;
    m_globalHash->drop(tab);
    m_globalHash->unlock();   
    DBUG_RETURN(dropTable(name));
@@ -1793,9 +1794,10 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
  if(ret == 0 || m_error.code == 709){
    const char * internalTableName = impl.m_internalName.c_str();

    m_localHash.drop(internalTableName);
    
    m_localHash.drop(internalTableName);
    m_globalHash->lock();
    impl.m_status = NdbDictionary::Object::Invalid;
    m_globalHash->drop(&impl);
    m_globalHash->unlock();

@@ -1889,6 +1891,7 @@ NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)

  m_localHash.drop(internalTableName);  
  m_globalHash->lock();
  impl.m_status = NdbDictionary::Object::Invalid;
  m_globalHash->drop(&impl);
  m_globalHash->unlock();
  return 0;
@@ -2152,8 +2155,8 @@ NdbDictionaryImpl::dropIndex(const char * indexName,
      m_ndb.internalizeTableName(indexName); // Index is also a table
    
    m_localHash.drop(internalIndexName);
    
    m_globalHash->lock();
    idx->m_table->m_status = NdbDictionary::Object::Invalid;
    m_globalHash->drop(idx->m_table);
    m_globalHash->unlock();   
    return dropIndex(indexName, tableName);
@@ -2187,8 +2190,8 @@ NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
    int ret = m_receiver.dropIndex(impl, *timpl);
    if(ret == 0){
      m_localHash.drop(internalIndexName);
      
      m_globalHash->lock();
      impl.m_table->m_status = NdbDictionary::Object::Invalid;
      m_globalHash->drop(impl.m_table);
      m_globalHash->unlock();
    }
+77 −20
Original line number Diff line number Diff line
@@ -331,11 +331,28 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
    #   The mapped error code
*/

void ha_ndbcluster::invalidateDictionaryCache()
void ha_ndbcluster::invalidate_dictionary_cache(bool global)
{
  NDBDICT *dict= get_ndb()->getDictionary();
  DBUG_ENTER("invalidate_dictionary_cache");
  DBUG_PRINT("info", ("invalidating %s", m_tabname));

  if (global)
  {
    const NDBTAB *tab= dict->getTable(m_tabname);
    if (!tab)
      DBUG_VOID_RETURN;
    if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
    {
      // Global cache has already been invalidated
      dict->removeCachedTable(m_tabname);
      global= FALSE;
    }
    else
      dict->invalidateTable(m_tabname);
  }
  else
    dict->removeCachedTable(m_tabname);
  table->version=0L;			/* Free when thread is ready */
  /* Invalidate indexes */
  for (uint i= 0; i < table->keys; i++)
@@ -347,18 +364,28 @@ void ha_ndbcluster::invalidateDictionaryCache()
    switch(idx_type) {
    case(PRIMARY_KEY_ORDERED_INDEX):
    case(ORDERED_INDEX):
      if (global)
        dict->invalidateIndex(index->getName(), m_tabname);
      else
        dict->removeCachedIndex(index->getName(), m_tabname);
      break;      
    case(UNIQUE_ORDERED_INDEX):
      if (global)
        dict->invalidateIndex(index->getName(), m_tabname);
      else
        dict->removeCachedIndex(index->getName(), m_tabname);
    case(UNIQUE_INDEX):
      if (global)
        dict->invalidateIndex(unique_index->getName(), m_tabname);
      else
        dict->removeCachedIndex(unique_index->getName(), m_tabname);
      break;
    case(PRIMARY_KEY_INDEX):
    case(UNDEFINED_INDEX):
      break;
    }
  }
  DBUG_VOID_RETURN;
}

int ha_ndbcluster::ndb_err(NdbConnection *trans)
@@ -371,7 +398,7 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans)
  switch (err.classification) {
  case NdbError::SchemaError:
  {
    invalidateDictionaryCache();
    invalidate_dictionary_cache(TRUE);

    if (err.code==284)
    {
@@ -765,9 +792,16 @@ int ha_ndbcluster::get_metadata(const char *path)
    const void *data, *pack_data;
    uint length, pack_length;

    if (!(tab= dict->getTable(m_tabname)))
      ERR_RETURN(dict->getNdbError());
    // Check if thread has stale local cache
    if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
    {
      invalidate_dictionary_cache(FALSE);
      if (!(tab= dict->getTable(m_tabname)))
         ERR_RETURN(dict->getNdbError());
      DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
    }
    /*
      Compare FrmData in NDB with frm file from disk.
    */
@@ -786,7 +820,7 @@ int ha_ndbcluster::get_metadata(const char *path)
      if (!invalidating_ndb_table)
      {
	DBUG_PRINT("info", ("Invalidating table"));
        invalidateDictionaryCache();
        invalidate_dictionary_cache(TRUE);
	invalidating_ndb_table= TRUE;
      }
      else
@@ -812,7 +846,7 @@ int ha_ndbcluster::get_metadata(const char *path)
  if (error)
    DBUG_RETURN(error);
  
  m_tableVersion= tab->getObjectVersion();
  m_table_version= tab->getObjectVersion();
  m_table= (void *)tab; 
  m_table_info= NULL; // Set in external lock
  
@@ -3226,15 +3260,25 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
      void *tab_info;
      if (!(tab= dict->getTable(m_tabname, &tab_info)))
	ERR_RETURN(dict->getNdbError());
      DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
      if (m_table != (void *)tab || m_tableVersion != tab->getObjectVersion())
      DBUG_PRINT("info", ("Table schema version: %d", 
                          tab->getObjectVersion()));
      // Check if thread has stale local cache
      if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
      {
        invalidate_dictionary_cache(FALSE);
        if (!(tab= dict->getTable(m_tabname)))
          ERR_RETURN(dict->getNdbError());
        DBUG_PRINT("info", ("Table schema version: %d", 
                            tab->getObjectVersion()));
      }
      if (m_table != (void *)tab || m_table_version < tab->getObjectVersion())
      {
        /*
          The table has been altered, refresh the index list
        */
        build_index_list(ndb, table, ILBP_OPEN);  
        m_table= (void *)tab;
        m_tableVersion = tab->getObjectVersion();
        m_table_version = tab->getObjectVersion();
      }
      m_table_info= tab_info;
    }
@@ -3260,7 +3304,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
        thd->transaction.stmt.ndb_tid= 0;
      }
    }
    m_table= NULL;
    m_table_info= NULL;
    /*
      This is the place to make sure this handler instance
@@ -3882,7 +3925,13 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
  dict= ndb->getDictionary();
  if (!(orig_tab= dict->getTable(m_tabname)))
    ERR_RETURN(dict->getNdbError());

  // Check if thread has stale local cache
  if (orig_tab->getObjectStatus() == NdbDictionary::Object::Invalid)
  {
    dict->removeCachedTable(m_tabname);
    if (!(orig_tab= dict->getTable(m_tabname)))
      ERR_RETURN(dict->getNdbError());
  }
  m_table= (void *)orig_tab;
  // Change current database to that of target table
  set_dbname(to);
@@ -4006,7 +4055,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
  m_active_trans(NULL),
  m_active_cursor(NULL),
  m_table(NULL),
  m_tableVersion(-1),
  m_table_version(-1),
  m_table_info(NULL),
  m_table_flags(HA_REC_NOT_IN_SEQ |
		HA_NULL_IN_KEY |
@@ -4250,7 +4299,6 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
      DBUG_RETURN(1);
    ERR_RETURN(err);
  }
  
  DBUG_PRINT("info", ("Found table %s", tab->getName()));
  
  len= tab->getFrmLength();  
@@ -4327,6 +4375,7 @@ int ndbcluster_drop_database(const char *path)
  uint i;
  char *tabname;
  List<char> drop_list;
  int ret= 0;
  ha_ndbcluster::set_dbname(path, (char *)&dbname);
  DBUG_PRINT("enter", ("db: %s", dbname));
  
@@ -4353,10 +4402,18 @@ int ndbcluster_drop_database(const char *path)
  ndb->setDatabaseName(dbname);
  List_iterator_fast<char> it(drop_list);
  while ((tabname=it++))
  {
    if (dict->dropTable(tabname))
      ERR_RETURN(dict->getNdbError());      

  DBUG_RETURN(0);
    {
      const NdbError err= dict->getNdbError();
      if (err.code != 709)
      {
        ERR_PRINT(err);
        ret= ndb_to_mysql_error(&err);
      }
    }
  }
  DBUG_RETURN(ret);      
}


Loading