diff options
Diffstat (limited to 'src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp')
-rw-r--r-- | src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp | 103 |
1 files changed, 60 insertions, 43 deletions
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp index 79326f3f1cc..eb41d13245f 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp @@ -71,6 +71,7 @@ #include "mongo/db/storage/journal_listener.h" #include "mongo/db/storage/storage_file_util.h" #include "mongo/db/storage/storage_options.h" +#include "mongo/db/storage/storage_repair_observer.h" #include "mongo/db/storage/wiredtiger/wiredtiger_customization_hooks.h" #include "mongo/db/storage/wiredtiger/wiredtiger_extensions.h" #include "mongo/db/storage/wiredtiger/wiredtiger_global_options.h" @@ -159,48 +160,6 @@ std::string WiredTigerFileVersion::getDowngradeString() { return "compatibility=(release=3.1)"; } -namespace { -void openWiredTiger(const std::string& path, - WT_EVENT_HANDLER* eventHandler, - const std::string& wtOpenConfig, - WT_CONNECTION** connOut, - WiredTigerFileVersion* fileVersionOut) { - std::string configStr = wtOpenConfig + ",compatibility=(require_min=\"3.1.0\")"; - int ret = wiredtiger_open(path.c_str(), eventHandler, configStr.c_str(), connOut); - if (!ret) { - *fileVersionOut = {WiredTigerFileVersion::StartupVersion::IS_40}; - return; - } - - // Arbiters do not replicate the FCV document. Due to arbiter FCV semantics on 4.0, shutting - // down a 4.0 arbiter may either downgrade the data files to WT compatibility 2.9 or 3.0. Thus, - // 4.2 binaries must allow starting up on 2.9 and 3.0 files. - configStr = wtOpenConfig + ",compatibility=(require_min=\"3.0.0\")"; - ret = wiredtiger_open(path.c_str(), eventHandler, configStr.c_str(), connOut); - if (!ret) { - *fileVersionOut = {WiredTigerFileVersion::StartupVersion::IS_36}; - return; - } - - configStr = wtOpenConfig + ",compatibility=(require_min=\"2.9.0\")"; - ret = wiredtiger_open(path.c_str(), eventHandler, configStr.c_str(), connOut); - if (!ret) { - *fileVersionOut = {WiredTigerFileVersion::StartupVersion::IS_34}; - return; - } - - severe() << "Failed to start up WiredTiger under any compatibility version."; - if (ret == EINVAL) { - fassertFailedNoTrace(28561); - } - - severe() << "Reason: " << wtRCToStatus(ret).reason(); - severe() << "Failed to open a WiredTiger connection. This may be due to metadata corruption. " - << kWTRepairMsg; - fassertFailedNoTrace(28595); -} -} // namespace - using std::set; using std::string; @@ -572,7 +531,7 @@ WiredTigerKVEngine::WiredTigerKVEngine(const std::string& canonicalName, string config = ss.str(); log() << "wiredtiger_open config: " << config; - openWiredTiger(path, _eventHandler.getWtEventHandler(), config, &_conn, &_fileVersion); + _openWiredTiger(path, config); _eventHandler.setStartupSuccessful(); _wtOpenConfig = config; @@ -645,6 +604,64 @@ void WiredTigerKVEngine::appendGlobalStats(BSONObjBuilder& b) { bb.done(); } +void WiredTigerKVEngine::_openWiredTiger(const std::string& path, const std::string& wtOpenConfig) { + std::string configStr = wtOpenConfig + ",compatibility=(require_min=\"3.1.0\")"; + + auto wtEventHandler = _eventHandler.getWtEventHandler(); + + int ret = wiredtiger_open(path.c_str(), wtEventHandler, configStr.c_str(), &_conn); + if (!ret) { + _fileVersion = {WiredTigerFileVersion::StartupVersion::IS_40}; + return; + } + + // Arbiters do not replicate the FCV document. Due to arbiter FCV semantics on 4.0, shutting + // down a 4.0 arbiter may either downgrade the data files to WT compatibility 2.9 or 3.0. Thus, + // 4.2 binaries must allow starting up on 2.9 and 3.0 files. + configStr = wtOpenConfig + ",compatibility=(require_min=\"3.0.0\")"; + ret = wiredtiger_open(path.c_str(), wtEventHandler, configStr.c_str(), &_conn); + if (!ret) { + _fileVersion = {WiredTigerFileVersion::StartupVersion::IS_36}; + return; + } + + configStr = wtOpenConfig + ",compatibility=(require_min=\"2.9.0\")"; + ret = wiredtiger_open(path.c_str(), wtEventHandler, configStr.c_str(), &_conn); + if (!ret) { + _fileVersion = {WiredTigerFileVersion::StartupVersion::IS_34}; + return; + } + + warning() << "Failed to start up WiredTiger under any compatibility version."; + if (ret == EINVAL) { + fassertFailedNoTrace(28561); + } + + if (ret == WT_TRY_SALVAGE) { + warning() << "WiredTiger metadata corruption detected"; + + if (!_inRepairMode) { + severe() << kWTRepairMsg; + fassertFailedNoTrace(50944); + } + + warning() << "Attempting to salvage WiredTiger metadata"; + configStr = wtOpenConfig + ",salvage=true"; + ret = wiredtiger_open(path.c_str(), wtEventHandler, configStr.c_str(), &_conn); + if (!ret) { + StorageRepairObserver::get(getGlobalServiceContext()) + ->onModification("WiredTiger metadata salvaged"); + return; + } + + severe() << "Failed to salvage WiredTiger metadata: " + wtRCToStatus(ret).reason(); + fassertFailedNoTrace(50947); + } + + severe() << "Reason: " << wtRCToStatus(ret).reason(); + fassertFailedNoTrace(28595); +} + void WiredTigerKVEngine::cleanShutdown() { log() << "WiredTigerKVEngine shutting down"; if (!_readOnly) |