summaryrefslogtreecommitdiff
path: root/sql/ha_ndbcluster.cc
diff options
context:
space:
mode:
authorunknown <tomas@poseidon.ndb.mysql.com>2006-04-19 14:54:39 +0200
committerunknown <tomas@poseidon.ndb.mysql.com>2006-04-19 14:54:39 +0200
commit37fdc236722d6c8fd7579717ce888d7156d7c2c7 (patch)
treebb379aa90d42b9db5e969a1b761f4697362ddfde /sql/ha_ndbcluster.cc
parent1a18a365cb755588d7586b7a3fa71ff220125006 (diff)
downloadmariadb-git-37fdc236722d6c8fd7579717ce888d7156d7c2c7.tar.gz
BUG#18094 Slave caches invalid table definition after atlters causes select failure
- return correct object status from ndb dictionary - check for validity of index retrieved from index, and retry if invalid
Diffstat (limited to 'sql/ha_ndbcluster.cc')
-rw-r--r--sql/ha_ndbcluster.cc84
1 files changed, 58 insertions, 26 deletions
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 587eabb82d2..1ccd080aa5a 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -466,7 +466,7 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
# The mapped error code
*/
-int ha_ndbcluster::invalidate_dictionary_cache(bool global)
+int ha_ndbcluster::invalidate_dictionary_cache(bool global, const NDBTAB *ndbtab)
{
NDBDICT *dict= get_ndb()->getDictionary();
DBUG_ENTER("invalidate_dictionary_cache");
@@ -494,20 +494,17 @@ int ha_ndbcluster::invalidate_dictionary_cache(bool global)
DBUG_PRINT("info", ("Released ndbcluster mutex"));
}
#endif
- const NDBTAB *tab= dict->getTable(m_tabname);
- if (!tab)
- DBUG_RETURN(1);
- if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
+ if (!ndbtab)
{
- // Global cache has already been invalidated
- dict->removeCachedTable(m_tabname);
- global= FALSE;
- DBUG_PRINT("info", ("global: %d", global));
+ ndbtab= dict->getTable(m_tabname);
+ if (!ndbtab)
+ DBUG_RETURN(1);
}
- else
- dict->invalidateTable(m_tabname);
+ dict->invalidateTable(ndbtab);
table_share->version= 0L; /* Free when thread is ready */
}
+ else if (ndbtab)
+ dict->removeCachedTable(ndbtab);
else
dict->removeCachedTable(m_tabname);
@@ -564,7 +561,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
table_list.alias= table_list.table_name= m_tabname;
close_cached_tables(current_thd, 0, &table_list);
- invalidate_dictionary_cache(TRUE);
+ invalidate_dictionary_cache(TRUE, m_table);
if (err.code==284)
{
@@ -1041,7 +1038,7 @@ int ha_ndbcluster::get_metadata(const char *path)
// Check if thread has stale local cache
if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
{
- invalidate_dictionary_cache(FALSE);
+ invalidate_dictionary_cache(FALSE, tab);
if (!(tab= dict->getTable(m_tabname)))
ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
@@ -1064,7 +1061,7 @@ int ha_ndbcluster::get_metadata(const char *path)
if (!invalidating_ndb_table)
{
DBUG_PRINT("info", ("Invalidating table"));
- invalidate_dictionary_cache(TRUE);
+ invalidate_dictionary_cache(TRUE, tab);
invalidating_ndb_table= TRUE;
}
else
@@ -1091,7 +1088,7 @@ int ha_ndbcluster::get_metadata(const char *path)
DBUG_RETURN(error);
m_table_version= tab->getObjectVersion();
- m_table= (void *)tab;
+ m_table= tab;
m_table_info= NULL; // Set in external lock
DBUG_RETURN(open_indexes(ndb, table, FALSE));
@@ -1150,7 +1147,7 @@ int ha_ndbcluster::table_changed(const void *pack_frm_data, uint pack_frm_len)
// Check if thread has stale local cache
if (orig_tab->getObjectStatus() == NdbDictionary::Object::Invalid)
{
- dict->removeCachedTable(m_tabname);
+ dict->removeCachedTable(orig_tab);
if (!(orig_tab= dict->getTable(m_tabname)))
ERR_RETURN(dict->getNdbError());
}
@@ -1219,13 +1216,31 @@ int ha_ndbcluster::add_index_handle(THD *thd, NDBDICT *dict, KEY *key_info,
int error= 0;
NDB_INDEX_TYPE idx_type= get_index_type_from_table(index_no);
m_index[index_no].type= idx_type;
- DBUG_ENTER("ha_ndbcluster::get_index_handle");
+ DBUG_ENTER("ha_ndbcluster::add_index_handle");
+ DBUG_PRINT("enter", ("table %s", m_tabname));
if (idx_type != PRIMARY_KEY_INDEX && idx_type != UNIQUE_INDEX)
{
DBUG_PRINT("info", ("Get handle to index %s", index_name));
- const NDBINDEX *index= dict->getIndex(index_name, m_tabname);
- if (!index) ERR_RETURN(dict->getNdbError());
+ const NDBINDEX *index;
+ do
+ {
+ index= dict->getIndex(index_name, m_tabname);
+ if (!index)
+ ERR_RETURN(dict->getNdbError());
+ DBUG_PRINT("info", ("index: 0x%x id: %d version: %d.%d status: %d",
+ index,
+ index->getObjectId(),
+ index->getObjectVersion() & 0xFFFFFF,
+ index->getObjectVersion() >> 24,
+ index->getObjectStatus()));
+ if (index->getObjectStatus() != NdbDictionary::Object::Retrieved)
+ {
+ dict->removeCachedIndex(index);
+ continue;
+ }
+ break;
+ } while (1);
m_index[index_no].index= (void *) index;
// ordered index - add stats
NDB_INDEX_DATA& d=m_index[index_no];
@@ -1254,8 +1269,25 @@ int ha_ndbcluster::add_index_handle(THD *thd, NDBDICT *dict, KEY *key_info,
m_has_unique_index= TRUE;
strxnmov(unique_index_name, FN_LEN, index_name, unique_suffix, NullS);
DBUG_PRINT("info", ("Get handle to unique_index %s", unique_index_name));
- const NDBINDEX *index= dict->getIndex(unique_index_name, m_tabname);
- if (!index) ERR_RETURN(dict->getNdbError());
+ const NDBINDEX *index;
+ do
+ {
+ index= dict->getIndex(unique_index_name, m_tabname);
+ if (!index)
+ ERR_RETURN(dict->getNdbError());
+ DBUG_PRINT("info", ("index: 0x%x id: %d version: %d.%d status: %d",
+ index,
+ index->getObjectId(),
+ index->getObjectVersion() & 0xFFFFFF,
+ index->getObjectVersion() >> 24,
+ index->getObjectStatus()));
+ if (index->getObjectStatus() != NdbDictionary::Object::Retrieved)
+ {
+ dict->removeCachedIndex(index);
+ continue;
+ }
+ break;
+ } while (1);
m_index[index_no].unique_index= (void *) index;
error= fix_unique_index_attr_order(m_index[index_no], index, key_info);
}
@@ -3954,7 +3986,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
if ((trans && tab->getObjectStatus() != NdbDictionary::Object::Retrieved)
|| tab->getObjectStatus() == NdbDictionary::Object::Invalid)
{
- invalidate_dictionary_cache(FALSE);
+ invalidate_dictionary_cache(FALSE, tab);
if (!(tab= dict->getTable(m_tabname, &tab_info)))
ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d",
@@ -3970,7 +4002,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
}
if (m_table != (void *)tab)
{
- m_table= (void *)tab;
+ m_table= tab;
m_table_version = tab->getObjectVersion();
if (!(my_errno= open_indexes(ndb, table, FALSE)))
DBUG_RETURN(my_errno);
@@ -4990,7 +5022,7 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
// Check if thread has stale local cache
if (orig_tab->getObjectStatus() == NdbDictionary::Object::Invalid)
{
- dict->removeCachedTable(m_tabname);
+ dict->removeCachedTable(orig_tab);
if (!(orig_tab= dict->getTable(m_tabname)))
ERR_RETURN(dict->getNdbError());
}
@@ -5002,7 +5034,7 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
DBUG_ASSERT(r == 0);
}
#endif
- m_table= (void *)orig_tab;
+ m_table= orig_tab;
// Change current database to that of target table
set_dbname(to);
ndb->setDatabaseName(m_dbname);
@@ -9988,7 +10020,7 @@ bool ha_ndbcluster::get_no_parts(const char *name, uint *no_parts)
// Check if thread has stale local cache
if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
{
- invalidate_dictionary_cache(FALSE);
+ invalidate_dictionary_cache(FALSE, tab);
if (!(tab= dict->getTable(m_tabname)))
ERR_BREAK(dict->getNdbError(), err);
}