Commit 56499dbe authored by mskold@mysql.com's avatar mskold@mysql.com

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

into mysql.com:/usr/local/home/marty/MySQL/mysql-4.1
parents b2ebf51f 2428e7b1
...@@ -13,6 +13,26 @@ a ...@@ -13,6 +13,26 @@ a
show status like 'handler_discover%'; show status like 'handler_discover%';
Variable_name Value Variable_name Value
Handler_discover 0 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; flush status;
select * from t1; select * from t1;
a a
...@@ -20,7 +40,7 @@ a ...@@ -20,7 +40,7 @@ a
update t1 set a=3 where a=2; update t1 set a=3 where a=2;
show status like 'handler_discover%'; show status like 'handler_discover%';
Variable_name Value Variable_name Value
Handler_discover 1 Handler_discover 0
create table t3 (a int not null primary key, b varchar(22), create table t3 (a int not null primary key, b varchar(22),
c int, last_col text) engine=ndb; c int, last_col text) engine=ndb;
insert into t3 values(1, 'Hi!', 89, 'Longtext column'); insert into t3 values(1, 'Hi!', 89, 'Longtext column');
......
...@@ -18,6 +18,30 @@ select * from t1; ...@@ -18,6 +18,30 @@ select * from t1;
select * from t2; select * from t2;
show status like 'handler_discover%'; 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 # Connect to server2 and use the tables from there
connection server2; connection server2;
flush status; flush status;
......
...@@ -75,8 +75,11 @@ public: ...@@ -75,8 +75,11 @@ public:
Changed, ///< The object has been modified in memory Changed, ///< The object has been modified in memory
///< and has to be commited in NDB Kernel for ///< and has to be commited in NDB Kernel for
///< changes to take effect ///< 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 ///< into main memory from NDB Kernel
Invalid ///< The object has been invalidated
///< and should not be used
}; };
/** /**
......
...@@ -1448,6 +1448,7 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl) ...@@ -1448,6 +1448,7 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
// If in local cache it must be in global // If in local cache it must be in global
if (!cachedImpl) if (!cachedImpl)
abort(); abort();
cachedImpl->m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(cachedImpl); m_globalHash->drop(cachedImpl);
m_globalHash->unlock(); m_globalHash->unlock();
} }
...@@ -1747,8 +1748,8 @@ NdbDictionaryImpl::dropTable(const char * name) ...@@ -1747,8 +1748,8 @@ NdbDictionaryImpl::dropTable(const char * name)
DBUG_PRINT("info",("INCOMPATIBLE_VERSION internal_name: %s", internalTableName)); DBUG_PRINT("info",("INCOMPATIBLE_VERSION internal_name: %s", internalTableName));
m_localHash.drop(internalTableName); m_localHash.drop(internalTableName);
m_globalHash->lock(); m_globalHash->lock();
tab->m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(tab); m_globalHash->drop(tab);
m_globalHash->unlock(); m_globalHash->unlock();
DBUG_RETURN(dropTable(name)); DBUG_RETURN(dropTable(name));
...@@ -1793,9 +1794,10 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl) ...@@ -1793,9 +1794,10 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
if(ret == 0 || m_error.code == 709){ if(ret == 0 || m_error.code == 709){
const char * internalTableName = impl.m_internalName.c_str(); const char * internalTableName = impl.m_internalName.c_str();
m_localHash.drop(internalTableName);
m_localHash.drop(internalTableName);
m_globalHash->lock(); m_globalHash->lock();
impl.m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(&impl); m_globalHash->drop(&impl);
m_globalHash->unlock(); m_globalHash->unlock();
...@@ -1889,6 +1891,7 @@ NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl) ...@@ -1889,6 +1891,7 @@ NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
m_localHash.drop(internalTableName); m_localHash.drop(internalTableName);
m_globalHash->lock(); m_globalHash->lock();
impl.m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(&impl); m_globalHash->drop(&impl);
m_globalHash->unlock(); m_globalHash->unlock();
return 0; return 0;
...@@ -2152,8 +2155,8 @@ NdbDictionaryImpl::dropIndex(const char * indexName, ...@@ -2152,8 +2155,8 @@ NdbDictionaryImpl::dropIndex(const char * indexName,
m_ndb.internalizeTableName(indexName); // Index is also a table m_ndb.internalizeTableName(indexName); // Index is also a table
m_localHash.drop(internalIndexName); m_localHash.drop(internalIndexName);
m_globalHash->lock(); m_globalHash->lock();
idx->m_table->m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(idx->m_table); m_globalHash->drop(idx->m_table);
m_globalHash->unlock(); m_globalHash->unlock();
return dropIndex(indexName, tableName); return dropIndex(indexName, tableName);
...@@ -2187,8 +2190,8 @@ NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName) ...@@ -2187,8 +2190,8 @@ NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
int ret = m_receiver.dropIndex(impl, *timpl); int ret = m_receiver.dropIndex(impl, *timpl);
if(ret == 0){ if(ret == 0){
m_localHash.drop(internalIndexName); m_localHash.drop(internalIndexName);
m_globalHash->lock(); m_globalHash->lock();
impl.m_table->m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(impl.m_table); m_globalHash->drop(impl.m_table);
m_globalHash->unlock(); m_globalHash->unlock();
} }
......
/* Copyright (C) 2000-2003 MySQL AB /* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -331,11 +331,28 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd) ...@@ -331,11 +331,28 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
# The mapped error code # The mapped error code
*/ */
void ha_ndbcluster::invalidateDictionaryCache() void ha_ndbcluster::invalidate_dictionary_cache(bool global)
{ {
NDBDICT *dict= get_ndb()->getDictionary(); NDBDICT *dict= get_ndb()->getDictionary();
DBUG_ENTER("invalidate_dictionary_cache");
DBUG_PRINT("info", ("invalidating %s", m_tabname)); 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); dict->invalidateTable(m_tabname);
}
else
dict->removeCachedTable(m_tabname);
table->version=0L; /* Free when thread is ready */ table->version=0L; /* Free when thread is ready */
/* Invalidate indexes */ /* Invalidate indexes */
for (uint i= 0; i < table->keys; i++) for (uint i= 0; i < table->keys; i++)
...@@ -347,18 +364,28 @@ void ha_ndbcluster::invalidateDictionaryCache() ...@@ -347,18 +364,28 @@ void ha_ndbcluster::invalidateDictionaryCache()
switch(idx_type) { switch(idx_type) {
case(PRIMARY_KEY_ORDERED_INDEX): case(PRIMARY_KEY_ORDERED_INDEX):
case(ORDERED_INDEX): case(ORDERED_INDEX):
if (global)
dict->invalidateIndex(index->getName(), m_tabname); dict->invalidateIndex(index->getName(), m_tabname);
else
dict->removeCachedIndex(index->getName(), m_tabname);
break; break;
case(UNIQUE_ORDERED_INDEX): case(UNIQUE_ORDERED_INDEX):
if (global)
dict->invalidateIndex(index->getName(), m_tabname); dict->invalidateIndex(index->getName(), m_tabname);
else
dict->removeCachedIndex(index->getName(), m_tabname);
case(UNIQUE_INDEX): case(UNIQUE_INDEX):
if (global)
dict->invalidateIndex(unique_index->getName(), m_tabname); dict->invalidateIndex(unique_index->getName(), m_tabname);
else
dict->removeCachedIndex(unique_index->getName(), m_tabname);
break; break;
case(PRIMARY_KEY_INDEX): case(PRIMARY_KEY_INDEX):
case(UNDEFINED_INDEX): case(UNDEFINED_INDEX):
break; break;
} }
} }
DBUG_VOID_RETURN;
} }
int ha_ndbcluster::ndb_err(NdbConnection *trans) int ha_ndbcluster::ndb_err(NdbConnection *trans)
...@@ -371,7 +398,7 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans) ...@@ -371,7 +398,7 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans)
switch (err.classification) { switch (err.classification) {
case NdbError::SchemaError: case NdbError::SchemaError:
{ {
invalidateDictionaryCache(); invalidate_dictionary_cache(TRUE);
if (err.code==284) if (err.code==284)
{ {
...@@ -765,9 +792,16 @@ int ha_ndbcluster::get_metadata(const char *path) ...@@ -765,9 +792,16 @@ int ha_ndbcluster::get_metadata(const char *path)
const void *data, *pack_data; const void *data, *pack_data;
uint length, pack_length; 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))) if (!(tab= dict->getTable(m_tabname)))
ERR_RETURN(dict->getNdbError()); ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion())); DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
}
/* /*
Compare FrmData in NDB with frm file from disk. Compare FrmData in NDB with frm file from disk.
*/ */
...@@ -786,7 +820,7 @@ int ha_ndbcluster::get_metadata(const char *path) ...@@ -786,7 +820,7 @@ int ha_ndbcluster::get_metadata(const char *path)
if (!invalidating_ndb_table) if (!invalidating_ndb_table)
{ {
DBUG_PRINT("info", ("Invalidating table")); DBUG_PRINT("info", ("Invalidating table"));
invalidateDictionaryCache(); invalidate_dictionary_cache(TRUE);
invalidating_ndb_table= TRUE; invalidating_ndb_table= TRUE;
} }
else else
...@@ -812,7 +846,7 @@ int ha_ndbcluster::get_metadata(const char *path) ...@@ -812,7 +846,7 @@ int ha_ndbcluster::get_metadata(const char *path)
if (error) if (error)
DBUG_RETURN(error); DBUG_RETURN(error);
m_tableVersion= tab->getObjectVersion(); m_table_version= tab->getObjectVersion();
m_table= (void *)tab; m_table= (void *)tab;
m_table_info= NULL; // Set in external lock m_table_info= NULL; // Set in external lock
...@@ -3226,15 +3260,25 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ...@@ -3226,15 +3260,25 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
void *tab_info; void *tab_info;
if (!(tab= dict->getTable(m_tabname, &tab_info))) if (!(tab= dict->getTable(m_tabname, &tab_info)))
ERR_RETURN(dict->getNdbError()); ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion())); DBUG_PRINT("info", ("Table schema version: %d",
if (m_table != (void *)tab || m_tableVersion != tab->getObjectVersion()) 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, &tab_info)))
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 The table has been altered, refresh the index list
*/ */
build_index_list(ndb, table, ILBP_OPEN); build_index_list(ndb, table, ILBP_OPEN);
m_table= (void *)tab; m_table= (void *)tab;
m_tableVersion = tab->getObjectVersion(); m_table_version = tab->getObjectVersion();
} }
m_table_info= tab_info; m_table_info= tab_info;
} }
...@@ -3260,7 +3304,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ...@@ -3260,7 +3304,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
thd->transaction.stmt.ndb_tid= 0; thd->transaction.stmt.ndb_tid= 0;
} }
} }
m_table= NULL;
m_table_info= NULL; m_table_info= NULL;
/* /*
This is the place to make sure this handler instance 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) ...@@ -3882,7 +3925,13 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
dict= ndb->getDictionary(); dict= ndb->getDictionary();
if (!(orig_tab= dict->getTable(m_tabname))) if (!(orig_tab= dict->getTable(m_tabname)))
ERR_RETURN(dict->getNdbError()); 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; m_table= (void *)orig_tab;
// Change current database to that of target table // Change current database to that of target table
set_dbname(to); set_dbname(to);
...@@ -4006,7 +4055,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): ...@@ -4006,7 +4055,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
m_active_trans(NULL), m_active_trans(NULL),
m_active_cursor(NULL), m_active_cursor(NULL),
m_table(NULL), m_table(NULL),
m_tableVersion(-1), m_table_version(-1),
m_table_info(NULL), m_table_info(NULL),
m_table_flags(HA_REC_NOT_IN_SEQ | m_table_flags(HA_REC_NOT_IN_SEQ |
HA_NULL_IN_KEY | HA_NULL_IN_KEY |
...@@ -4250,7 +4299,6 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name, ...@@ -4250,7 +4299,6 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
DBUG_RETURN(1); DBUG_RETURN(1);
ERR_RETURN(err); ERR_RETURN(err);
} }
DBUG_PRINT("info", ("Found table %s", tab->getName())); DBUG_PRINT("info", ("Found table %s", tab->getName()));
len= tab->getFrmLength(); len= tab->getFrmLength();
...@@ -4327,6 +4375,7 @@ int ndbcluster_drop_database(const char *path) ...@@ -4327,6 +4375,7 @@ int ndbcluster_drop_database(const char *path)
uint i; uint i;
char *tabname; char *tabname;
List<char> drop_list; List<char> drop_list;
int ret= 0;
ha_ndbcluster::set_dbname(path, (char *)&dbname); ha_ndbcluster::set_dbname(path, (char *)&dbname);
DBUG_PRINT("enter", ("db: %s", dbname)); DBUG_PRINT("enter", ("db: %s", dbname));
...@@ -4353,10 +4402,18 @@ int ndbcluster_drop_database(const char *path) ...@@ -4353,10 +4402,18 @@ int ndbcluster_drop_database(const char *path)
ndb->setDatabaseName(dbname); ndb->setDatabaseName(dbname);
List_iterator_fast<char> it(drop_list); List_iterator_fast<char> it(drop_list);
while ((tabname=it++)) while ((tabname=it++))
{
if (dict->dropTable(tabname)) if (dict->dropTable(tabname))
ERR_RETURN(dict->getNdbError()); {
const NdbError err= dict->getNdbError();
DBUG_RETURN(0); if (err.code != 709)
{
ERR_PRINT(err);
ret= ndb_to_mysql_error(&err);
}
}
}
DBUG_RETURN(ret);
} }
......
...@@ -203,7 +203,7 @@ class ha_ndbcluster: public handler ...@@ -203,7 +203,7 @@ class ha_ndbcluster: public handler
void print_results(); void print_results();
longlong get_auto_increment(); longlong get_auto_increment();
void invalidateDictionaryCache(); void invalidate_dictionary_cache(bool global);
int ndb_err(NdbConnection*); int ndb_err(NdbConnection*);
bool uses_blob_value(bool all_fields); bool uses_blob_value(bool all_fields);
...@@ -215,7 +215,7 @@ class ha_ndbcluster: public handler ...@@ -215,7 +215,7 @@ class ha_ndbcluster: public handler
NdbConnection *m_active_trans; NdbConnection *m_active_trans;
NdbResultSet *m_active_cursor; NdbResultSet *m_active_cursor;
void *m_table; void *m_table;
int m_tableVersion; int m_table_version;
void *m_table_info; void *m_table_info;
char m_dbname[FN_HEADLEN]; char m_dbname[FN_HEADLEN];
//char m_schemaname[FN_HEADLEN]; //char m_schemaname[FN_HEADLEN];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment