diff options
author | Alex Cameron <alex.cameron@10gen.com> | 2019-06-11 08:45:32 +0000 |
---|---|---|
committer | Alex Cameron <alex.cameron@10gen.com> | 2019-07-14 09:02:00 +0000 |
commit | b6f1010451de1a10e12c4b6d865476cce284afce (patch) | |
tree | a0efef007ce7c5b26c488eec301fff608b318bc5 | |
parent | 57ea3693bf4c52a1f5568539862b5fbf51e86b7f (diff) | |
download | mongo-b6f1010451de1a10e12c4b6d865476cce284afce.tar.gz |
SERVER-39004 Introduce a quota mechanism for the overflow file
(cherry picked from commit b29c22ad4b89dccca63bd2a279c48f47f76093d1)
13 files changed, 132 insertions, 2 deletions
diff --git a/jstests/noPassthrough/wiredTigerMaxCacheOverflowSizeGB_serverParameter.js b/jstests/noPassthrough/wiredTigerMaxCacheOverflowSizeGB_serverParameter.js new file mode 100644 index 00000000000..f048f2cbf04 --- /dev/null +++ b/jstests/noPassthrough/wiredTigerMaxCacheOverflowSizeGB_serverParameter.js @@ -0,0 +1,22 @@ +/** + * Test server validation of the 'wiredTigerMaxCacheOverflowSizeGB' server parameter setting via + * the setParameter command. + * @tags: [requires_persistence, requires_wiredtiger] + */ + +(function() { + 'use strict'; + + load("jstests/noPassthrough/libs/server_parameter_helpers.js"); + + // Valid parameter values are in the range [0.1, infinity) or 0 (unbounded). + testNumericServerParameter("wiredTigerMaxCacheOverflowSizeGB", + false /*isStartupParameter*/, + true /*isRuntimeParameter*/, + 0 /*defaultValue*/, + 0.1 /*nonDefaultValidValue*/, + true /*hasLowerBound*/, + 0.09 /*lowerOutOfBounds*/, + false /*hasUpperBound*/, + "unused" /*upperOutOfBounds*/); +})(); diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.cpp index 63424bf4844..7e708bfded2 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.cpp @@ -78,4 +78,13 @@ Status WiredTigerGlobalOptions::validateWiredTigerCompressor(const std::string& return Status::OK(); } +Status WiredTigerGlobalOptions::validateMaxCacheOverflowFileSizeGB(double value) { + if (value != 0.0 && value < 0.1) { + return {ErrorCodes::BadValue, + "MaxCacheOverflowFileSizeGB must be either 0 (unbounded) or greater than 0.1."}; + } + + return Status::OK(); +} + } // namespace mongo diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.h b/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.h index f77273a4289..0cfb7c4fb4f 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.h +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.h @@ -43,6 +43,7 @@ public: checkpointDelaySecs(0), statisticsLogDelaySecs(0), directoryForIndexes(false), + maxCacheOverflowFileSizeGB(0), useCollectionPrefixCompression(false), useIndexPrefixCompression(false){}; @@ -53,6 +54,7 @@ public: size_t statisticsLogDelaySecs; std::string journalCompressor; bool directoryForIndexes; + double maxCacheOverflowFileSizeGB; std::string engineConfig; std::string collectionBlockCompressor; @@ -63,6 +65,7 @@ public: std::string indexConfig; static Status validateWiredTigerCompressor(const std::string&); + static Status validateMaxCacheOverflowFileSizeGB(double); }; extern WiredTigerGlobalOptions wiredTigerGlobalOptions; diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.idl b/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.idl index 2b02e73d6a9..d04f5b8a464 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.idl +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.idl @@ -69,6 +69,16 @@ configs: arg_vartype: Switch cpp_varname: 'wiredTigerGlobalOptions.directoryForIndexes' short_name: wiredTigerDirectoryForIndexes + "storage.wiredTiger.engineConfig.maxCacheOverflowFileSizeGB": + description: >- + Maximum amount of disk space to use for cache overflow; + Defaults to 0 (unbounded) + arg_vartype: Double + cpp_varname: 'wiredTigerGlobalOptions.maxCacheOverflowFileSizeGB' + short_name: wiredTigerMaxCacheOverflowFileSizeGB + validator: + callback: 'WiredTigerGlobalOptions::validateMaxCacheOverflowFileSizeGB' + default: 0.0 "storage.wiredTiger.engineConfig.configString": description: 'WiredTiger storage engine custom configuration setting' arg_vartype: String diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp index 201cc59c322..b01e796f1de 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp @@ -101,12 +101,15 @@ public: } } const bool ephemeral = false; + const auto maxCacheOverflowMB = + static_cast<size_t>(1024 * wiredTigerGlobalOptions.maxCacheOverflowFileSizeGB); WiredTigerKVEngine* kv = new WiredTigerKVEngine(getCanonicalName().toString(), params.dbpath, getGlobalServiceContext()->getFastClockSource(), wiredTigerGlobalOptions.engineConfig, cacheMB, + maxCacheOverflowMB, params.dur, ephemeral, params.repair, @@ -119,6 +122,10 @@ public: ServerParameterType::kRuntimeOnly); param->_data.second = kv; + auto* maxCacheOverflowParam = new WiredTigerMaxCacheOverflowSizeGBParameter( + "wiredTigerMaxCacheOverflowSizeGB", ServerParameterType::kRuntimeOnly); + maxCacheOverflowParam->_data = {wiredTigerGlobalOptions.maxCacheOverflowFileSizeGB, kv}; + StorageEngineOptions options; options.directoryPerDB = params.directoryperdb; options.directoryForIndexes = wiredTigerGlobalOptions.directoryForIndexes; diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp index db309f66c1b..361c6577c1f 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp @@ -542,6 +542,7 @@ WiredTigerKVEngine::WiredTigerKVEngine(const std::string& canonicalName, ClockSource* cs, const std::string& extraOpenOptions, size_t cacheSizeMB, + size_t maxCacheOverflowFileSizeMB, bool durable, bool ephemeral, bool repair, @@ -574,6 +575,7 @@ WiredTigerKVEngine::WiredTigerKVEngine(const std::string& canonicalName, std::stringstream ss; ss << "create,"; ss << "cache_size=" << cacheSizeMB << "M,"; + ss << "cache_overflow=(file_max=" << maxCacheOverflowFileSizeMB << "M),"; ss << "session_max=33000,"; ss << "eviction=(threads_min=4,threads_max=4),"; ss << "config_base=false,"; diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h index ae0fffd31a5..814faa1a3d8 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h @@ -71,7 +71,8 @@ public: const std::string& path, ClockSource* cs, const std::string& extraOpenOptions, - size_t cacheSizeGB, + size_t cacheSizeMB, + size_t maxCacheOverflowFileSizeMB, bool durable, bool ephemeral, bool repair, diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp index c6e0da77906..6cbf18a756b 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp @@ -85,6 +85,7 @@ private: _cs.get(), "", 1, + 0, false, false, _forRepair, diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_parameters.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_parameters.cpp index c5ebea88b34..5cda75b3c2f 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_parameters.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_parameters.cpp @@ -39,6 +39,37 @@ namespace mongo { using std::string; +namespace { + +Status applyMaxCacheOverflowSizeGBParameter(WiredTigerMaxCacheOverflowSizeGBParameter& param, + double value) { + if (value != 0.0 && value < 0.1) { + return {ErrorCodes::BadValue, + "MaxCacheOverflowFileSizeGB must be either 0 (unbounded) or greater than 0.1."}; + } + + const auto valueMB = static_cast<size_t>(1024 * value); + + log() << "Reconfiguring WiredTiger max cache overflow size with value: \"" << valueMB << "MB\'"; + + invariant(param._data.second); + int ret = param._data.second->reconfigure( + fmt::format("cache_overflow=(file_max={}M)", valueMB).c_str()); + if (ret != 0) { + string result = + (str::stream() << "WiredTiger reconfiguration failed with error code (" << ret << "): " + << wiredtiger_strerror(ret)); + error() << result; + + return Status(ErrorCodes::BadValue, result); + } + + param._data.first = value; + return Status::OK(); +} + +} // namespace + void WiredTigerEngineRuntimeConfigParameter::append(OperationContext* opCtx, BSONObjBuilder& b, const std::string& name) { @@ -71,4 +102,34 @@ Status WiredTigerEngineRuntimeConfigParameter::setFromString(const std::string& _data.first = str; return Status::OK(); } + +void WiredTigerMaxCacheOverflowSizeGBParameter::append(OperationContext* opCtx, + BSONObjBuilder& b, + const std::string& name) { + b << name << _data.first; +} + +Status WiredTigerMaxCacheOverflowSizeGBParameter::set(const BSONElement& element) { + if (element.type() == String) { + return setFromString(element.valuestrsafe()); + } + + double value; + if (!element.coerce(&value)) { + return {ErrorCodes::BadValue, "MaxCacheOverflowFileSizeGB must be a numeric value."}; + } + + return applyMaxCacheOverflowSizeGBParameter(*this, value); +} + +Status WiredTigerMaxCacheOverflowSizeGBParameter::setFromString(const std::string& str) { + double value; + const auto status = parseNumberFromString(str, &value); + if (!status.isOK()) { + return status; + } + + return applyMaxCacheOverflowSizeGBParameter(*this, value); +} + } // namespace mongo diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_parameters.idl b/src/mongo/db/storage/wiredtiger/wiredtiger_parameters.idl index 29e326c23ac..aa0a246835e 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_parameters.idl +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_parameters.idl @@ -109,3 +109,14 @@ server_parameters: cpp_vartype: 'AtomicWord<std::int32_t>' cpp_varname: gWiredTigerCursorCacheSize default: -100 + + wiredTigerMaxCacheOverflowSizeGB: + description: >- + Maximum amount of disk space to use for cache overflow; + Defaults to 0 (unbounded) + set_at: runtime + cpp_class: + name: WiredTigerMaxCacheOverflowSizeGBParameter + data: 'std::pair<double, WiredTigerKVEngine*>' + override_set: true + condition: { expr: false } diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_prefixed_record_store_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_prefixed_record_store_test.cpp index 45de934a4f6..76c8e5121a2 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_prefixed_record_store_test.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_prefixed_record_store_test.cpp @@ -78,6 +78,7 @@ public: _cs.get(), "", 1, + 0, false, false, false, diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit_test.cpp index e45d693b12c..df5e5935b8f 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit_test.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit_test.cpp @@ -54,7 +54,8 @@ public: _dbpath.path(), // .path &_cs, // .cs "", // .extraOpenOptions - 1, // .cacheSizeGB + 1, // .cacheSizeMB + 0, // .maxCacheOverflowFileSizeMB false, // .durable false, // .ephemeral false, // .repair diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_standard_record_store_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_standard_record_store_test.cpp index 0d4c5fbc477..4e09d0fdd9b 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_standard_record_store_test.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_standard_record_store_test.cpp @@ -79,6 +79,7 @@ public: &_cs, extraStrings.toString(), 1, + 0, false, false, false, |