diff --git a/storage/ndb/plugin/ha_ndbcluster_binlog.cc b/storage/ndb/plugin/ha_ndbcluster_binlog.cc index 3a24fd8adaff..6b0162274efa 100644 --- a/storage/ndb/plugin/ha_ndbcluster_binlog.cc +++ b/storage/ndb/plugin/ha_ndbcluster_binlog.cc @@ -1240,18 +1240,13 @@ static void ndbcluster_binlog_event_operation_teardown(THD *thd, Ndb *is_ndb, Ndb_event_data::get_event_data(pOp->getCustomData()); NDB_SHARE *const share = event_data->share; - // Invalidate any cached NdbApi table if object version is lower - // than what was used when setting up the NdbEventOperation - // NOTE! This functionality need to be explained further { - Thd_ndb *thd_ndb = get_thd_ndb(thd); - Ndb *ndb = thd_ndb->ndb; - Ndb_table_guard ndbtab_g(ndb, share->db, share->table_name); - const NDBTAB *ev_tab = pOp->getTable(); - const NDBTAB *cache_tab = ndbtab_g.get_table(); - if (cache_tab && cache_tab->getObjectId() == ev_tab->getObjectId() && - cache_tab->getObjectVersion() <= ev_tab->getObjectVersion()) + // Since table has been dropped or cluster connection lost the NdbApi table + // should be invalidated in the global dictionary cache + Ndb_table_guard ndbtab_g(is_ndb, share->db, share->table_name); + if (ndbtab_g.get_table()) { ndbtab_g.invalidate(); + } } // Close the table in MySQL Server @@ -3198,6 +3193,8 @@ class Ndb_schema_event_handler { if (schema->node_id == own_nodeid()) return; write_schema_op_to_binlog(m_thd, schema); + ndbapi_invalidate_table(schema->db, schema->name); + ndb_tdc_close_cached_table(m_thd, schema->db, schema->name); if (!create_table_from_engine(schema->db, schema->name, true, /* force_overwrite */ @@ -5058,6 +5055,12 @@ static int ndbcluster_setup_binlog_for_share(THD *thd, Ndb *ndb, return -1; } } + // The function that check if event exist will silently mark the NDB table + // definition as 'Invalid' when the event's table version does not match the + // cached NDB table definitions version. This indicates that the caller have + // used a stale version of the NDB table definition and is a problem which + // has to be fixed by the caller of this function. + assert(ndbtab->getObjectStatus() != NdbDictionary::Object::Invalid); if (share->have_event_operation()) { DBUG_PRINT("info", ("binlogging already setup")); diff --git a/storage/ndb/plugin/ndb_dd_sync.cc b/storage/ndb/plugin/ndb_dd_sync.cc index bf0281ed7d90..aa775d2cdaac 100644 --- a/storage/ndb/plugin/ndb_dd_sync.cc +++ b/storage/ndb/plugin/ndb_dd_sync.cc @@ -1187,6 +1187,12 @@ bool Ndb_dd_sync::synchronize_table(const char *schema_name, const char *table_name) const { ndb_log_verbose(1, "Synchronizing table '%s.%s'", schema_name, table_name); + { + // Invalidate potentially stale cached table + Ndb_table_guard ndbtab_g(m_thd_ndb->ndb, schema_name, table_name); + ndbtab_g.invalidate(); + } + Ndb_table_guard ndbtab_g(m_thd_ndb->ndb, schema_name, table_name); const NdbDictionary::Table *ndbtab = ndbtab_g.get_table(); if (!ndbtab) { diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 0c62ebf5505f..0c9bbb50bcf1 100644 --- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -5466,6 +5466,10 @@ NdbEventImpl *NdbDictionaryImpl::getEvent(const char *eventName, ((Uint32)tab->m_id != ev->m_table_id) || (table_version_major(tab->m_version) != table_version_major(ev->m_table_version))) { + // Table id or version does not match the table in the NdbApi dict cache, + // the cached table is invalidated and fetched from NDB again. For NdbApi + // user this have the effect that a different version of the table is used + // after calling NdbApi event functions. DBUG_PRINT("info", ("mismatch on verison in cache")); releaseTableGlobal(*tab, 1); tab = fetchGlobalTableImplRef(InitTable(ev->getTableName()));