Skip to content

Commit ac9cc54

Browse files
committed
Bug#35948153 Problem setting up events due to stale NdbApi dictionary
cache [#2] This is second patch, solving the problem of ineffiecent cache invalidation when invalidating a table which is known to be invalid but unknown if it is in the cache or not. Problem: Currently the only way to invalidate a table in the NdbApi dictionary cache is to open the table and then mark it as invalid. In case the table does not exists in the cache, it will still have to be opened and thus fetched fom NDB. This means that in order to get the latest table definition it has to be fetched two times, although the table definition does not already exist in the cache. This is inefficient. Analysis: In order to avoid the double roundtrip there need to be a function which marks the table as invalid only if it exists in the cache. Fix: Implement a NdbApi function that invalidates table by name if it exists in the cache. Replace the old pattern of opening table in order to invalidate it with the new function. The old pattern is still a valid use case for invalidating a table after having worked with it. Change-Id: I20f275f1fed76d991330348bea4ae72548366467
1 parent 48a8f44 commit ac9cc54

File tree

12 files changed

+93
-26
lines changed

12 files changed

+93
-26
lines changed

storage/ndb/include/ndbapi/Ndb.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,6 +2213,9 @@ class Ndb {
22132213

22142214
static const char *externalizeTableName(const char *internalTableName,
22152215
bool fullyQualifiedNames);
2216+
static BaseString internalize_table_name(const char *db_name,
2217+
const char *schema,
2218+
const char *table_name);
22162219
const BaseString internalize_table_name(const char *external_name) const;
22172220

22182221
static const char *externalizeIndexName(const char *internalIndexName,

storage/ndb/include/ndbapi/NdbDictionary.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2916,6 +2916,9 @@ class NdbDictionary {
29162916
int removeIndexGlobal(const Index &ndbidx, int invalidate) const;
29172917
int removeTableGlobal(const Table &ndbtab, int invalidate) const;
29182918
void invalidateDbGlobal(const char *dbname);
2919+
// Invalidate table by name if it exist in the cache
2920+
void invalidateTableGlobal(const char *dbName, const char *schemaName,
2921+
const char *tableName);
29192922
#endif
29202923

29212924
/*

storage/ndb/plugin/ha_ndbcluster_binlog.cc

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,14 +1240,9 @@ static void ndbcluster_binlog_event_operation_teardown(THD *thd, Ndb *is_ndb,
12401240
Ndb_event_data::get_event_data(pOp->getCustomData());
12411241
NDB_SHARE *const share = event_data->share;
12421242

1243-
{
1244-
// Since table has been dropped or cluster connection lost the NdbApi table
1245-
// should be invalidated in the global dictionary cache
1246-
Ndb_table_guard ndbtab_g(is_ndb, share->db, share->table_name);
1247-
if (ndbtab_g.get_table()) {
1248-
ndbtab_g.invalidate();
1249-
}
1250-
}
1243+
// Since table has been dropped or cluster connection lost the NdbApi table
1244+
// should be invalidated in the global dictionary cache
1245+
Ndb_table_guard::invalidate_table(is_ndb, share->db, share->table_name);
12511246

12521247
// Close the table in MySQL Server
12531248
ndb_tdc_close_cached_table(thd, share->db, share->table_name);
@@ -2298,8 +2293,7 @@ class Ndb_schema_event_handler {
22982293
void ndbapi_invalidate_table(const char *db_name,
22992294
const char *table_name) const {
23002295
DBUG_TRACE;
2301-
Ndb_table_guard ndbtab_g(m_thd_ndb->ndb, db_name, table_name);
2302-
ndbtab_g.invalidate();
2296+
Ndb_table_guard::invalidate_table(m_thd_ndb->ndb, db_name, table_name);
23032297
}
23042298

23052299
NDB_SHARE *acquire_reference(const char *db, const char *name,

storage/ndb/plugin/ndb_dd_sync.cc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,11 +1187,8 @@ bool Ndb_dd_sync::synchronize_table(const char *schema_name,
11871187
const char *table_name) const {
11881188
ndb_log_verbose(1, "Synchronizing table '%s.%s'", schema_name, table_name);
11891189

1190-
{
1191-
// Invalidate potentially stale cached table
1192-
Ndb_table_guard ndbtab_g(m_thd_ndb->ndb, schema_name, table_name);
1193-
ndbtab_g.invalidate();
1194-
}
1190+
// Invalidate potentially stale cached table
1191+
Ndb_table_guard::invalidate_table(m_thd_ndb->ndb, schema_name, table_name);
11951192

11961193
Ndb_table_guard ndbtab_g(m_thd_ndb->ndb, schema_name, table_name);
11971194
const NdbDictionary::Table *ndbtab = ndbtab_g.get_table();

storage/ndb/plugin/ndb_metadata_sync.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -912,8 +912,8 @@ bool Ndb_metadata_sync::sync_table(THD *thd, const std::string &schema_name,
912912
table_name.c_str());
913913

914914
// Invalidate the table in NdbApi
915-
Ndb_table_guard ndbtab_guard(ndb, schema_name.c_str(), table_name.c_str());
916-
ndbtab_guard.invalidate();
915+
Ndb_table_guard::invalidate_table(ndb, schema_name.c_str(),
916+
table_name.c_str());
917917
return true;
918918
}
919919

storage/ndb/plugin/ndb_table_guard.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,18 @@ class Ndb_table_guard {
186186
}
187187

188188
const NdbError &getNdbError() const { return m_ndberror; }
189+
190+
/**
191+
@brief Invalidate table in the global dictionary cache (if it exists)
192+
without fetching table from NDB on cache miss, this saves one roundtrip.
193+
194+
This function is to be used to invalidate table when it's not already being
195+
held open.
196+
*/
197+
static void invalidate_table(Ndb *ndb, const char *dbname,
198+
const char *tabname) {
199+
ndb->getDictionary()->invalidateTableGlobal(dbname, "def", tabname);
200+
}
189201
};
190202

191203
#endif

storage/ndb/src/ndbapi/DictCache.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,35 @@ void GlobalDictCache::invalidateDb(const char *name, size_t len) {
360360
DBUG_VOID_RETURN;
361361
}
362362

363+
void GlobalDictCache::invalidateTable(const BaseString &internal_name) {
364+
DBUG_TRACE;
365+
DBUG_PRINT("enter", ("internal_name: '%s'", internal_name.c_str()));
366+
Vector<TableVersion> *vers =
367+
m_tableHash.getData(internal_name.c_str(), internal_name.length());
368+
if (vers == nullptr) {
369+
DBUG_PRINT("exit", ("nothing cached"));
370+
return;
371+
}
372+
373+
if (vers->size() == 0) {
374+
DBUG_PRINT("exit", ("no cached versions"));
375+
return;
376+
}
377+
378+
TableVersion *const ver = &vers->back();
379+
if (ver->m_status == RETREIVING) {
380+
DBUG_PRINT("exit", ("fresh version on the way"));
381+
return;
382+
}
383+
384+
ver->m_impl->m_status = NdbDictionary::Object::Invalid;
385+
ver->m_status = DROPPED;
386+
if (ver->m_refCount == 0) {
387+
delete ver->m_impl;
388+
vers->erase(vers->size() - 1);
389+
}
390+
}
391+
363392
void GlobalDictCache::release(const NdbTableImpl *tab, int invalidate) {
364393
DBUG_ENTER("GlobalDictCache::release");
365394
DBUG_PRINT("enter",

storage/ndb/src/ndbapi/DictCache.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class GlobalDictCache : public NdbLockable {
9494
}
9595

9696
void invalidateDb(const char *name, size_t len);
97+
void invalidateTable(const BaseString &name);
9798

9899
public:
99100
enum Status { OK = 0, DROPPED = 1, RETREIVING = 2 };

storage/ndb/src/ndbapi/Ndb.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,9 +1733,21 @@ const char *Ndb::externalizeIndexName(const char *internalIndexName,
17331733
}
17341734
}
17351735

1736+
// Format internal name from db, schema and table name
1737+
BaseString Ndb::internalize_table_name(const char *db_name, const char *schema,
1738+
const char *table_name) {
1739+
BaseString internal_name;
1740+
// Internal table name format <db>/<schema>/<table>
1741+
internal_name.assfmt("%s%c%s%c%s", db_name, table_name_separator, schema,
1742+
table_name_separator, table_name);
1743+
1744+
DBUG_PRINT("exit", ("internal_name: %s", internal_name.c_str()));
1745+
return internal_name;
1746+
}
1747+
1748+
// Format internal name using schema and db name from the Ndb object
17361749
const BaseString Ndb::internalize_table_name(const char *external_name) const {
1737-
BaseString ret;
1738-
DBUG_ENTER("internalize_table_name");
1750+
DBUG_TRACE;
17391751
DBUG_PRINT("enter", ("external_name: %s", external_name));
17401752

17411753
#ifdef VM_TRACE
@@ -1744,13 +1756,8 @@ const BaseString Ndb::internalize_table_name(const char *external_name) const {
17441756
assert(theImpl->m_schemaname.length());
17451757
#endif
17461758

1747-
// Internal table name format <db>/<schema>/<table>
1748-
ret.assfmt("%s%c%s%c%s", theImpl->m_dbname.c_str(), table_name_separator,
1749-
theImpl->m_schemaname.c_str(), table_name_separator,
1750-
external_name);
1751-
1752-
DBUG_PRINT("exit", ("internal_name: %s", ret.c_str()));
1753-
DBUG_RETURN(ret);
1759+
return internalize_table_name(theImpl->m_dbname.c_str(),
1760+
theImpl->m_schemaname.c_str(), external_name);
17541761
}
17551762

17561763
const BaseString Ndb::getDatabaseFromInternalName(const char *internalName) {

storage/ndb/src/ndbapi/NdbDictionary.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3125,6 +3125,12 @@ void NdbDictionary::Dictionary::invalidateDbGlobal(const char *name) {
31253125
}
31263126
}
31273127

3128+
void NdbDictionary::Dictionary::invalidateTableGlobal(const char *dbName,
3129+
const char *schemaName,
3130+
const char *tableName) {
3131+
m_impl.invalidateTableGlobal(dbName, schemaName, tableName);
3132+
}
3133+
31283134
int NdbDictionary::Dictionary::beginSchemaTrans() {
31293135
return m_impl.beginSchemaTrans();
31303136
}

storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5053,6 +5053,19 @@ int NdbDictionaryImpl::dropIndexGlobal(NdbIndexImpl &impl, bool ignoreFKs) {
50535053
ERR_RETURN(getNdbError(), ret);
50545054
}
50555055

5056+
void NdbDictionaryImpl::invalidateTableGlobal(const char *dbName,
5057+
const char *schemaName,
5058+
const char *tableName) {
5059+
DBUG_TRACE;
5060+
if (!m_globalHash) return;
5061+
5062+
BaseString internalName(
5063+
Ndb::internalize_table_name(dbName, schemaName, tableName));
5064+
m_globalHash->lock();
5065+
m_globalHash->invalidateTable(internalName);
5066+
m_globalHash->unlock();
5067+
}
5068+
50565069
int NdbDictInterface::dropIndex(const NdbTableImpl &timpl) {
50575070
DBUG_ENTER("NdbDictInterface::dropIndex");
50585071
DBUG_PRINT("enter",

storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,8 @@ class NdbDictionaryImpl : public NdbDictionary::Dictionary {
965965
int dropIndexGlobal(NdbIndexImpl &, bool ignoreFKs);
966966
int releaseTableGlobal(const NdbTableImpl &impl, int invalidate);
967967
int releaseIndexGlobal(const NdbIndexImpl &impl, int invalidate);
968+
void invalidateTableGlobal(const char *dbName, const char *schemaName,
969+
const char *tableName);
968970

969971
NdbTableImpl *getTable(const char *tableName, void **data = nullptr);
970972
NdbTableImpl *getBlobTable(const NdbTableImpl &, uint col_no);

0 commit comments

Comments
 (0)