1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-06-15 03:21:42 +03:00

MCOL-5306 Re-read the config (Columnstore.xml) file if it was updated.

The existing implementation of Config::makeConfig() factory method
was returning a possibly stale config to the caller, without checking
if the config file was updated since the last read. This bug triggered
a scenario as described in MCOL-5306 where after a failover in an MCS
cluster, the controllernode coordinates changed in the config file
after failover and the existing mariadbd process was still using the
old controllernode coordinates. This lead to failed network connection
between mariadbd and the new controllernode.

The change in this fix, however, is more generic and not just limited
to this above scenario.
This commit is contained in:
Gagan Goel
2022-12-02 06:30:46 +00:00
parent b63efe0103
commit 9bf35d74d4
2 changed files with 37 additions and 39 deletions

View File

@ -83,6 +83,21 @@ boost::mutex Config::fXmlLock;
boost::mutex Config::fWriteXmlLock;
std::atomic_bool globHasConfig;
void Config::checkAndReloadConfig()
{
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
}
Config* Config::makeConfig(const string& cf)
{
if (cf.empty() || cf == configDefaultFileName)
@ -93,22 +108,35 @@ Config* Config::makeConfig(const string& cf)
// this scope.
boost::mutex::scoped_lock lk(fInstanceMapMutex);
if (globConfigInstancePtr)
{
globConfigInstancePtr->checkAndReloadConfig();
return globConfigInstancePtr;
}
// Make this configurable at least at compile-time.
std::string configFilePath =
std::string(MCSSYSCONFDIR) + std::string("/columnstore/") + configDefaultFileName;
globConfigInstancePtr = new Config(configFilePath);
globHasConfig.store(true, std::memory_order_relaxed);
return globConfigInstancePtr;
}
boost::mutex::scoped_lock lk(fInstanceMapMutex);
globConfigInstancePtr->checkAndReloadConfig();
return globConfigInstancePtr;
}
boost::mutex::scoped_lock lk(fInstanceMapMutex);
if (fInstanceMap.find(cf) == fInstanceMap.end())
{
fInstanceMap[cf] = new Config(cf);
}
else
{
fInstanceMap[cf]->checkAndReloadConfig();
}
return fInstanceMap[cf];
}
@ -256,12 +284,7 @@ const string Config::getFromActualConfig(const string& section, const string& na
boost::recursive_mutex::scoped_lock lk(fLock);
// To protect the potential race that happens right after
// the config was changed.
if (!stat(fConfigFile.c_str(), &statbuf) && statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
checkAndReloadConfig();
}
}
@ -312,17 +335,7 @@ void Config::delConfig(const string& section, const string& name)
throw runtime_error("Config::delConfig: no XML document!");
}
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
checkAndReloadConfig();
fParser.delConfig(fDoc, section, name);
return;
@ -627,17 +640,7 @@ const vector<string> Config::enumConfig()
throw runtime_error("Config::getConfig: no XML document!");
}
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
checkAndReloadConfig();
return fParser.enumConfig(fDoc);
}
@ -652,17 +655,7 @@ const vector<string> Config::enumSection(const string& section)
throw runtime_error("Config::getConfig: no XML document!");
}
struct stat statbuf;
if (stat(fConfigFile.c_str(), &statbuf) == 0)
{
if (statbuf.st_mtime != fMtime)
{
closeConfig();
fMtime = statbuf.st_mtime;
parseDoc();
}
}
checkAndReloadConfig();
return fParser.enumSection(fDoc, section);
}