Skip to content

Commit 1750ea4

Browse files
blauddennawazn
authored andcommitted
Bug#34843889 Handle temporary error during load table
Temporary errors can occur while opening a table from the NDB dictionary, this kind of error is rare but can be provoked by repeatedly performing schema operations. Since failing to open the NDB table definition most often causes fatal errors down the line, it's most likely better to take some time and attempt to resolve the temporary error by retrying to open the table. These kind of temporary errors are primarily important to get rid of when distributing schema operations throughout the cluster, where many MySQL Server simultaneously attempts to open table from NDB. Fix by handling temporary errors while opening table from NDB with retry. It is acceptable with some delays during these operations in order for temporary resource shortages to subside while opening tables. Change-Id: Ie26426d7f4892828d1e759d131fdbda810a5c846
1 parent ed273ab commit 1750ea4

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

storage/ndb/plugin/ndb_table_guard.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "storage/ndb/include/ndbapi/Ndb.hpp"
3232
#include "storage/ndb/include/ndbapi/NdbDictionary.hpp"
3333
#include "storage/ndb/plugin/ndb_dbname_guard.h"
34+
#include "storage/ndb/plugin/ndb_sleep.h"
3435

3536
/*
3637
@brief This class maintains the reference to a NDB table definition retrieved
@@ -81,11 +82,47 @@ class Ndb_table_guard {
8182
return;
8283
}
8384

85+
/**
86+
@brief Initialize the NDB Dictionary table by loading it from NDB while
87+
handling temporary errors by retrying a few times
88+
89+
@param dbname The database name of table to load
90+
@param tabname The table name of table to load
91+
*/
8492
void init(const char *dbname, const char *tabname) {
8593
DBUG_TRACE;
8694
/* Don't allow init() if already initialized */
8795
assert(m_ndbtab == nullptr);
8896

97+
int attempt = 1;
98+
constexpr int retries = 10;
99+
do {
100+
open_table_from_NDB(dbname, tabname);
101+
if (m_ndbtab) {
102+
// Successfully loaded table
103+
return;
104+
}
105+
// Expect error to be set
106+
assert(m_ndberror.code != 0);
107+
108+
if (m_ndberror.status != NdbError::TemporaryError) {
109+
// Not an error that should be retried
110+
return;
111+
}
112+
113+
attempt++;
114+
ndb_retry_sleep(50);
115+
116+
} while (attempt < retries);
117+
118+
// Failed to load table
119+
assert(m_ndbtab == nullptr && m_ndberror.code != 0);
120+
}
121+
122+
void open_table_from_NDB(const char *dbname, const char *tabname) {
123+
DBUG_TRACE;
124+
assert(m_ndbtab == nullptr);
125+
89126
// Change to the database where the table should be found
90127
Ndb_dbname_guard dbname_guard(m_ndb, dbname);
91128
if (dbname_guard.change_database_failed()) {

0 commit comments

Comments
 (0)