summaryrefslogtreecommitdiff
path: root/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp')
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp69
1 files changed, 60 insertions, 9 deletions
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
index 8770cac0f0f..8e7f6f80669 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp
@@ -113,6 +113,15 @@ bool WiredTigerFileVersion::shouldDowngrade(bool readOnly,
return false;
}
+ if (_startupVersion == StartupVersion::IS_42_UPGRADED) {
+ // Once a 4.4 binary has touched data files, only 4.2.6+ can make sense of them. Note, even
+ // if the FCV was changed to 4.0, we choose to not make the journal compatible with a 4.0
+ // binary. If a primary continues to accept FCV downgrades to 3.6 and earlier, the 4.4
+ // touched data files will never be able to recover. At that point, a resync is the only
+ // option.
+ return false;
+ }
+
const auto replCoord = repl::ReplicationCoordinator::get(getGlobalServiceContext());
const auto memberState = replCoord->getMemberState();
if (memberState.arbiter()) {
@@ -155,7 +164,8 @@ bool WiredTigerFileVersion::shouldDowngrade(bool readOnly,
std::string WiredTigerFileVersion::getDowngradeString() {
if (!serverGlobalParams.featureCompatibility.isVersionInitialized()) {
- invariant(_startupVersion != StartupVersion::IS_42);
+ invariant(_startupVersion != StartupVersion::IS_42_UPGRADED &&
+ _startupVersion != StartupVersion::IS_42_CLASSIC);
switch (_startupVersion) {
case StartupVersion::IS_34:
@@ -668,10 +678,6 @@ WiredTigerKVEngine::WiredTigerKVEngine(const std::string& canonicalName,
ss << "verbose=[recovery_progress,checkpoint_progress],";
}
- // MongoDB 4.2.6+ will also understand WT compatibility version 3.3. However it should only
- // write data in compatibility version 3.2.
- ss << "compatibility=(release=3.2,require_max=\"3.3.0\"),";
-
// Enable debug write-ahead logging for all tables under debug build.
if (kDebugBuild) {
ss << "debug_mode=(table_logging=true),";
@@ -817,13 +823,56 @@ void WiredTigerKVEngine::appendGlobalStats(BSONObjBuilder& b) {
bb.done();
}
+/**
+ * Table of MongoDB<->WiredTiger<->Log version numbers:
+ *
+ * | MongoDB | WiredTiger | Log |
+ * |------------------------+------------+-----|
+ * | 3.0.15 | 2.5.3 | 1 |
+ * | 3.2.20 | 2.9.2 | 1 |
+ * | 3.4.15 | 2.9.2 | 1 |
+ * | 3.6.4 | 3.0.1 | 2 |
+ * | 4.0.16 | 3.1.1 | 3 |
+ * | 4.2.1 | 3.2.2 | 3 |
+ * | 4.2.6 | 3.3.0 | 3 |
+ * | 4.2.6 (blessed by 4.4) | 3.3.0 | 4 |
+ * | 4.4.0 | 10.0.0 | 5 |
+ */
void WiredTigerKVEngine::_openWiredTiger(const std::string& path, const std::string& wtOpenConfig) {
- std::string configStr = wtOpenConfig + ",compatibility=(require_min=\"3.1.0\")";
+ // So long as the data files are never touched by 4.4, MongoDB 4.2.6+ will remain compatible
+ // with earlier 4.2 versions by using compatibility version 3.2 (log version 3).
+ //
+ // Additionally, we first try opening with `release=3.2` to allow fresh "dbpaths" to be
+ // backwards compatible with earlier 4.2 versions.
+ std::string configStr =
+ wtOpenConfig + ",compatibility=(release=3.2,require_min=\"3.2\",require_max=\"3.2\")";
auto wtEventHandler = _eventHandler.getWtEventHandler();
-
int ret = wiredtiger_open(path.c_str(), wtEventHandler, configStr.c_str(), &_conn);
if (!ret) {
+ _fileVersion = {WiredTigerFileVersion::StartupVersion::IS_42_CLASSIC};
+ return;
+ }
+
+ // If the data files are in 4.4 -> 4.2 downgraded format (log version 4, compatibility version
+ // 3.3), continue to use compatibility version 3.3. This prevents earlier 4.2 releases from ever
+ // running on these data files.
+ configStr =
+ wtOpenConfig + ",compatibility=(release=3.3,require_min=\"3.3\",require_max=\"3.3\")";
+ ret = wiredtiger_open(path.c_str(), wtEventHandler, configStr.c_str(), &_conn);
+ if (!ret) {
+ _fileVersion = {WiredTigerFileVersion::StartupVersion::IS_42_UPGRADED};
+ return;
+ }
+
+ // This shoud only succeed when the previous datafiles were in compatibility mode
+ // 3.1. `require_max=` is added for improved WT error messages. "3.3" is used because WT
+ // disallows using a release outside of the min/max range. These details also apply to the
+ // remaining `wiredtiger_open` calls.
+ configStr =
+ wtOpenConfig + ",compatibility=(release=3.2,require_min=\"3.1\",require_max=\"3.3\")";
+ ret = wiredtiger_open(path.c_str(), wtEventHandler, configStr.c_str(), &_conn);
+ if (!ret) {
_fileVersion = {WiredTigerFileVersion::StartupVersion::IS_40};
return;
}
@@ -831,14 +880,16 @@ void WiredTigerKVEngine::_openWiredTiger(const std::string& path, const std::str
// 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\")";
+ configStr =
+ wtOpenConfig + ",compatibility=(release=3.2,require_min=\"3.0\",require_max=\"3.3\")";
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\")";
+ configStr =
+ wtOpenConfig + ",compatibility=(release=3.2,require_min=\"2.9\",require_max=\"3.3\")";
ret = wiredtiger_open(path.c_str(), wtEventHandler, configStr.c_str(), &_conn);
if (!ret) {
_fileVersion = {WiredTigerFileVersion::StartupVersion::IS_34};