summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/core/dbadmin.js89
-rw-r--r--jstests/core/startup_log.js75
-rw-r--r--jstests/libs/override_methods/implicitly_shard_accessed_collections.js9
-rw-r--r--jstests/sharding/top_chunk_autosplit.js16
-rw-r--r--src/mongo/s/catalog/catalog_manager_common.cpp5
-rw-r--r--src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp28
6 files changed, 140 insertions, 82 deletions
diff --git a/jstests/core/dbadmin.js b/jstests/core/dbadmin.js
index 02644a054fe..b287a9ba58c 100644
--- a/jstests/core/dbadmin.js
+++ b/jstests/core/dbadmin.js
@@ -1,96 +1,33 @@
load('jstests/aggregation/extras/utils.js');
-// Check that smallArray is entirely contained by largeArray
-// returns false if a member of smallArray is not in largeArray
-function arrayIsSubset(smallArray, largeArray) {
+(function() {
+'use strict';
- for(var i = 0; i < smallArray.length; i++) {
- if(!Array.contains(largeArray, smallArray[i])) {
- print("Could not find " + smallArray[i] + " in largeArray");
- return false;
- }
- }
-
- return true;
-}
-
-t = db.dbadmin;
+var t = db.dbadmin;
t.save( { x : 1 } );
t.save( { x : 1 } );
-res = db._adminCommand( "listDatabases" );
+var res = db._adminCommand( "listDatabases" );
assert( res.databases && res.databases.length > 0 , "listDatabases 1 " + tojson(res) );
-now = new Date();
-x = db._adminCommand( "ismaster" );
+var now = new Date();
+var x = db._adminCommand( "ismaster" );
assert( x.ismaster , "ismaster failed: " + tojson( x ) )
assert( x.localTime, "ismaster didn't include time: " + tojson(x))
-localTimeSkew = x.localTime - now
+
+var localTimeSkew = x.localTime - now
if ( localTimeSkew >= 50 ) {
print( "Warning: localTimeSkew " + localTimeSkew + " > 50ms." )
}
assert.lt( localTimeSkew, 500, "isMaster.localTime" )
-before = db.runCommand( "serverStatus" )
+var before = db.runCommand( "serverStatus" )
print(before.uptimeEstimate);
sleep( 5000 )
-after = db.runCommand( "serverStatus" )
+
+var after = db.runCommand( "serverStatus" )
print(after.uptimeEstimate);
assert.lt( 2 , after.uptimeEstimate , "up1" )
-assert.gt( after.uptimeEstimate , before.uptimeEstimate , "up2" )
-
-// Test startup_log
-var stats = db.getSisterDB( "local" ).startup_log.stats();
-assert(stats.capped);
-
-var latestStartUpLog = db.getSisterDB( "local" ).startup_log.find().sort( { $natural: -1 } ).limit(1).next();
-var serverStatus = db._adminCommand( "serverStatus" );
-var cmdLine = db._adminCommand( "getCmdLineOpts" ).parsed;
-
-// Test that the startup log has the expected keys
-var verbose = false;
-var expectedKeys = ["_id", "hostname", "startTime", "startTimeLocal", "cmdLine", "pid", "buildinfo"];
-var keys = Object.keySet(latestStartUpLog);
-assert(arrayEq(expectedKeys, keys, verbose), 'startup_log keys failed');
-
-// Tests _id implicitly - should be comprised of host-timestamp
-// Setup expected startTime and startTimeLocal from the supplied timestamp
-var _id = latestStartUpLog._id.split('-'); // _id should consist of host-timestamp
-var _idUptime = _id.pop();
-var _idHost = _id.join('-');
-var uptimeSinceEpochRounded = Math.floor(_idUptime/1000) * 1000;
-var startTime = new Date(uptimeSinceEpochRounded); // Expected startTime
-
-assert.eq(_idHost, latestStartUpLog.hostname, "Hostname doesn't match one from _id");
-assert.eq(serverStatus.host.split(':')[0], latestStartUpLog.hostname, "Hostname doesn't match one in server status");
-assert.closeWithinMS(startTime, latestStartUpLog.startTime,
- "StartTime doesn't match one from _id", 2000); // Expect less than 2 sec delta
-assert.eq(cmdLine, latestStartUpLog.cmdLine, "cmdLine doesn't match that from getCmdLineOpts");
-assert.eq(serverStatus.pid, latestStartUpLog.pid, "pid doesn't match that from serverStatus");
-
-// Test buildinfo
-var buildinfo = db.runCommand( "buildinfo" );
-delete buildinfo.ok; // Delete extra meta info not in startup_log
-var isMaster = db._adminCommand( "ismaster" );
-
-// Test buildinfo has the expected keys
-var expectedKeys = ["version", "gitVersion", "allocator", "versionArray", "javascriptEngine",
- "openssl", "buildEnvironment", "debug", "maxBsonObjectSize", "bits", "modules" ];
-
-var keys = Object.keySet(latestStartUpLog.buildinfo);
-// Disabled to check
-assert(arrayIsSubset(expectedKeys, keys), "buildinfo keys failed! \n expected:\t" + expectedKeys + "\n actual:\t" + keys);
-assert.eq(buildinfo, latestStartUpLog.buildinfo, "buildinfo doesn't match that from buildinfo command");
-
-// Test version and version Array
-var version = latestStartUpLog.buildinfo.version.split('-')[0];
-var versionArray = latestStartUpLog.buildinfo.versionArray;
-var versionArrayCleaned = [];
-// Only create a string with 2 dots (2.5.5, not 2.5.5.0)
-for (var i = 0; i < (versionArray.length - 1); i++) if (versionArray[i] >= 0) { versionArrayCleaned.push(versionArray[i]); }
+assert.gt( after.uptimeEstimate , before.uptimeEstimate , "up2" );
-assert.eq(serverStatus.version, latestStartUpLog.buildinfo.version, "Mongo version doesn't match that from ServerStatus");
-assert.eq(version, versionArrayCleaned.join('.'), "version doesn't match that from the versionArray");
-var jsEngine = latestStartUpLog.buildinfo.javascriptEngine;
-assert((jsEngine == "none") || jsEngine.startsWith("mozjs"));
-assert.eq(isMaster.maxBsonObjectSize, latestStartUpLog.buildinfo.maxBsonObjectSize, "maxBsonObjectSize doesn't match one from ismaster");
+})();
diff --git a/jstests/core/startup_log.js b/jstests/core/startup_log.js
new file mode 100644
index 00000000000..e64e582c319
--- /dev/null
+++ b/jstests/core/startup_log.js
@@ -0,0 +1,75 @@
+load('jstests/aggregation/extras/utils.js');
+
+(function() {
+'use strict';
+
+// Check that smallArray is entirely contained by largeArray
+// returns false if a member of smallArray is not in largeArray
+function arrayIsSubset(smallArray, largeArray) {
+ for(var i = 0; i < smallArray.length; i++) {
+ if(!Array.contains(largeArray, smallArray[i])) {
+ print("Could not find " + smallArray[i] + " in largeArray");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Test startup_log
+var stats = db.getSisterDB( "local" ).startup_log.stats();
+assert(stats.capped);
+
+var latestStartUpLog = db.getSisterDB( "local" ).startup_log.find().sort( { $natural: -1 } ).limit(1).next();
+var serverStatus = db._adminCommand( "serverStatus" );
+var cmdLine = db._adminCommand( "getCmdLineOpts" ).parsed;
+
+// Test that the startup log has the expected keys
+var verbose = false;
+var expectedKeys = ["_id", "hostname", "startTime", "startTimeLocal", "cmdLine", "pid", "buildinfo"];
+var keys = Object.keySet(latestStartUpLog);
+assert(arrayEq(expectedKeys, keys, verbose), 'startup_log keys failed');
+
+// Tests _id implicitly - should be comprised of host-timestamp
+// Setup expected startTime and startTimeLocal from the supplied timestamp
+var _id = latestStartUpLog._id.split('-'); // _id should consist of host-timestamp
+var _idUptime = _id.pop();
+var _idHost = _id.join('-');
+var uptimeSinceEpochRounded = Math.floor(_idUptime/1000) * 1000;
+var startTime = new Date(uptimeSinceEpochRounded); // Expected startTime
+
+assert.eq(_idHost, latestStartUpLog.hostname, "Hostname doesn't match one from _id");
+assert.eq(serverStatus.host.split(':')[0], latestStartUpLog.hostname, "Hostname doesn't match one in server status");
+assert.closeWithinMS(startTime, latestStartUpLog.startTime,
+ "StartTime doesn't match one from _id", 2000); // Expect less than 2 sec delta
+assert.eq(cmdLine, latestStartUpLog.cmdLine, "cmdLine doesn't match that from getCmdLineOpts");
+assert.eq(serverStatus.pid, latestStartUpLog.pid, "pid doesn't match that from serverStatus");
+
+// Test buildinfo
+var buildinfo = db.runCommand( "buildinfo" );
+delete buildinfo.ok; // Delete extra meta info not in startup_log
+var isMaster = db._adminCommand( "ismaster" );
+
+// Test buildinfo has the expected keys
+var expectedKeys = ["version", "gitVersion", "allocator", "versionArray", "javascriptEngine",
+ "openssl", "buildEnvironment", "debug", "maxBsonObjectSize", "bits", "modules" ];
+
+var keys = Object.keySet(latestStartUpLog.buildinfo);
+// Disabled to check
+assert(arrayIsSubset(expectedKeys, keys), "buildinfo keys failed! \n expected:\t" + expectedKeys + "\n actual:\t" + keys);
+assert.eq(buildinfo, latestStartUpLog.buildinfo, "buildinfo doesn't match that from buildinfo command");
+
+// Test version and version Array
+var version = latestStartUpLog.buildinfo.version.split('-')[0];
+var versionArray = latestStartUpLog.buildinfo.versionArray;
+var versionArrayCleaned = [];
+// Only create a string with 2 dots (2.5.5, not 2.5.5.0)
+for (var i = 0; i < (versionArray.length - 1); i++) if (versionArray[i] >= 0) { versionArrayCleaned.push(versionArray[i]); }
+
+assert.eq(serverStatus.version, latestStartUpLog.buildinfo.version, "Mongo version doesn't match that from ServerStatus");
+assert.eq(version, versionArrayCleaned.join('.'), "version doesn't match that from the versionArray");
+var jsEngine = latestStartUpLog.buildinfo.javascriptEngine;
+assert((jsEngine == "none") || jsEngine.startsWith("mozjs"));
+assert.eq(isMaster.maxBsonObjectSize, latestStartUpLog.buildinfo.maxBsonObjectSize, "maxBsonObjectSize doesn't match one from ismaster");
+
+})();
diff --git a/jstests/libs/override_methods/implicitly_shard_accessed_collections.js b/jstests/libs/override_methods/implicitly_shard_accessed_collections.js
index 45ba5af116f..ab69f1cb817 100644
--- a/jstests/libs/override_methods/implicitly_shard_accessed_collections.js
+++ b/jstests/libs/override_methods/implicitly_shard_accessed_collections.js
@@ -21,6 +21,7 @@
];
DB.prototype.getCollection = function() {
+ var dbName = this.getName();
var collection = originalGetCollection.apply(this, arguments);
var fullName = collection.getFullName();
@@ -36,8 +37,12 @@
}
}
- var res = this.adminCommand({enableSharding: this.getName()});
- assert.commandWorked(res, "enabling sharding on the '" + this.getName() + "' db failed");
+ var res = this.adminCommand({enableSharding: dbName});
+
+ // enableSharding may only be called once for a database.
+ if (res.code !== ErrorCodes.AlreadyInitialized) {
+ assert.commandWorked(res, "enabling sharding on the '" + dbName + "' db failed");
+ }
res = this.adminCommand({shardCollection: fullName, key: {_id: 'hashed'}});
assert.commandWorked(res, "sharding '" + fullName + "' with a hashed _id key failed");
diff --git a/jstests/sharding/top_chunk_autosplit.js b/jstests/sharding/top_chunk_autosplit.js
index 7d001f9bcb5..4c431da75f7 100644
--- a/jstests/sharding/top_chunk_autosplit.js
+++ b/jstests/sharding/top_chunk_autosplit.js
@@ -24,9 +24,7 @@ function runTest(test) {
jsTest.log(tojson(test));
// Setup
- // Enable sharding, set primary shard and shard collection
- assert.commandWorked(db.adminCommand({enableSharding: dbName}));
- db.adminCommand({movePrimary: dbName, to: 'shard0000'});
+ // Shard collection
assert.commandWorked(db.adminCommand({shardCollection: coll + "", key: {x: 1}}));
// Pre-split, move chunks & create tags
@@ -235,6 +233,9 @@ var tests = [
}
];
+assert.commandWorked(db.adminCommand({enableSharding: dbName}));
+db.adminCommand({movePrimary: dbName, to: 'shard0000'});
+
// Execute all test objects
for (var i = 0; i < tests.length; i++) {
runTest(tests[i]);
@@ -267,6 +268,9 @@ var singleNodeTests = [
}
];
+assert.commandWorked(db.adminCommand({enableSharding: dbName}));
+db.adminCommand({movePrimary: dbName, to: 'shard0000'});
+
// Execute all test objects
for (var i = 0; i < singleNodeTests.length; i++) {
runTest(singleNodeTests[i]);
@@ -310,11 +314,15 @@ var maxSizeTests = [
}
];
-// Execute all test objects
// SERVER-17070 Auto split moves to shard node running WiredTiger, if exceeding maxSize
var unsupported = ["wiredTiger", "rocksdb"];
if (unsupported.indexOf(st.d0.adminCommand({serverStatus : 1}).storageEngine.name) == -1 &&
unsupported.indexOf(st.d1.adminCommand({serverStatus : 1}).storageEngine.name) == -1) {
+
+ assert.commandWorked(db.adminCommand({enableSharding: dbName}));
+ db.adminCommand({movePrimary: dbName, to: 'shard0000'});
+
+ // Execute all test objects
for (var i = 0; i < maxSizeTests.length; i++) {
runTest(maxSizeTests[i]);
}
diff --git a/src/mongo/s/catalog/catalog_manager_common.cpp b/src/mongo/s/catalog/catalog_manager_common.cpp
index 9475c04ee3b..a4c949a4635 100644
--- a/src/mongo/s/catalog/catalog_manager_common.cpp
+++ b/src/mongo/s/catalog/catalog_manager_common.cpp
@@ -559,6 +559,11 @@ Status CatalogManagerCommon::enableSharding(OperationContext* txn, const std::st
db.setPrimary(newShardId);
db.setSharded(true);
} else if (status.code() == ErrorCodes::NamespaceExists) {
+ if (db.getSharded()) {
+ return Status(ErrorCodes::AlreadyInitialized,
+ str::stream() << "sharding already enabled for database " << dbName);
+ }
+
// Database exists, so just update it
db.setSharded(true);
} else {
diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp
index 6af30bc9481..71c0bd96204 100644
--- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp
+++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp
@@ -2197,6 +2197,34 @@ TEST_F(CatalogManagerReplSetTest, EnableShardingDBExists) {
future.timed_get(kFutureTimeout);
}
+TEST_F(CatalogManagerReplSetTest, EnableShardingFailsWhenTheDatabaseIsAlreadySharded) {
+ configTargeter()->setFindHostReturnValue(HostAndPort("config:123"));
+
+ vector<ShardType> shards;
+ ShardType shard;
+ shard.setName("shard0");
+ shard.setHost("shard0:12");
+
+ setupShards(vector<ShardType>{shard});
+
+ distLock()->expectLock(
+ [](StringData, StringData, stdx::chrono::milliseconds, stdx::chrono::milliseconds) {},
+ Status::OK());
+
+ auto future = launchAsync([this] {
+ auto status = catalogManager()->enableSharding(operationContext(), "test");
+ ASSERT_EQ(status.code(), ErrorCodes::AlreadyInitialized);
+ });
+
+ // Query to find if db already exists in config and it is sharded.
+ onFindCommand([](const RemoteCommandRequest& request) {
+ BSONObj existingDoc(fromjson(R"({ _id: "test", primary: "shard2", partitioned: true })"));
+ return vector<BSONObj>{existingDoc};
+ });
+
+ future.timed_get(kFutureTimeout);
+}
+
TEST_F(CatalogManagerReplSetTest, EnableShardingDBExistsInvalidFormat) {
configTargeter()->setFindHostReturnValue(HostAndPort("config:123"));