diff options
author | Louis Williams <louis.williams@mongodb.com> | 2018-10-26 12:06:36 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2018-12-07 08:26:28 -0500 |
commit | bdcf088d3c90a4fe6e9c4f23559a22e73117af45 (patch) | |
tree | c8001eaec29c1612f6528a0797866f77d639397e | |
parent | 79607f92debdeb3841387ff368f37764c23b913f (diff) | |
download | mongo-bdcf088d3c90a4fe6e9c4f23559a22e73117af45.tar.gz |
SERVER-37749 replSetResizeOplog command does not validate argument correctly
(cherry picked from commit 83328dadb7aba72fc9202c91d5715ab4a2d04fcb)
(cherry picked from commit 8b07e3e7242c5048eb847105fe30a9e3ef2bb88c)
-rw-r--r-- | jstests/noPassthrough/repl_set_resize_oplog.js | 53 | ||||
-rw-r--r-- | src/mongo/db/commands/resize_oplog.cpp | 9 |
2 files changed, 61 insertions, 1 deletions
diff --git a/jstests/noPassthrough/repl_set_resize_oplog.js b/jstests/noPassthrough/repl_set_resize_oplog.js new file mode 100644 index 00000000000..7c164175685 --- /dev/null +++ b/jstests/noPassthrough/repl_set_resize_oplog.js @@ -0,0 +1,53 @@ +/** + * Tests that resizing the oplog works as expected and validates input arguments. + * + * @tags: [requires_replication, requires_wiredtiger] + */ +(function() { + "use strict"; + + // Skip this test if not running with the "wiredTiger" storage engine. + if (jsTest.options().storageEngine && jsTest.options().storageEngine !== 'wiredTiger') { + jsTest.log('Skipping test because storageEngine is not "wiredTiger"'); + return; + } + + let replSet = new ReplSetTest({nodes: 2, oplogSize: 50}); + replSet.startSet(); + replSet.initiate(); + + let primary = replSet.getPrimary(); + + const MB = 1024 * 1024; + const GB = 1024 * MB; + const PB = 1024 * GB; + const EB = 1024 * PB; + + assert.eq(primary.getDB('local').oplog.rs.stats().maxSize, 50 * MB); + + // Too small: 990MB + assert.commandFailedWithCode( + primary.getDB('admin').runCommand({replSetResizeOplog: 1, size: 900}), + ErrorCodes.InvalidOptions, + "Expected replSetResizeOplog to fail because the size was too small"); + + // Way too small: -1GB + assert.commandFailedWithCode( + primary.getDB('admin').runCommand({replSetResizeOplog: 1, size: -1 * GB / MB}), + ErrorCodes.InvalidOptions, + "Expected replSetResizeOplog to fail because the size was too small"); + + // Too big: 8EB + assert.commandFailedWithCode( + primary.getDB('admin').runCommand({replSetResizeOplog: 1, size: 8 * EB / MB}), + ErrorCodes.InvalidOptions, + "Expected replSetResizeOplog to fail because the size was too big"); + + // The maximum: 1PB + assert.commandWorked( + primary.getDB('admin').runCommand({replSetResizeOplog: 1, size: 1 * PB / MB})); + + assert.eq(primary.getDB('local').oplog.rs.stats().maxSize, 1 * PB); + + replSet.stopSet(); +})(); diff --git a/src/mongo/db/commands/resize_oplog.cpp b/src/mongo/db/commands/resize_oplog.cpp index ea2899ed62a..c2a8c05c619 100644 --- a/src/mongo/db/commands/resize_oplog.cpp +++ b/src/mongo/db/commands/resize_oplog.cpp @@ -110,11 +110,18 @@ public: } long long sizeMb = jsobj["size"].numberLong(); - long long size = sizeMb * 1024 * 1024; if (sizeMb < 990L) { return appendCommandStatus( result, Status(ErrorCodes::InvalidOptions, "oplog size should be 990MB at least")); } + + const long long kMB = 1024 * 1024; + const long long kPB = kMB * 1024 * 1024 * 1024; + if (sizeMb > kPB / kMB) { + uasserted(ErrorCodes::InvalidOptions, "oplog size in MB cannot exceed maximum of 1PB"); + } + long long size = sizeMb * kMB; + WriteUnitOfWork wunit(opCtx); Status status = coll->getRecordStore()->updateCappedSize(opCtx, size); if (!status.isOK()) { |