Keep connections older than 6.2 open indefinitely to avoid weird bugs around quickly closing the database.

This commit is contained in:
A.J. Beamon 2021-04-27 15:00:56 -07:00
parent 9009780aa8
commit 16dfb2b2f2
3 changed files with 29 additions and 5 deletions

View File

@ -892,15 +892,26 @@ MultiVersionDatabase::MultiVersionDatabase(MultiVersionApi* api,
dbState->addClient(api->getLocalClient());
}
api->runOnExternalClients(threadIdx, [this](Reference<ClientInfo> client) { dbState->addClient(client); });
if (!externalClientsInitialized.test_and_set()) {
api->runOnExternalClientsAllThreads([&clusterFilePath](Reference<ClientInfo> client) {
// This creates a database to initialize some client state on the external library,
// but it gets deleted immediately so that we don't keep open connections
// This creates a database to initialize some client state on the external library
// We only do this on 6.2+ clients to avoid some bugs associated with older versions
// This deletes the new database immediately to discard its connections
if (client->protocolVersion.hasCloseUnusedConnection()) {
Reference<IDatabase> newDb = client->api->createDatabase(clusterFilePath.c_str());
}
});
}
api->runOnExternalClients(threadIdx, [this](Reference<ClientInfo> client) { dbState->addClient(client); });
// For clients older than 6.2 we create and maintain our database connection
api->runOnExternalClients(threadIdx, [this, &clusterFilePath](Reference<ClientInfo> client) {
if (!client->protocolVersion.hasCloseUnusedConnection()) {
dbState->legacyDatabaseConnections[client->protocolVersion] =
client->api->createDatabase(clusterFilePath.c_str());
}
});
onMainThreadVoid([this]() { dbState->protocolVersionMonitor = dbState->monitorProtocolVersion(); }, nullptr);
}
@ -1158,7 +1169,10 @@ void MultiVersionDatabase::LegacyVersionMonitor::startConnectionMonitor(
if (!monitorRunning) {
monitorRunning = true;
db = client->api->createDatabase(dbState->clusterFilePath.c_str());
auto itr = dbState->legacyDatabaseConnections.find(client->protocolVersion);
ASSERT(itr != dbState->legacyDatabaseConnections.end());
db = itr->second;
tr = Reference<ITransaction>();
TraceEvent("StartingLegacyVersionMonitor").detail("ProtocolVersion", client->protocolVersion);

View File

@ -510,7 +510,16 @@ public:
ThreadFuture<Void> dbReady;
ThreadFuture<Void> protocolVersionMonitor;
// Versions older than 6.1 do not benefit from having their database connections closed. Additionally,
// there are various issues that result in negative behavior in some cases if the connections are closed.
// Therefore, we leave them open.
std::map<ProtocolVersion, Reference<IDatabase>> legacyDatabaseConnections;
// Versions 5.0 and older do not support connection packet monitoring and require alternate techniques to
// determine the cluster version.
std::list<LegacyVersionMonitor> legacyVersionMonitors;
Optional<ProtocolVersion> dbProtocolVersion;
// This maps a normalized protocol version to the client associated with it. This prevents compatible

View File

@ -118,6 +118,7 @@ public: // introduced features
PROTOCOL_VERSION_FEATURE(0x0FDB00B062010001LL, BackupMutations);
PROTOCOL_VERSION_FEATURE(0x0FDB00B062010001LL, ClusterControllerPriorityInfo);
PROTOCOL_VERSION_FEATURE(0x0FDB00B062010001LL, ProcessIDFile);
PROTOCOL_VERSION_FEATURE(0x0FDB00B062010001LL, CloseUnusedConnection);
PROTOCOL_VERSION_FEATURE(0x0FDB00B063010000LL, DBCoreState);
PROTOCOL_VERSION_FEATURE(0x0FDB00B063010000LL, TagThrottleValue);
PROTOCOL_VERSION_FEATURE(0x0FDB00B063010000LL, ServerListValue);