diff options
92 files changed, 203 insertions, 1497 deletions
diff --git a/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml b/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml index 7ff9246370e..e608545b008 100644 --- a/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml +++ b/buildscripts/resmokeconfig/suites/causally_consistent_jscore_passthrough_auth.yml @@ -118,7 +118,6 @@ selector: # These include operations the root user auth'd on the test database is not authorized to perform, # e.g. dropping or creating system collections. - - jstests/core/cannot_create_system_dot_indexes.js - jstests/core/list_collections_no_views.js - jstests/core/rename8.js - jstests/core/views/duplicate_ns.js diff --git a/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml index 4de9eb7e88f..0ccb4112ef5 100644 --- a/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml +++ b/buildscripts/resmokeconfig/suites/sharded_causally_consistent_jscore_passthrough.yml @@ -53,7 +53,6 @@ selector: # additional hashed shard key indexes that are automatically added by this passthrough. - jstests/core/bad_index_plugin.js - jstests/core/create_indexes.js - - jstests/core/indexOtherNamespace.js - jstests/core/list_indexes_non_existent_ns.js - jstests/core/rename6.js # The following tests fail because they expect no databases to be created. However a DB is created diff --git a/buildscripts/resmokeconfig/suites/sharded_collections_jscore_passthrough.yml b/buildscripts/resmokeconfig/suites/sharded_collections_jscore_passthrough.yml index 15faab4414f..4c68e692df8 100644 --- a/buildscripts/resmokeconfig/suites/sharded_collections_jscore_passthrough.yml +++ b/buildscripts/resmokeconfig/suites/sharded_collections_jscore_passthrough.yml @@ -57,7 +57,6 @@ selector: - jstests/core/apitest_dbcollection.js - jstests/core/bad_index_plugin.js - jstests/core/create_indexes.js - - jstests/core/indexOtherNamespace.js - jstests/core/list_indexes_non_existent_ns.js - jstests/core/rename6.js # The following tests fail because they expect no databases to be created. However a DB is created diff --git a/jstests/auth/basic_role_auth.js b/jstests/auth/basic_role_auth.js index 81e1518152c..f21ef40d962 100644 --- a/jstests/auth/basic_role_auth.js +++ b/jstests/auth/basic_role_auth.js @@ -120,7 +120,12 @@ var testOps = function(db, allowedActions) { }); checkErr(allowedActions.hasOwnProperty('index_r'), function() { - db.system.indexes.findOne(); + var errorCodeUnauthorized = 13; + var res = db.runCommand({"listIndexes": "user"}); + + if (res.code == errorCodeUnauthorized) { + throw Error("unauthorized listIndexes") + } }); checkErr(allowedActions.hasOwnProperty('index_w'), function() { diff --git a/jstests/auth/clac_system_colls.js b/jstests/auth/clac_system_colls.js index 0b2fd75d69f..d9a6912e0ea 100644 --- a/jstests/auth/clac_system_colls.js +++ b/jstests/auth/clac_system_colls.js @@ -10,14 +10,7 @@ function runTest(admindb) { admindb.createUser({user: "admin", pwd: "pwd", roles: ["userAdminAnyDatabase"]}); assert.eq(1, admindb.auth("admin", "pwd")); - var sysCollections = [ - "system.indexes", - "system.js", - "system.namespaces", - "system.profile", - "system.roles", - "system.users" - ]; + var sysCollections = ["system.js", "system.profile", "system.roles", "system.users"]; var sysPrivs = new Array(); for (var i in sysCollections) { sysPrivs.push( diff --git a/jstests/auth/indexSystemUsers.js b/jstests/auth/indexSystemUsers.js index 10bcaf24965..8b9069b1afb 100644 --- a/jstests/auth/indexSystemUsers.js +++ b/jstests/auth/indexSystemUsers.js @@ -15,8 +15,6 @@ adminDB.auth('mallory', 'x'); var res = adminDB.system.users.createIndex({haxx: 1}, {unique: true, dropDups: true}); assert(!res.ok); assert.eq(13, res.code); // unauthorized -assert.writeError(adminDB.exploit.system.indexes.insert( - {ns: "admin.system.users", key: {haxx: 1.0}, name: "haxx_1", unique: true, dropDups: true})); // Make sure that no indexes were built. var collectionInfosCursor = adminDB.runCommand("listCollections", { filter: { @@ -34,4 +32,4 @@ adminDB.logout(); adminDB.auth('admin', 'x'); // Make sure that no users were actually dropped assert.eq(3, adminDB.system.users.count()); -MongoRunner.stopMongod(conn, null, {user: 'admin', pwd: 'x'});
\ No newline at end of file +MongoRunner.stopMongod(conn, null, {user: 'admin', pwd: 'x'}); diff --git a/jstests/auth/lib/commands_lib.js b/jstests/auth/lib/commands_lib.js index c50fc1c9d99..b61ab47137a 100644 --- a/jstests/auth/lib/commands_lib.js +++ b/jstests/auth/lib/commands_lib.js @@ -4604,34 +4604,24 @@ var authCommandsLib = { db.x.drop(); db.y.drop(); }, - testcases: [ - { - runOnDb: firstDbName, - roles: { - read: 1, - readAnyDatabase: 1, - readWrite: 1, - readWriteAnyDatabase: 1, - dbAdmin: 1, - dbAdminAnyDatabase: 1, - dbOwner: 1, - backup: 1, - restore: 1, - root: 1, - __system: 1 - }, - privileges: - [{resource: {db: firstDbName, collection: ""}, actions: ["listCollections"]}] + testcases: [{ + runOnDb: firstDbName, + roles: { + read: 1, + readAnyDatabase: 1, + readWrite: 1, + readWriteAnyDatabase: 1, + dbAdmin: 1, + dbAdminAnyDatabase: 1, + dbOwner: 1, + backup: 1, + restore: 1, + root: 1, + __system: 1 }, - // Test legacy (pre 3.0) way of authorizing listCollections. - { - runOnDb: firstDbName, - privileges: [{ - resource: {db: firstDbName, collection: "system.namespaces"}, - actions: ["find"] - }] - } - ] + privileges: + [{resource: {db: firstDbName, collection: ""}, actions: ["listCollections"]}] + }] }, { testname: "listOwnCollections", @@ -4668,14 +4658,6 @@ var authCommandsLib = { __system: 1 }, }, - // Test legacy (pre 3.0) way of authorizing listCollections. - { - runOnDb: firstDbName, - privileges: [{ - resource: {db: firstDbName, collection: "system.namespaces"}, - actions: ["find"] - }] - }, { runOnDb: firstDbName, privileges: [{resource: {db: firstDbName, collection: "x"}, actions: ["find"]}] @@ -4716,33 +4698,23 @@ var authCommandsLib = { teardown: function(db) { db.x.drop(); }, - testcases: [ - { - runOnDb: firstDbName, - roles: { - read: 1, - readAnyDatabase: 1, - readWrite: 1, - readWriteAnyDatabase: 1, - dbAdmin: 1, - dbAdminAnyDatabase: 1, - dbOwner: 1, - backup: 1, - root: 1, - __system: 1 - }, - privileges: - [{resource: {db: firstDbName, collection: ""}, actions: ["listIndexes"]}] + testcases: [{ + runOnDb: firstDbName, + roles: { + read: 1, + readAnyDatabase: 1, + readWrite: 1, + readWriteAnyDatabase: 1, + dbAdmin: 1, + dbAdminAnyDatabase: 1, + dbOwner: 1, + backup: 1, + root: 1, + __system: 1 }, - // Test legacy (pre 3.0) way of authorizing listIndexes. - { - runOnDb: firstDbName, - privileges: [{ - resource: {db: firstDbName, collection: "system.indexes"}, - actions: ["find"] - }] - } - ] + privileges: + [{resource: {db: firstDbName, collection: ""}, actions: ["listIndexes"]}] + }] }, { testname: "listIndexesWithUUID", @@ -4759,25 +4731,14 @@ var authCommandsLib = { teardown: function(db) { db.x.drop(); }, - testcases: [ - { - runOnDb: firstDbName, - roles: {backup: 1, root: 1, __system: 1}, - privileges: [ - {resource: {db: firstDbName, collection: ""}, actions: ["listIndexes"]}, - {resource: {cluster: true}, actions: ["useUUID"]} - ] - }, - // Test legacy (pre 3.0) way of authorizing listIndexes. - { - runOnDb: firstDbName, - privileges: [ - {resource: {db: firstDbName, collection: "system.indexes"}, actions: ["find"]}, - {resource: {cluster: true}, actions: ["useUUID"]} - - ] - } - ] + testcases: [{ + runOnDb: firstDbName, + roles: {backup: 1, root: 1, __system: 1}, + privileges: [ + {resource: {db: firstDbName, collection: ""}, actions: ["listIndexes"]}, + {resource: {cluster: true}, actions: ["useUUID"]} + ] + }] }, { diff --git a/jstests/core/apply_ops1.js b/jstests/core/apply_ops1.js index e71c33ad9b6..0b098bed8a0 100644 --- a/jstests/core/apply_ops1.js +++ b/jstests/core/apply_ops1.js @@ -212,82 +212,6 @@ }), "Excessively nested applyOps should be rejected"); - // Missing 'o' field value in an operation of type 'i' on 'system.indexes' collection. - assert.commandFailedWithCode( - db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes'}]}), - ErrorCodes.NoSuchKey, - 'applyOps should fail on system.indexes insert operation without "o" field'); - - // Non-object 'o' field value in an operation of type 'i' on 'system.indexes' collection. - assert.commandFailedWithCode( - db.adminCommand({applyOps: [{op: 'i', ns: db.getName() + '.system.indexes', o: 'bar'}]}), - ErrorCodes.TypeMismatch, - 'applyOps should fail on system.indexes insert operation with non-object "o" field'); - - // Missing 'ns' field in index spec. - assert.commandFailedWithCode( - db.adminCommand({ - applyOps: [{ - op: 'i', - ns: db.getName() + '.system.indexes', - o: { - key: {a: 1}, - name: 'a_1', - } - }] - }), - ErrorCodes.NoSuchKey, - 'applyOps should fail on system.indexes insert operation with missing index namespace'); - - // Non-string 'ns' field in index spec. - assert.commandFailedWithCode( - db.adminCommand({ - applyOps: [{ - op: 'i', - ns: db.getName() + '.system.indexes', - o: { - ns: 12345, - key: {a: 1}, - name: 'a_1', - } - }] - }), - ErrorCodes.TypeMismatch, - 'applyOps should fail on system.indexes insert operation with non-string index namespace'); - - // Invalid 'ns' field in index spec. - assert.commandFailedWithCode( - db.adminCommand({ - applyOps: [{ - op: 'i', - ns: db.getName() + '.system.indexes', - o: { - ns: 'invalid_namespace', - key: {a: 1}, - name: 'a_1', - } - }] - }), - ErrorCodes.InvalidNamespace, - 'applyOps should fail on system.indexes insert operation with invalid index namespace'); - - // Inconsistent database name in index spec namespace. - assert.commandFailedWithCode( - db.adminCommand({ - applyOps: [{ - op: 'i', - ns: db.getName() + '.system.indexes', - o: { - ns: 'baddbprefix' + t.getFullName(), - key: {a: 1}, - name: 'a_1', - } - }] - }), - ErrorCodes.InvalidNamespace, - 'applyOps should fail on system.indexes insert operation with index namespace containing ' + - 'inconsistent database name'); - // Valid 'ns' field value in unknown operation type 'x'. assert.commandFailed( db.adminCommand({applyOps: [{op: 'x', ns: t.getFullName()}]}), @@ -476,65 +400,6 @@ assert.eq(true, res.results[1], "Valid update with transaction number failed"); assert.eq(true, res.results[2], "Valid delete with transaction number failed"); - // Foreground index build. - res = assert.commandWorked(db.adminCommand({ - applyOps: [{ - "op": "i", - "ns": db.getName() + ".system.indexes", - "o": { - ns: t.getFullName(), - key: {a: 1}, - name: "a_1", - } - }] - })); - assert.eq(1, res.applied, "Incorrect number of operations applied"); - assert.eq(true, res.results[0], "Foreground index creation failed"); - var allIndexes = t.getIndexes(); - var spec = GetIndexHelpers.findByName(allIndexes, "a_1"); - assert.neq(null, spec, "Foreground index 'a_1' not found: " + tojson(allIndexes)); - assert.eq(1, spec.v, "Expected v=1 index to be built since 'v' field was omitted"); - - // Background indexes are created in the foreground when processed by applyOps. - res = assert.commandWorked(db.adminCommand({ - applyOps: [{ - "op": "i", - "ns": db.getName() + ".system.indexes", - "o": { - ns: t.getFullName(), - key: {b: 1}, - name: "b_1", - background: true, - } - }] - })); - assert.eq(1, res.applied, "Incorrect number of operations applied"); - assert.eq(true, res.results[0], "Background index creation failed"); - allIndexes = t.getIndexes(); - spec = GetIndexHelpers.findByName(allIndexes, "b_1"); - assert.neq(null, spec, "Background index 'b_1' not found: " + tojson(allIndexes)); - assert.eq(1, spec.v, "Expected v=1 index to be built since 'v' field was omitted"); - - // Foreground v=2 index build. - res = assert.commandWorked(db.adminCommand({ - applyOps: [{ - "op": "i", - "ns": db.getName() + ".system.indexes", - "o": { - ns: t.getFullName(), - key: {c: 1}, - name: "c_1", - v: 2, - } - }] - })); - assert.eq(1, res.applied, "Incorrect number of operations applied"); - assert.eq(true, res.results[0], "Foreground v=2 index creation failed"); - allIndexes = t.getIndexes(); - spec = GetIndexHelpers.findByName(allIndexes, "c_1"); - assert.neq(null, spec, "Foreground index 'c_1' not found: " + tojson(allIndexes)); - assert.eq(2, spec.v, "Expected v=2 index to be built"); - // When applying a "u" (update) op, we default to 'UpdateNode' update semantics, and $set // operations add new fields in lexicographic order. res = assert.commandWorked(db.adminCommand({ diff --git a/jstests/core/apply_ops_index_collation.js b/jstests/core/apply_ops_index_collation.js index 135cb37483f..d58d3659223 100644 --- a/jstests/core/apply_ops_index_collation.js +++ b/jstests/core/apply_ops_index_collation.js @@ -87,66 +87,4 @@ assert.neq(null, spec, "Index 'b_1' not found: " + tojson(allIndexes)); assert.eq(1, spec.v, tojson(spec)); assert(!spec.hasOwnProperty("collation"), tojson(spec)); - - // An index created using an insert-style oplog entry with a non-simple collation does not - // inherit the collection default collation. - res = assert.commandWorked(db.adminCommand({ - applyOps: [{ - op: "i", - ns: db.system.indexes.getFullName(), - o: { - v: 2, - key: {c: 1}, - name: "c_1_en", - ns: coll.getFullName(), - collation: { - locale: "en_US", - caseLevel: false, - caseFirst: "off", - strength: 3, - numericOrdering: false, - alternate: "non-ignorable", - maxVariable: "punct", - normalization: false, - backwards: false, - version: "57.1" - } - } - }] - })); - allIndexes = coll.getIndexes(); - spec = GetIndexHelpers.findByName(allIndexes, "c_1_en"); - assert.neq(null, spec, "Index 'c_1_en' not found: " + tojson(allIndexes)); - assert.eq(2, spec.v, tojson(spec)); - assert.eq("en_US", spec.collation.locale, tojson(spec)); - - // An index created using an insert-style oplog entry with a simple collation does not inherit - // the collection default collation. - res = assert.commandWorked(db.adminCommand({ - applyOps: [{ - op: "i", - ns: db.system.indexes.getFullName(), - o: {v: 2, key: {c: 1}, name: "c_1", ns: coll.getFullName()} - }] - })); - allIndexes = coll.getIndexes(); - spec = GetIndexHelpers.findByName(allIndexes, "c_1"); - assert.neq(null, spec, "Index 'c_1' not found: " + tojson(allIndexes)); - assert.eq(2, spec.v, tojson(spec)); - assert(!spec.hasOwnProperty("collation"), tojson(spec)); - - // A v=1 index created using an insert-style oplog entry does not inherit the collection default - // collation. - res = assert.commandWorked(db.adminCommand({ - applyOps: [{ - op: "i", - ns: db.system.indexes.getFullName(), - o: {v: 1, key: {d: 1}, name: "d_1", ns: coll.getFullName()} - }] - })); - allIndexes = coll.getIndexes(); - spec = GetIndexHelpers.findByName(allIndexes, "d_1"); - assert.neq(null, spec, "Index 'd_1' not found: " + tojson(allIndexes)); - assert.eq(1, spec.v, tojson(spec)); - assert(!spec.hasOwnProperty("collation"), tojson(spec)); })(); diff --git a/jstests/core/batch_write_command_insert.js b/jstests/core/batch_write_command_insert.js index d1e3fc8b600..5d0a85fa763 100644 --- a/jstests/core/batch_write_command_insert.js +++ b/jstests/core/batch_write_command_insert.js @@ -261,129 +261,6 @@ coll.find().forEach(function(doc) { }); // -// -// Index insertion tests - currently supported via bulk write commands - -// -// Successful index creation -coll.drop(); -request = { - insert: "system.indexes", - documents: [{ns: coll.toString(), key: {x: 1}, name: "x_1"}] -}; -result = coll.runCommand(request); -assert(result.ok, tojson(result)); -assert.eq(1, result.n); -var allIndexes = coll.getIndexes(); -var spec = GetIndexHelpers.findByName(allIndexes, "x_1"); -assert.neq(null, spec, "Index with name 'x_1' not found: " + tojson(allIndexes)); -assert.lte(2, spec.v, tojson(spec)); - -// Test that a v=1 index can be created by inserting into the system.indexes collection. -coll.drop(); -request = { - insert: "system.indexes", - documents: [{ns: coll.toString(), key: {x: 1}, name: "x_1", v: 1}] -}; -result = coll.runCommand(request); -assert(result.ok, tojson(result)); -assert.eq(1, result.n); -allIndexes = coll.getIndexes(); -spec = GetIndexHelpers.findByName(allIndexes, "x_1"); -assert.neq(null, spec, "Index with name 'x_1' not found: " + tojson(allIndexes)); -assert.eq(1, spec.v, tojson(spec)); - -// -// Duplicate index insertion gives n = 0 -coll.drop(); -coll.ensureIndex({x: 1}, {unique: true}); -request = { - insert: "system.indexes", - documents: [{ns: coll.toString(), key: {x: 1}, name: "x_1", unique: true}] -}; -result = coll.runCommand(request); -assert(result.ok, tojson(result)); -assert.eq(0, result.n, 'duplicate index insertion should give n = 0: ' + tojson(result)); -assert(!('writeErrors' in result)); -assert.eq(coll.getIndexes().length, 2); - -// -// Invalid index insertion with mismatched collection db -coll.drop(); -request = { - insert: "system.indexes", - documents: [{ns: "invalid." + coll.getName(), key: {x: 1}, name: "x_1", unique: true}] -}; -result = coll.runCommand(request); -assert(!result.ok || (result.n == 0 && result.writeErrors.length == 1), tojson(result)); -assert.eq(coll.getIndexes().length, 0); - -// -// Empty index insertion -coll.drop(); -request = { - insert: "system.indexes", - documents: [{}] -}; -result = coll.runCommand(request); -assert(!result.ok || (result.n == 0 && result.writeErrors.length == 1), tojson(result)); -assert.eq(coll.getIndexes().length, 0); - -// -// Invalid index desc -coll.drop(); -request = { - insert: "system.indexes", - documents: [{ns: coll.toString()}] -}; -result = coll.runCommand(request); -assert(result.ok, tojson(result)); -assert.eq(0, result.n); -assert.eq(0, result.writeErrors[0].index); -assert.eq(coll.getIndexes().length, 0); - -// -// Invalid index desc -coll.drop(); -request = { - insert: "system.indexes", - documents: [{ns: coll.toString(), key: {x: 1}}] -}; -result = coll.runCommand(request); -print(tojson(result)); -assert(result.ok, tojson(result)); -assert.eq(0, result.n); -assert.eq(0, result.writeErrors[0].index); -assert.eq(coll.getIndexes().length, 0); - -// -// Invalid index desc -coll.drop(); -request = { - insert: "system.indexes", - documents: [{ns: coll.toString(), name: "x_1"}] -}; -result = coll.runCommand(request); -assert(result.ok, tojson(result)); -assert.eq(0, result.n); -assert.eq(0, result.writeErrors[0].index); -assert.eq(coll.getIndexes().length, 0); - -// -// Cannot insert more than one index at a time through the batch writes -coll.drop(); -request = { - insert: "system.indexes", - documents: [ - {ns: coll.toString(), key: {x: 1}, name: "x_1"}, - {ns: coll.toString(), key: {y: 1}, name: "y_1"} - ] -}; -result = coll.runCommand(request); -assert(!result.ok, tojson(result)); -assert.eq(coll.getIndexes().length, 0); - -// // Ensure we error out correctly in the middle of a batch coll.drop(); coll.insert({_id: 50}); // Create a document to force a duplicate key exception. @@ -398,21 +275,3 @@ try { } catch (err) { assert(coll.count() == 50, "Unexpected number inserted by bulk write: " + coll.count()); } - -// -// Background index creation -// Note: due to SERVER-13304 this test is at the end of this file, and we don't drop -// the collection afterwards. -coll.drop(); -coll.insert({x: 1}); -request = { - insert: "system.indexes", - documents: [{ns: coll.toString(), key: {x: 1}, name: "x_1", background: true}] -}; -result = coll.runCommand(request); -assert(result.ok, tojson(result)); -assert.eq(1, result.n); -allIndexes = coll.getIndexes(); -spec = GetIndexHelpers.findByName(allIndexes, "x_1"); -assert.neq(null, spec, "Index with name 'x_1' not found: " + tojson(allIndexes)); -assert.lte(2, spec.v, tojson(spec)); diff --git a/jstests/core/cannot_create_system_dot_indexes.js b/jstests/core/cannot_create_system_dot_indexes.js deleted file mode 100644 index 50928d5a27d..00000000000 --- a/jstests/core/cannot_create_system_dot_indexes.js +++ /dev/null @@ -1,51 +0,0 @@ -// Tests that a user cannot create the 'system.indexes' collection. -// @tags: [requires_non_retryable_commands] -(function() { - "use strict"; - - // Cannot create system.indexes using the 'create' command. - assert.commandFailedWithCode(db.createCollection("system.indexes"), - ErrorCodes.InvalidNamespace); - assert.eq( - 0, db.getCollectionInfos({name: "system.indexes"}).length, tojson(db.getCollectionInfos())); - - // Cannot create system.indexes using the 'renameCollection' command. - db.coll.drop(); - assert.commandWorked(db.coll.insert({})); - assert.commandFailed(db.coll.renameCollection("system.indexes")); - assert.eq( - 0, db.getCollectionInfos({name: "system.indexes"}).length, tojson(db.getCollectionInfos())); - - // Cannot create system.indexes using the 'createIndexes' command. - assert.commandFailedWithCode(db.system.indexes.createIndex({a: 1}), - ErrorCodes.InvalidNamespace); - assert.eq( - 0, db.getCollectionInfos({name: "system.indexes"}).length, tojson(db.getCollectionInfos())); - - // Cannot create system.indexes using the 'insert' command. - assert.commandWorked( - db.system.indexes.insert({ns: "test.coll", v: 2, key: {a: 1}, name: "a_1"})); - assert.eq( - 0, db.getCollectionInfos({name: "system.indexes"}).length, tojson(db.getCollectionInfos())); - - // Cannot create system.indexes using the 'update' command with upsert=true. - assert.commandFailedWithCode( - db.system.indexes.update({ns: "test.coll", v: 2, key: {a: 1}, name: "a_1"}, - {$set: {name: "a_1"}}, - {upsert: true}), - ErrorCodes.InvalidNamespace); - assert.eq( - 0, db.getCollectionInfos({name: "system.indexes"}).length, tojson(db.getCollectionInfos())); - - // Cannot create system.indexes using the 'findAndModify' command with upsert=true. - let error = assert.throws(() => { - db.system.indexes.findAndModify({ - query: {ns: "test.coll", v: 2, key: {a: 1}, name: "a_1"}, - update: {$set: {name: "a_1"}}, - upsert: true - }); - }); - assert.eq(error.code, ErrorCodes.InvalidNamespace); - assert.eq( - 0, db.getCollectionInfos({name: "system.indexes"}).length, tojson(db.getCollectionInfos())); -}()); diff --git a/jstests/core/indexOtherNamespace.js b/jstests/core/indexOtherNamespace.js deleted file mode 100644 index 86589714a35..00000000000 --- a/jstests/core/indexOtherNamespace.js +++ /dev/null @@ -1,19 +0,0 @@ -// SERVER-8814: Test that only the system.indexes namespace can be used to build indexes. - -// Include helpers for analyzing explain output. -load("jstests/libs/analyze_plan.js"); - -var otherDB = db.getSiblingDB("indexOtherNS"); -otherDB.dropDatabase(); - -otherDB.foo.insert({a: 1}); -assert.eq(1, otherDB.foo.getIndexes().length); -assert(isCollscan(db, otherDB.foo.find({a: 1}).explain().queryPlanner.winningPlan)); - -assert.writeError( - otherDB.randomNS.system.indexes.insert({ns: "indexOtherNS.foo", key: {a: 1}, name: "a_1"})); - -// Assert that index didn't actually get built -assert.eq(1, otherDB.foo.getIndexes().length); -assert(isCollscan(db, otherDB.foo.find({a: 1}).explain().queryPlanner.winningPlan)); -otherDB.dropDatabase(); diff --git a/jstests/core/indexapi.js b/jstests/core/indexapi.js index 3153519501a..14cf634e556 100644 --- a/jstests/core/indexapi.js +++ b/jstests/core/indexapi.js @@ -43,7 +43,3 @@ idx = t.getIndexes(); assert.eq(2, idx.length, "M1"); assert.eq(key, idx[1].key, "M2"); assert(idx[1].unique, "M3"); -// printjson( idx ); - -// Test that attempting to create index in an invalid namespace fails. -assert.writeError(db.system.indexes.insert({ns: "test", key: {x: 1}, name: "x"})); diff --git a/jstests/core/indexes_on_indexes.js b/jstests/core/indexes_on_indexes.js deleted file mode 100644 index b7c4b7edcb5..00000000000 --- a/jstests/core/indexes_on_indexes.js +++ /dev/null @@ -1,25 +0,0 @@ -// Ensure an index cannot be created on system.indexes -(function() { - var t = db.getSiblingDB("indexes_on_indexes"); - t.dropDatabase(); - t.coll.insert({}); - - printjson(t.system.indexes.getIndexes()); - assert.eq(t.system.indexes.getIndexes().length, 0); - - print("trying via ensureIndex"); - assert.commandFailed(t.system.indexes.ensureIndex({_id: 1})); - printjson(t.system.indexes.getIndexes()); - assert.eq(t.system.indexes.getIndexes().length, 0); - - print("trying via createIndex"); - assert.commandFailed(t.system.indexes.createIndex({_id: 1})); - printjson(t.system.indexes.getIndexes()); - assert.eq(t.system.indexes.getIndexes().length, 0); - - print("trying via direct insertion"); - assert.commandFailed(t.system.indexes.insert( - {v: 1, key: {_id: 1}, ns: "indexes_on_indexes.system.indexes", name: "wontwork"})); - printjson(t.system.indexes.getIndexes()); - assert.eq(t.system.indexes.getIndexes().length, 0); -}()); diff --git a/jstests/core/list_collections1.js b/jstests/core/list_collections1.js index f23331b97ce..33377c2db97 100644 --- a/jstests/core/list_collections1.js +++ b/jstests/core/list_collections1.js @@ -58,20 +58,6 @@ assert(!collObj.hasOwnProperty("idIndex"), tojson(collObj)); // - // Test basic command output for system.indexes. - // - - collObj = res.cursor.firstBatch.filter(function(c) { - return c.name === "system.indexes"; - })[0]; - if (collObj) { - assert.eq("object", typeof(collObj.options), tojson(collObj)); - assert.eq("collection", collObj.type, tojson(collObj)); - assert.eq(false, collObj.info.readOnly, tojson(collObj)); - assert(!collObj.hasOwnProperty("idIndex"), tojson(collObj)); - } - - // // Test basic usage with DBCommandCursor. // diff --git a/jstests/core/list_collections_filter.js b/jstests/core/list_collections_filter.js index 76feeb9dd4b..ef162642bdf 100644 --- a/jstests/core/list_collections_filter.js +++ b/jstests/core/list_collections_filter.js @@ -24,16 +24,12 @@ function stripToName(result) { return result.name; } - function isNotSystemIndexes(result) { - return result !== "system.indexes"; - } - var cursorResultNames = cursor.toArray().map(stripToName).filter(isNotSystemIndexes); + var cursorResultNames = cursor.toArray().map(stripToName); assert.eq(cursorResultNames.sort(), expectedNames.sort()); // Assert the shell helper returns the same list, but in sorted order. - var shellResultNames = - mydb.getCollectionInfos(filter).map(stripToName).filter(isNotSystemIndexes); + var shellResultNames = mydb.getCollectionInfos(filter).map(stripToName); assert.eq(shellResultNames, expectedNames.sort()); } diff --git a/jstests/core/list_collections_no_views.js b/jstests/core/list_collections_no_views.js index 7ff19c9adce..b380f8c3db6 100644 --- a/jstests/core/list_collections_no_views.js +++ b/jstests/core/list_collections_no_views.js @@ -26,9 +26,6 @@ assert.eq(allExpected, all.cursor.firstBatch - .filter(function(c) { - return c.name != "system.indexes"; - }) .map(function(c) { return {name: c.name, type: c.type}; }) @@ -66,9 +63,6 @@ assert.eq(collOnlyExpected, collOnly.cursor.firstBatch - .filter(function(c) { - return c.name != "system.indexes"; - }) .map(function(c) { return {name: c.name, type: c.type}; }) @@ -93,9 +87,6 @@ assert.eq(viewOnlyExpected, viewOnly.cursor.firstBatch - .filter(function(c) { - return c.name != "system.indexes"; - }) .map(function(c) { return {name: c.name, type: c.type}; }) @@ -117,9 +108,6 @@ let collOnlyInvalidView = mydb.runCommand(collOnlyCommand); assert.eq(collOnlyExpected, collOnlyInvalidView.cursor.firstBatch - .filter(function(c) { - return c.name != "system.indexes"; - }) .map(function(c) { return {name: c.name, type: c.type}; }) diff --git a/jstests/core/list_indexes_invalidation.js b/jstests/core/list_indexes_invalidation.js index 75a62da531a..38a70ce4005 100644 --- a/jstests/core/list_indexes_invalidation.js +++ b/jstests/core/list_indexes_invalidation.js @@ -2,7 +2,6 @@ // on sharded collections. // @tags: [assumes_unsharded_collection, requires_non_retryable_commands, requires_fastcount] -// SERVER-24963/SERVER-27930 Missing invalidation for system.indexes writes (function() { 'use strict'; let collName = 'system_indexes_invalidations'; diff --git a/jstests/core/list_namespaces_invalidation.js b/jstests/core/list_namespaces_invalidation.js index da5d392b9f5..ebd5dd82542 100644 --- a/jstests/core/list_namespaces_invalidation.js +++ b/jstests/core/list_namespaces_invalidation.js @@ -1,6 +1,4 @@ // @tags: [requires_non_retryable_commands, requires_fastcount] - -// SERVER-27996/SERVER-28022 Missing invalidation for system.namespaces writes (function() { 'use strict'; let dbInvalidName = 'system_namespaces_invalidations'; diff --git a/jstests/core/operation_latency_histogram.js b/jstests/core/operation_latency_histogram.js index 1e971dc93eb..a8f0800b327 100644 --- a/jstests/core/operation_latency_histogram.js +++ b/jstests/core/operation_latency_histogram.js @@ -121,12 +121,7 @@ // CreateIndex assert.commandWorked(testColl.createIndex({pt: "2dsphere"})); - // The createIndex shell helper is run as an insert when writeMode is not "commands". - if (testDB.getMongo().writeMode() === "commands") { - lastHistogram = assertHistogramDiffEq(testColl, lastHistogram, 0, 0, 1); - } else { - lastHistogram = assertHistogramDiffEq(testColl, lastHistogram, 0, 1, 0); - } + lastHistogram = assertHistogramDiffEq(testColl, lastHistogram, 0, 0, 1); // $geoNear aggregation stage assert.commandWorked(testDB.runCommand({ diff --git a/jstests/core/rename8.js b/jstests/core/rename8.js index d0a2a2fea60..923b0a52cec 100644 --- a/jstests/core/rename8.js +++ b/jstests/core/rename8.js @@ -5,7 +5,6 @@ var testdb = db.getSiblingDB("rename8"); // to avoid breaking other tests when we touch system.users var coll = testdb.rename8; -var systemNamespaces = testdb.system.namespaces; var systemFoo = testdb.system.foo; var systemUsers = testdb.system.users; @@ -18,11 +17,6 @@ coll.insert({}); assert.commandFailed(coll.renameCollection(systemFoo.getName())); assert.commandFailed(systemFoo.renameCollection(coll.getName())); -// same with system.namespaces, even though it does exist -assert.commandFailed(coll.renameCollection(systemNamespaces.getName())); -assert.commandFailed(coll.renameCollection(systemNamespaces.getName(), /*dropTarget*/ true)); -assert.commandFailed(systemNamespaces.renameCollection(coll.getName())); - // system.users is whitelisted so these should work assert.commandWorked(coll.renameCollection(systemUsers.getName())); assert.commandWorked(systemUsers.renameCollection(coll.getName())); diff --git a/jstests/core/top.js b/jstests/core/top.js index 5919cdbe59d..eca4570472f 100644 --- a/jstests/core/top.js +++ b/jstests/core/top.js @@ -114,12 +114,7 @@ // createIndex res = assert.commandWorked(testColl.createIndex({x: 1})); assertTopDiffEq(testColl, lastTop, "writeLock", 1); - // The createIndex shell helper is run as an insert when writeMode is not "commands". - if (testDB.getMongo().writeMode() === "commands") { - lastTop = assertTopDiffEq(testColl, lastTop, "commands", 1); - } else { - lastTop = assertTopDiffEq(testColl, lastTop, "insert", 1); - } + lastTop = assertTopDiffEq(testColl, lastTop, "commands", 1); // dropIndex res = assert.commandWorked(testColl.dropIndex({x: 1})); diff --git a/jstests/core/txns/do_txn_atomicity.js b/jstests/core/txns/do_txn_atomicity.js index f7077bd863e..59307a4641b 100644 --- a/jstests/core/txns/do_txn_atomicity.js +++ b/jstests/core/txns/do_txn_atomicity.js @@ -31,7 +31,7 @@ ], txnNumber: NumberLong(txnNumber++) }), - 16886); // nsToCollectionSubstring: no . + ErrorCodes.InvalidNamespace); assert.eq(t.count({x: 1}), 0); // Operations on non-existent databases cannot be atomic. diff --git a/jstests/core/views/views_creation.js b/jstests/core/views/views_creation.js index 7fd2686dff5..68c896118a5 100644 --- a/jstests/core/views/views_creation.js +++ b/jstests/core/views/views_creation.js @@ -20,11 +20,6 @@ ErrorCodes.InvalidNamespace, "Created an illegal view named 'system.views'"); - assert.commandFailedWithCode( - viewsDB.runCommand({create: "system.indexes", viewOn: "collection"}), - ErrorCodes.InvalidNamespace, - "Created an illegal view named 'system.indexes'"); - // Collections that start with 'system.' that are not special to MongoDB fail with a different // error code. assert.commandFailedWithCode(viewsDB.runCommand({create: "system.foo", viewOn: "collection"}), diff --git a/jstests/core/views/views_drop.js b/jstests/core/views/views_drop.js index bc2a654415e..bf3498d85a6 100644 --- a/jstests/core/views/views_drop.js +++ b/jstests/core/views/views_drop.js @@ -27,7 +27,7 @@ // Database should now be empty. let res = viewsDB.runCommand({listCollections: 1}); assert.commandWorked(res); - assert.eq(res.cursor.firstBatch.filter((entry) => entry.name != "system.indexes"), + assert.eq(res.cursor.firstBatch, [], viewsDBName + " is not empty after deleting views and system.views"); })(); diff --git a/jstests/multiVersion/index_bigkeys_secondary_downgrade_during_index_build_background.js b/jstests/multiVersion/index_bigkeys_secondary_downgrade_during_index_build_background.js index 80f1a911b61..20836332643 100644 --- a/jstests/multiVersion/index_bigkeys_secondary_downgrade_during_index_build_background.js +++ b/jstests/multiVersion/index_bigkeys_secondary_downgrade_during_index_build_background.js @@ -45,7 +45,16 @@ // Make sure index build starts on the secondary. assert.soon(() => { - let res = secondaryDB.currentOp({"ns": "test.system.indexes"}); + // The currentOp entry for createIndexes looks like: + // {..., + // "command": {"v": 2, + // "key": {x: 1}, + // "name": "x_1", + // "background": true, + // "ns": "test.index_bigkeys_downgrade_during_index_build"}, + // ... + // } + let res = secondaryDB.currentOp({'command.name': "x_1"}); return res['ok'] === 1 && res["inprog"].length > 0; }); diff --git a/jstests/noPassthrough/plan_cache_index_create.js b/jstests/noPassthrough/plan_cache_index_create.js index 57f63a7a326..9213f59bc38 100644 --- a/jstests/noPassthrough/plan_cache_index_create.js +++ b/jstests/noPassthrough/plan_cache_index_create.js @@ -16,10 +16,7 @@ "command.indexes.0.name": indexName }; // TODO SERVER-34830: Add command name filter for secondaries once available. - const secondaryIndexBuildFilter = { - ns: dbName + ".system.indexes", - "command.name": indexName - }; + const secondaryIndexBuildFilter = {"command.name": indexName}; const curOp = testDB.getSiblingDB("admin").aggregate([ {$currentOp: {}}, {$match: {$or: [primaryIndexBuildFilter, secondaryIndexBuildFilter]}} diff --git a/jstests/noPassthroughWithMongod/create_indexes_shell_helper.js b/jstests/noPassthroughWithMongod/create_indexes_shell_helper.js index 6d9937139ae..8a36f7ee11e 100644 --- a/jstests/noPassthroughWithMongod/create_indexes_shell_helper.js +++ b/jstests/noPassthroughWithMongod/create_indexes_shell_helper.js @@ -9,11 +9,8 @@ var commandsRan = []; var insertsRan = []; var mockMongo = { - forceWriteMode: function(mode) { - this._writeMode = mode; - }, writeMode: function() { - return this._writeMode; + return "commands"; }, getSlaveOk: function() { return true; @@ -22,10 +19,6 @@ commandsRan.push({db: db, cmd: cmd, opts: opts}); return {ok: 1.0}; }, - insert: function(db, indexSpecs, opts) { - insertsRan.push({db: db, indexSpecs: indexSpecs, opts: opts}); - return {ok: 1.0}; - }, getWriteConcern: function() { return null; }, @@ -58,8 +51,6 @@ db._mongo = mockMongo; db._session = new _DummyDriverSession(mockMongo); - mockMongo.forceWriteMode("commands"); - t.createIndexes([{x: 1}]); assert.eq(commandsRan.length, 1); assert(commandsRan[0].cmd.hasOwnProperty("createIndexes")); @@ -79,19 +70,6 @@ assert.eq(commandsRan.length, 1); assert(commandsRan[0].cmd.hasOwnProperty("createIndexes")); assert.eq(commandsRan[0].cmd["indexes"][0], {key: {a: 1}, name: "a_1"}); - - db.getMongo().forceWriteMode("compatibility"); - - commandsRan = []; - assert.eq(commandsRan.length, 0); - t.createIndex({b: 1}); - assert.eq(insertsRan.length, 1); - assert.eq(insertsRan[0]["indexSpecs"]["ns"], "test.create_indexes_shell_helper"); - assert.eq(insertsRan[0]["indexSpecs"]["key"], {b: 1}); - assert.eq(insertsRan[0]["indexSpecs"]["name"], "b_1"); - // getLastError is called in the course of the bulk insert - assert.eq(commandsRan.length, 1); - assert(commandsRan[0].cmd.hasOwnProperty("getlasterror")); } finally { db._mongo = mongo; db._session = new _DummyDriverSession(mongo); diff --git a/jstests/replsets/apply_ops_create_indexes.js b/jstests/replsets/apply_ops_create_indexes.js index 4fe813b5ed4..f400265afb0 100644 --- a/jstests/replsets/apply_ops_create_indexes.js +++ b/jstests/replsets/apply_ops_create_indexes.js @@ -1,6 +1,5 @@ /* This test ensures that indexes created by running applyOps are successfully replicated (see - * SERVER-31435). Both insertion into system.indexes and createIndexes style oplog entries are - * passed to applyOps here. + * SERVER-31435). */ (function() { "use strict"; @@ -70,33 +69,5 @@ ensureIndexExists(secondaryTestDB, collName, cmdFormatIndexName, 2); } - // Create an index by inserting into system.indexes in applyOps. - let insertFormatIndexName = "b_1"; - cmd = { - applyOps: [{ - "op": "i", - "ns": dbName + ".system.indexes", - "o": { - ns: dbName + "." + collName, - key: {b: 1}, - name: insertFormatIndexName, - } - }] - }; - res = primaryTestDB.adminCommand(cmd); - assert.commandWorked(res, "could not run " + tojson(cmd)); - rst.awaitReplication(); - ensureIndexExists(primaryTestDB, collName, insertFormatIndexName, 3); - - // Make sure the index was replicated to the secondaries. - secondaries = rst.getSecondaries(); - for (let j = 0; j < secondaries.length; j++) { - let secondaryTestDB = secondaries[j].getDB(dbName); - ensureIndexExists(secondaryTestDB, collName, insertFormatIndexName, 3); - } - - localDB = rst.getPrimary().getDB("local"); - ensureOplogEntryExists(localDB, insertFormatIndexName); - rst.stopSet(); }()); diff --git a/jstests/replsets/oplog_format_create_indexes.js b/jstests/replsets/oplog_format_create_indexes.js index ec779e28457..0697df44b07 100644 --- a/jstests/replsets/oplog_format_create_indexes.js +++ b/jstests/replsets/oplog_format_create_indexes.js @@ -26,13 +26,10 @@ indexSpec, "Index with key pattern " + tojson(keyPattern) + " not found: " + tojson(allIndexes)); - // Find either the old-style insert into system.indexes index creations, or new-style - // createIndexes command entries. + // Find the createIndexes command entries. const indexCreationOplogQuery = { - $or: [ - {op: "i", ns: testDB.system.indexes.getFullName()}, - {op: "c", ns: testDB.getName() + ".$cmd", "o.createIndexes": coll.getName()} - ] + op: "c", + ns: testDB.getName() + ".$cmd", "o.createIndexes": coll.getName() }; const allOplogEntries = oplogColl.find(indexCreationOplogQuery).toArray(); diff --git a/jstests/replsets/rollback_views.js b/jstests/replsets/rollback_views.js index a833ed82ecc..a7c89014de6 100644 --- a/jstests/replsets/rollback_views.js +++ b/jstests/replsets/rollback_views.js @@ -23,11 +23,10 @@ load("jstests/replsets/rslib.js"); let checkedRunCommand = (db, cmd) => ((res, msg) => (assert.commandWorked(res, msg), res))(db.runCommand(cmd), tojson(cmd)); - // Like db.getCollectionNames, but allows a filter and works without system.namespaces. + // Like db.getCollectionNames, but allows a filter. let getCollectionNames = (db, filter) => checkedRunCommand(db, {listCollections: 1, filter}) .cursor.firstBatch.map((entry) => entry.name) - .sort() - .filter((name) => name != "system.indexes"); + .sort(); // Function that checks that all array elements are equal, and returns the unique element. let checkEqual = (array, what) => diff --git a/jstests/sharding/clone_catalog_data.js b/jstests/sharding/clone_catalog_data.js index f0cf4fac12d..dfb5863f69f 100644 --- a/jstests/sharding/clone_catalog_data.js +++ b/jstests/sharding/clone_catalog_data.js @@ -54,7 +54,7 @@ var res = fromShard.getDB('test').runCommand({listCollections: 1}); assert.commandWorked(res); - var collections = res.cursor.firstBatch.filter(coll => coll.name != 'system.indexes'); + var collections = res.cursor.firstBatch; collections.sort(sortByName); var coll2uuid = collections[1].info.uuid; @@ -67,7 +67,7 @@ res = toShard.getDB('test').runCommand({listCollections: 1}); assert.commandWorked(res); - collections = res.cursor.firstBatch.filter(coll => coll.name != 'system.indexes'); + collections = res.cursor.firstBatch; // There should be 2 collections: coll1, coll2 assert.eq(collections.length, 2); diff --git a/jstests/sharding/move_primary_clone_test.js b/jstests/sharding/move_primary_clone_test.js index 2ef19b044bf..6c30ff56b46 100644 --- a/jstests/sharding/move_primary_clone_test.js +++ b/jstests/sharding/move_primary_clone_test.js @@ -13,9 +13,7 @@ var res = toShard.getDB("test1").runCommand({listCollections: 1}); assert.commandWorked(res); - // Remove system.indexes collection (which exists in mmap) - // Indexes are checked separately below. - var collections = res.cursor.firstBatch.filter(coll => coll.name != 'system.indexes'); + var collections = res.cursor.firstBatch; // Sort collections by name. collections.sort(sortByName); @@ -145,8 +143,7 @@ assert.eq(0, toShard.getDB("test1").bar.count(), "to shard has data before move"); var listCollsFrom = fromShard.getDB("test1").runCommand({listCollections: 1}); - var fromColls = - listCollsFrom.cursor.firstBatch.filter(coll => coll.name != 'system.indexes'); + var fromColls = listCollsFrom.cursor.firstBatch; fromColls.sort(sortByName); var baruuid = fromColls[0].info.uuid; var foouuid = fromColls[1].info.uuid; @@ -194,8 +191,7 @@ assert.eq(0, toShard.getDB("test1").bar.count(), "to shard has data before move"); var listCollsFrom = fromShard.getDB("test1").runCommand({listCollections: 1}); - var fromColls = - listCollsFrom.cursor.firstBatch.filter(coll => coll.name != 'system.indexes'); + var fromColls = listCollsFrom.cursor.firstBatch; fromColls.sort(sortByName); var baruuid = fromColls[0].info.uuid; var foouuid = fromColls[1].info.uuid; diff --git a/jstests/sharding/sharding_system_namespaces.js b/jstests/sharding/sharding_system_namespaces.js index b46487dacd8..d44f1150d64 100644 --- a/jstests/sharding/sharding_system_namespaces.js +++ b/jstests/sharding/sharding_system_namespaces.js @@ -1,12 +1,6 @@ -// SERVER-16498 d_migrate.cpp should not rely on system.namespaces -// // This test creates a sharded collection with wiredtiger options. // When the chunks of this collection get migrated to the other shard, // the other shard should create the collection with the same options. -// However, before SERVER-16498, the receiver relies on checking -// system.namespaces on the donor, which is empty on wiredtiger. -// As a result, the new collection created on receiver has different -// options. var st = new ShardingTest({shards: 2}); diff --git a/jstests/sharding/stats.js b/jstests/sharding/stats.js index 26bd656ac4d..76c64c8b41f 100644 --- a/jstests/sharding/stats.js +++ b/jstests/sharding/stats.js @@ -84,10 +84,8 @@ 'indexDetails should not be present in s.shard1.shardName: ' + tojson(x.shards[s.shard1.shardName])); - a_extras = - a.stats().objects - a.foo.count(); // things like system.namespaces and system.indexes - b_extras = - b.stats().objects - b.foo.count(); // things like system.namespaces and system.indexes + a_extras = a.stats().objects - a.foo.count(); + b_extras = b.stats().objects - b.foo.count(); print("a_extras: " + a_extras); print("b_extras: " + b_extras); diff --git a/jstests/tool/dumprestoreWithNoOptions.js b/jstests/tool/dumprestoreWithNoOptions.js index a1782d3ff7c..e6fdbd87ca8 100644 --- a/jstests/tool/dumprestoreWithNoOptions.js +++ b/jstests/tool/dumprestoreWithNoOptions.js @@ -13,10 +13,6 @@ t = new ToolTest("dumprestoreWithNoOptions"); t.startDB("foo"); db = t.db; -// We turn this off to prevent the server from touching the 'options' field in system.namespaces. -// This is important because we check exact values of the 'options' field in this test. -db.adminCommand({setParameter: 1, newCollectionsUsePowerOf2Sizes: false}); - dbname = db.getName(); dbname2 = "NOT_" + dbname; diff --git a/src/mongo/db/auth/authorization_session.h b/src/mongo/db/auth/authorization_session.h index 5042a1fd7e5..6afd520910b 100644 --- a/src/mongo/db/auth/authorization_session.h +++ b/src/mongo/db/auth/authorization_session.h @@ -202,12 +202,8 @@ public: const BSONObj& update, bool upsert) = 0; - // Checks if this connection has the privileges necessary to insert the given document - // to the given namespace. Correctly interprets inserts to system.indexes and performs - // the proper auth checks for index building. - virtual Status checkAuthForInsert(OperationContext* opCtx, - const NamespaceString& ns, - const BSONObj& document) = 0; + // Checks if this connection has the privileges necessary to insert to the given namespace. + virtual Status checkAuthForInsert(OperationContext* opCtx, const NamespaceString& ns) = 0; // Checks if this connection has the privileges necessary to perform a delete on the given // namespace. diff --git a/src/mongo/db/auth/authorization_session_impl.cpp b/src/mongo/db/auth/authorization_session_impl.cpp index c1920d36d63..7ef744aef6e 100644 --- a/src/mongo/db/auth/authorization_session_impl.cpp +++ b/src/mongo/db/auth/authorization_session_impl.cpp @@ -351,30 +351,14 @@ Status AuthorizationSessionImpl::checkAuthForGetMore(const NamespaceString& ns, } Status AuthorizationSessionImpl::checkAuthForInsert(OperationContext* opCtx, - const NamespaceString& ns, - const BSONObj& document) { - if (ns.coll() == "system.indexes"_sd) { - BSONElement nsElement = document["ns"]; - if (nsElement.type() != String) { - return Status(nsElement.type() == BSONType::EOO ? ErrorCodes::NoSuchKey - : ErrorCodes::TypeMismatch, - "Cannot authorize inserting into " - "system.indexes documents without a string-typed \"ns\" field."); - } - NamespaceString indexNS(nsElement.valueStringData()); - if (!isAuthorizedForActionsOnNamespace(indexNS, ActionType::createIndex)) { - return Status(ErrorCodes::Unauthorized, - str::stream() << "not authorized to create index on " << indexNS.ns()); - } - } else { - ActionSet required{ActionType::insert}; - if (documentValidationDisabled(opCtx)) { - required.addAction(ActionType::bypassDocumentValidation); - } - if (!isAuthorizedForActionsOnNamespace(ns, required)) { - return Status(ErrorCodes::Unauthorized, - str::stream() << "not authorized for insert on " << ns.ns()); - } + const NamespaceString& ns) { + ActionSet required{ActionType::insert}; + if (documentValidationDisabled(opCtx)) { + required.addAction(ActionType::bypassDocumentValidation); + } + if (!isAuthorizedForActionsOnNamespace(ns, required)) { + return Status(ErrorCodes::Unauthorized, + str::stream() << "not authorized for insert on " << ns.ns()); } return Status::OK(); @@ -747,13 +731,9 @@ bool AuthorizationSessionImpl::isAuthorizedToListCollections(StringData dbname, return true; } - // Check for the listCollections ActionType on the database or find on system.namespaces for - // pre 3.0 systems. + // Check for the listCollections ActionType on the database. return AuthorizationSessionImpl::isAuthorizedForActionsOnResource( - ResourcePattern::forDatabaseName(dbname), ActionType::listCollections) || - AuthorizationSessionImpl::isAuthorizedForActionsOnResource( - ResourcePattern::forExactNamespace(NamespaceString(dbname, "system.namespaces")), - ActionType::find); + ResourcePattern::forDatabaseName(dbname), ActionType::listCollections); } bool AuthorizationSessionImpl::isAuthenticatedAsUserWithRole(const RoleName& roleName) { diff --git a/src/mongo/db/auth/authorization_session_impl.h b/src/mongo/db/auth/authorization_session_impl.h index 5449d2a99b8..b0b6bb731d3 100644 --- a/src/mongo/db/auth/authorization_session_impl.h +++ b/src/mongo/db/auth/authorization_session_impl.h @@ -113,9 +113,7 @@ public: const BSONObj& update, bool upsert) override; - Status checkAuthForInsert(OperationContext* opCtx, - const NamespaceString& ns, - const BSONObj& document) override; + Status checkAuthForInsert(OperationContext* opCtx, const NamespaceString& ns) override; Status checkAuthForDelete(OperationContext* opCtx, const NamespaceString& ns, diff --git a/src/mongo/db/auth/authorization_session_test.cpp b/src/mongo/db/auth/authorization_session_test.cpp index e629f50cac5..cad01f09e9b 100644 --- a/src/mongo/db/auth/authorization_session_test.cpp +++ b/src/mongo/db/auth/authorization_session_test.cpp @@ -149,20 +149,12 @@ const ResourcePattern otherUsersCollResource( ResourcePattern::forExactNamespace(NamespaceString("other.system.users"))); const ResourcePattern thirdUsersCollResource( ResourcePattern::forExactNamespace(NamespaceString("third.system.users"))); -const ResourcePattern testIndexesCollResource( - ResourcePattern::forExactNamespace(NamespaceString("test.system.indexes"))); -const ResourcePattern otherIndexesCollResource( - ResourcePattern::forExactNamespace(NamespaceString("other.system.indexes"))); -const ResourcePattern thirdIndexesCollResource( - ResourcePattern::forExactNamespace(NamespaceString("third.system.indexes"))); const ResourcePattern testProfileCollResource( ResourcePattern::forExactNamespace(NamespaceString("test.system.profile"))); const ResourcePattern otherProfileCollResource( ResourcePattern::forExactNamespace(NamespaceString("other.system.profile"))); const ResourcePattern thirdProfileCollResource( ResourcePattern::forExactNamespace(NamespaceString("third.system.profile"))); -const ResourcePattern testSystemNamespacesResource( - ResourcePattern::forExactNamespace(NamespaceString("test.system.namespaces"))); TEST_F(AuthorizationSessionTest, AddUserAndCheckAuthorization) { // Check that disabling auth checks works @@ -360,12 +352,8 @@ TEST_F(AuthorizationSessionTest, SystemCollectionsAccessControl) { ASSERT_FALSE( authzSession->isAuthorizedForActionsOnResource(otherUsersCollResource, ActionType::find)); ASSERT_TRUE( - authzSession->isAuthorizedForActionsOnResource(testIndexesCollResource, ActionType::find)); - ASSERT_TRUE( authzSession->isAuthorizedForActionsOnResource(testProfileCollResource, ActionType::find)); ASSERT_TRUE( - authzSession->isAuthorizedForActionsOnResource(otherIndexesCollResource, ActionType::find)); - ASSERT_TRUE( authzSession->isAuthorizedForActionsOnResource(otherProfileCollResource, ActionType::find)); // Logging in as useradminany@test implicitly logs out rwany@test. @@ -379,12 +367,8 @@ TEST_F(AuthorizationSessionTest, SystemCollectionsAccessControl) { ASSERT_TRUE( authzSession->isAuthorizedForActionsOnResource(otherUsersCollResource, ActionType::find)); ASSERT_FALSE( - authzSession->isAuthorizedForActionsOnResource(testIndexesCollResource, ActionType::find)); - ASSERT_FALSE( authzSession->isAuthorizedForActionsOnResource(testProfileCollResource, ActionType::find)); ASSERT_FALSE( - authzSession->isAuthorizedForActionsOnResource(otherIndexesCollResource, ActionType::find)); - ASSERT_FALSE( authzSession->isAuthorizedForActionsOnResource(otherProfileCollResource, ActionType::find)); // Logging in as rw@test implicitly logs out useradminany@test. @@ -399,12 +383,8 @@ TEST_F(AuthorizationSessionTest, SystemCollectionsAccessControl) { ASSERT_FALSE( authzSession->isAuthorizedForActionsOnResource(otherUsersCollResource, ActionType::find)); ASSERT_TRUE( - authzSession->isAuthorizedForActionsOnResource(testIndexesCollResource, ActionType::find)); - ASSERT_TRUE( authzSession->isAuthorizedForActionsOnResource(testProfileCollResource, ActionType::find)); ASSERT_FALSE( - authzSession->isAuthorizedForActionsOnResource(otherIndexesCollResource, ActionType::find)); - ASSERT_FALSE( authzSession->isAuthorizedForActionsOnResource(otherProfileCollResource, ActionType::find)); @@ -419,12 +399,8 @@ TEST_F(AuthorizationSessionTest, SystemCollectionsAccessControl) { ASSERT_FALSE( authzSession->isAuthorizedForActionsOnResource(otherUsersCollResource, ActionType::find)); ASSERT_FALSE( - authzSession->isAuthorizedForActionsOnResource(testIndexesCollResource, ActionType::find)); - ASSERT_FALSE( authzSession->isAuthorizedForActionsOnResource(testProfileCollResource, ActionType::find)); ASSERT_FALSE( - authzSession->isAuthorizedForActionsOnResource(otherIndexesCollResource, ActionType::find)); - ASSERT_FALSE( authzSession->isAuthorizedForActionsOnResource(otherProfileCollResource, ActionType::find)); } @@ -1252,19 +1228,6 @@ TEST_F(AuthorizationSessionTest, CannotListCollectionsWithoutListCollectionsPriv ASSERT_FALSE(authzSession->isAuthorizedToListCollections(testQuxNss.db(), cmd)); } -TEST_F(AuthorizationSessionTest, CanListCollectionsWithLegacySystemNamespacesAccess) { - BSONObj cmd = BSON("listCollections" << 1); - - // Deprecated: permissions for the find action on test.system.namespaces allows us to list - // collections in the test database. - authzSession->assumePrivilegesForDB( - Privilege(testSystemNamespacesResource, {ActionType::find})); - - ASSERT_TRUE(authzSession->isAuthorizedToListCollections(testFooNss.db(), cmd)); - ASSERT_TRUE(authzSession->isAuthorizedToListCollections(testBarNss.db(), cmd)); - ASSERT_TRUE(authzSession->isAuthorizedToListCollections(testQuxNss.db(), cmd)); -} - TEST_F(AuthorizationSessionTest, CanListCollectionsWithListCollectionsPrivilege) { BSONObj cmd = BSON("listCollections" << 1); // The listCollections privilege authorizes the list collections command. diff --git a/src/mongo/db/auth/role_graph_builtin_roles.cpp b/src/mongo/db/auth/role_graph_builtin_roles.cpp index 8f096ac641d..d9875a20f96 100644 --- a/src/mongo/db/auth/role_graph_builtin_roles.cpp +++ b/src/mongo/db/auth/role_graph_builtin_roles.cpp @@ -261,16 +261,8 @@ void addReadOnlyDbPrivileges(PrivilegeVector* privileges, StringData dbName) { privileges, Privilege(ResourcePattern::forDatabaseName(dbName), readRoleActions)); Privilege::addPrivilegeToPrivilegeVector( privileges, - Privilege(ResourcePattern::forExactNamespace(NamespaceString(dbName, "system.indexes")), - readRoleActions)); - Privilege::addPrivilegeToPrivilegeVector( - privileges, Privilege(ResourcePattern::forExactNamespace(NamespaceString(dbName, "system.js")), readRoleActions)); - Privilege::addPrivilegeToPrivilegeVector( - privileges, - Privilege(ResourcePattern::forExactNamespace(NamespaceString(dbName, "system.namespaces")), - readRoleActions)); } void addReadWriteDbPrivileges(PrivilegeVector* privileges, StringData dbName) { @@ -291,14 +283,6 @@ void addUserAdminDbPrivileges(PrivilegeVector* privileges, StringData dbName) { void addDbAdminDbPrivileges(PrivilegeVector* privileges, StringData dbName) { Privilege::addPrivilegeToPrivilegeVector( privileges, Privilege(ResourcePattern::forDatabaseName(dbName), dbAdminRoleActions)); - Privilege::addPrivilegeToPrivilegeVector( - privileges, - Privilege(ResourcePattern::forExactNamespace(NamespaceString(dbName, "system.indexes")), - readRoleActions)); - Privilege::addPrivilegeToPrivilegeVector( - privileges, - Privilege(ResourcePattern::forExactNamespace(NamespaceString(dbName, "system.namespaces")), - readRoleActions)); ActionSet profileActions = readRoleActions; profileActions.addAction(ActionType::convertToCapped); @@ -329,13 +313,7 @@ void addReadOnlyAnyDbPrivileges(PrivilegeVector* privileges) { Privilege::addPrivilegeToPrivilegeVector( privileges, Privilege(ResourcePattern::forClusterResource(), ActionType::listDatabases)); Privilege::addPrivilegeToPrivilegeVector( - privileges, - Privilege(ResourcePattern::forCollectionName("system.indexes"), readRoleActions)); - Privilege::addPrivilegeToPrivilegeVector( privileges, Privilege(ResourcePattern::forCollectionName("system.js"), readRoleActions)); - Privilege::addPrivilegeToPrivilegeVector( - privileges, - Privilege(ResourcePattern::forCollectionName("system.namespaces"), readRoleActions)); } void addReadWriteAnyDbPrivileges(PrivilegeVector* privileges) { @@ -402,12 +380,6 @@ void addDbAdminAnyDbPrivileges(PrivilegeVector* privileges) { privileges, Privilege(ResourcePattern::forClusterResource(), ActionType::listDatabases)); Privilege::addPrivilegeToPrivilegeVector( privileges, Privilege(ResourcePattern::forAnyNormalResource(), dbAdminRoleActions)); - Privilege::addPrivilegeToPrivilegeVector( - privileges, - Privilege(ResourcePattern::forCollectionName("system.indexes"), readRoleActions)); - Privilege::addPrivilegeToPrivilegeVector( - privileges, - Privilege(ResourcePattern::forCollectionName("system.namespaces"), readRoleActions)); ActionSet profileActions = readRoleActions; profileActions.addAction(ActionType::convertToCapped); profileActions.addAction(ActionType::createCollection); @@ -509,14 +481,6 @@ void addQueryableBackupPrivileges(PrivilegeVector* privileges) { privileges, Privilege(ResourcePattern::forDatabaseName("local"), ActionType::find)); Privilege::addPrivilegeToPrivilegeVector( - privileges, - Privilege(ResourcePattern::forCollectionName("system.indexes"), ActionType::find)); - - Privilege::addPrivilegeToPrivilegeVector( - privileges, - Privilege(ResourcePattern::forCollectionName("system.namespaces"), ActionType::find)); - - Privilege::addPrivilegeToPrivilegeVector( privileges, Privilege(ResourcePattern::forCollectionName("system.js"), ActionType::find)); Privilege::addPrivilegeToPrivilegeVector( @@ -585,10 +549,6 @@ void addRestorePrivileges(PrivilegeVector* privileges) { Privilege::addPrivilegeToPrivilegeVector( privileges, Privilege(ResourcePattern::forCollectionName("system.js"), actions)); - // Need to be able to query system.namespaces to check existing collection options. - Privilege::addPrivilegeToPrivilegeVector( - privileges, - Privilege(ResourcePattern::forCollectionName("system.namespaces"), ActionType::find)); Privilege::addPrivilegeToPrivilegeVector( privileges, Privilege(ResourcePattern::forAnyResource(), ActionType::listCollections)); diff --git a/src/mongo/db/catalog/database.h b/src/mongo/db/catalog/database.h index 73038f59a44..86c256d2925 100644 --- a/src/mongo/db/catalog/database.h +++ b/src/mongo/db/catalog/database.h @@ -115,8 +115,6 @@ public: StringData toNS, bool stayTemp) = 0; - virtual const NamespaceString& getSystemIndexesName() const = 0; - virtual const std::string& getSystemViewsName() const = 0; virtual StatusWith<NamespaceString> makeUniqueCollectionNamespace( @@ -353,10 +351,6 @@ public: */ static MONGO_DECLARE_SHIM((OperationContext * opCtx, Database* db)->void) dropDatabase; - inline const NamespaceString& getSystemIndexesName() const { - return this->_impl().getSystemIndexesName(); - } - inline const std::string& getSystemViewsName() const { return this->_impl().getSystemViewsName(); } diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp index 47033e7dcfa..3f68c72fe8c 100644 --- a/src/mongo/db/catalog/database_impl.cpp +++ b/src/mongo/db/catalog/database_impl.cpp @@ -248,7 +248,6 @@ DatabaseImpl::DatabaseImpl(Database* const this_, : _name(name.toString()), _dbEntry(dbEntry), _profileName(_name + ".system.profile"), - _indexesName(_name + ".system.indexes"), _viewsName(_name + "." + DurableViewCatalog::viewsCollectionName().toString()), _durableViews(DurableViewCatalogImpl(this_)), _views(&_durableViews), diff --git a/src/mongo/db/catalog/database_impl.h b/src/mongo/db/catalog/database_impl.h index 8a341037778..77d8505d3d2 100644 --- a/src/mongo/db/catalog/database_impl.h +++ b/src/mongo/db/catalog/database_impl.h @@ -216,10 +216,6 @@ public: static Status validateDBName(StringData dbname); - const NamespaceString& getSystemIndexesName() const final { - return _indexesName; - } - const std::string& getSystemViewsName() const final { return _viewsName; } @@ -279,9 +275,8 @@ private: DatabaseCatalogEntry* _dbEntry; // not owned here - const std::string _profileName; // "dbname.system.profile" - const NamespaceString _indexesName; // "dbname.system.indexes" - const std::string _viewsName; // "dbname.system.views" + const std::string _profileName; // "dbname.system.profile" + const std::string _viewsName; // "dbname.system.views" int _profile; // 0=off. diff --git a/src/mongo/db/catalog/drop_database.cpp b/src/mongo/db/catalog/drop_database.cpp index 58ae3624a62..fa80f77808a 100644 --- a/src/mongo/db/catalog/drop_database.cpp +++ b/src/mongo/db/catalog/drop_database.cpp @@ -145,7 +145,7 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) { latestDropPendingOpTime, uassertStatusOK(nss.getDropPendingNamespaceOpTime())); continue; } - if (replCoord->isOplogDisabledFor(opCtx, nss) || nss.isSystemDotIndexes()) { + if (replCoord->isOplogDisabledFor(opCtx, nss)) { continue; } collectionsToDrop.push_back(nss); diff --git a/src/mongo/db/catalog/drop_database_test.cpp b/src/mongo/db/catalog/drop_database_test.cpp index db8de66f22c..9cf3c7eefa7 100644 --- a/src/mongo/db/catalog/drop_database_test.cpp +++ b/src/mongo/db/catalog/drop_database_test.cpp @@ -285,16 +285,6 @@ TEST_F(DropDatabaseTest, DropDatabasePassedThroughAwaitReplicationErrorForDropPe ASSERT_EQUALS(ErrorCodes::WriteConcernFailed, dropDatabase(_opCtx.get(), _nss.db().toString())); } -TEST_F(DropDatabaseTest, DropDatabaseSkipsSystemDotIndexesCollectionWhenDroppingCollections) { - NamespaceString systemDotIndexesNss(_nss.getSystemIndexesCollection()); - _testDropDatabase(_opCtx.get(), _opObserver, systemDotIndexesNss, false); -} - -TEST_F(DropDatabaseTest, DropDatabaseSkipsSystemNamespacesCollectionWhenDroppingCollections) { - NamespaceString systemNamespacesNss(_nss.getSisterNS("system.namespaces")); - _testDropDatabase(_opCtx.get(), _opObserver, systemNamespacesNss, false); -} - TEST_F(DropDatabaseTest, DropDatabaseSkipsSystemProfileCollectionWhenDroppingCollections) { repl::OpTime dropOpTime(Timestamp(Seconds(100), 0), 1LL); NamespaceString profileNss(_nss.getSisterNS("system.profile")); diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp index af033c58f91..f6f9eea188c 100644 --- a/src/mongo/db/catalog/index_catalog_impl.cpp +++ b/src/mongo/db/catalog/index_catalog_impl.cpp @@ -503,10 +503,6 @@ Status IndexCatalogImpl::_isSpecOk(OperationContext* opCtx, const BSONObj& spec) << static_cast<int>(indexVersion)); } - if (nss.isSystemDotIndexes()) - return Status(ErrorCodes::CannotCreateIndex, - "cannot have an index on the system.indexes collection"); - if (nss.isOplog()) return Status(ErrorCodes::CannotCreateIndex, "cannot have an index on the oplog"); @@ -963,13 +959,6 @@ private: } // namespace Status IndexCatalogImpl::_dropIndex(OperationContext* opCtx, IndexCatalogEntry* entry) { - /** - * IndexState in order - * <db>.system.indexes - * NamespaceDetails - * <db>.system.ns - */ - // ----- SANITY CHECKS ------------- if (!entry) return Status(ErrorCodes::BadValue, "IndexCatalog::_dropIndex passed NULL"); diff --git a/src/mongo/db/catalog/index_catalog_impl.h b/src/mongo/db/catalog/index_catalog_impl.h index ef42f1b8cfc..f6b83145304 100644 --- a/src/mongo/db/catalog/index_catalog_impl.h +++ b/src/mongo/db/catalog/index_catalog_impl.h @@ -269,12 +269,10 @@ public: /** * disk creation order - * 1) system.indexes entry - * 2) collection's NamespaceDetails + * 1) collection's NamespaceDetails * a) info + head * b) _indexBuildsInProgress++ - * 3) indexes entry in .ns file - * 4) system.namespaces entry for index ns + * 2) indexes entry in .ns file */ class IndexBuildBlock { MONGO_DISALLOW_COPYING(IndexBuildBlock); diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp index 98c0e5ce7d0..e42aabc4f7b 100644 --- a/src/mongo/db/cloner.cpp +++ b/src/mongo/db/cloner.cpp @@ -139,8 +139,6 @@ struct Cloner::Fun { : lastLog(0), opCtx(opCtx), _dbName(dbName) {} void operator()(DBClientCursorBatchIterator& i) { - invariant(from_collection.coll() != "system.indexes"); - // XXX: can probably take dblock instead unique_ptr<Lock::GlobalWrite> globalWriteLock(new Lock::GlobalWrite(opCtx)); uassert( diff --git a/src/mongo/db/commands/clone_collection.cpp b/src/mongo/db/commands/clone_collection.cpp index af8d26eb518..2a3da6149d7 100644 --- a/src/mongo/db/commands/clone_collection.cpp +++ b/src/mongo/db/commands/clone_collection.cpp @@ -128,9 +128,8 @@ public: // In order to clone a namespace, a user must be allowed to both create and write to that // namespace. There exist namespaces that are legal to create but not write to (e.g. - // system.profile), and there exist namespaces that are legal to write to but not create - // (e.g. system.indexes), so we must check that it is legal to both create and write to the - // namespace. + // system.profile), and there exist namespaces that are legal to write to but not create, + // so we must check that it is legal to both create and write to the namespace. auto allowedCreateStatus = userAllowedCreateNS(dbname, nsToCollectionSubstring(ns)); uassertStatusOK(allowedCreateStatus); auto allowedWriteStatus = userAllowedWriteNS(dbname, nsToCollectionSubstring(ns)); diff --git a/src/mongo/db/commands/compact.cpp b/src/mongo/db/commands/compact.cpp index bffe66dd8c0..bfb9c33fd60 100644 --- a/src/mongo/db/commands/compact.cpp +++ b/src/mongo/db/commands/compact.cpp @@ -107,8 +107,7 @@ public: } if (nss.isSystem()) { - // items in system.* cannot be moved as there might be pointers to them - // i.e. system.indexes entries are pointed to from NamespaceDetails + // Items in system.* cannot be moved as there might be pointers to them. errmsg = "can't compact a system namespace"; return false; } diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp index 509bdc1d201..bdd3b2731d9 100644 --- a/src/mongo/db/commands/list_collections.cpp +++ b/src/mongo/db/commands/list_collections.cpp @@ -112,7 +112,7 @@ boost::optional<vector<StringData>> _getExactNameMatches(const MatchExpression* * Uses 'matcher' to determine if the collection's information should be added to 'root'. If so, * allocates a WorkingSetMember containing information about 'collection', and adds it to 'root'. * - * Does not add any information about the system.namespaces collection, or non-existent collections. + * Does not add any information about non-existent collections. */ void _addWorkingSetMember(OperationContext* opCtx, const BSONObj& maybe, @@ -161,16 +161,11 @@ BSONObj buildCollectionBson(OperationContext* opCtx, const Collection* collection, bool includePendingDrops, bool nameOnly) { - if (!collection) { return {}; } - auto nss = collection->ns(); auto collectionName = nss.coll(); - if (collectionName == "system.namespaces") { - return {}; - } // Drop-pending collections are replicated collections that have been marked for deletion. // These collections are considered dropped and should not be returned in the results for this diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp index 9402e24bd17..e49a65124c2 100644 --- a/src/mongo/db/commands/list_indexes.cpp +++ b/src/mongo/db/commands/list_indexes.cpp @@ -99,15 +99,11 @@ public: return Status(ErrorCodes::Unauthorized, "Unauthorized"); } - // Check for the listIndexes ActionType on the database, or find on system.indexes for pre - // 3.0 systems. + // Check for the listIndexes ActionType on the database. const auto nss = AutoGetCollection::resolveNamespaceStringOrUUID( opCtx, CommandHelpers::parseNsOrUUID(dbname, cmdObj)); if (authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forExactNamespace(nss), - ActionType::listIndexes) || - authzSession->isAuthorizedForActionsOnResource( - ResourcePattern::forExactNamespace(NamespaceString(dbname, "system.indexes")), - ActionType::find)) { + ActionType::listIndexes)) { return Status::OK(); } diff --git a/src/mongo/db/commands/oplog_application_checks.cpp b/src/mongo/db/commands/oplog_application_checks.cpp index 1a001805f55..873492f5243 100644 --- a/src/mongo/db/commands/oplog_application_checks.cpp +++ b/src/mongo/db/commands/oplog_application_checks.cpp @@ -103,7 +103,7 @@ Status OplogApplicationChecks::checkOperationAuthorization(OperationContext* opC } if (opType == "i"_sd) { - return authSession->checkAuthForInsert(opCtx, ns, o); + return authSession->checkAuthForInsert(opCtx, ns); } else if (opType == "u"_sd) { BSONElement o2Elem = oplogEntry["o2"]; checkBSONType(BSONType::Object, o2Elem); diff --git a/src/mongo/db/commands/rename_collection_cmd.cpp b/src/mongo/db/commands/rename_collection_cmd.cpp index 36c8aa4105b..c286ef21e1d 100644 --- a/src/mongo/db/commands/rename_collection_cmd.cpp +++ b/src/mongo/db/commands/rename_collection_cmd.cpp @@ -143,11 +143,6 @@ public: return false; } - if (source.isSystemDotIndexes() || target.isSystemDotIndexes()) { - errmsg = "renaming system.indexes is not allowed"; - return false; - } - if (source.isServerConfigurationCollection()) { uasserted(ErrorCodes::IllegalOperation, "renaming the server configuration " diff --git a/src/mongo/db/commands/write_commands/write_commands_common.cpp b/src/mongo/db/commands/write_commands/write_commands_common.cpp index 49f72b919fd..3ba6338cd0d 100644 --- a/src/mongo/db/commands/write_commands/write_commands_common.cpp +++ b/src/mongo/db/commands/write_commands/write_commands_common.cpp @@ -65,13 +65,6 @@ NamespaceString _getIndexedNss(const std::vector<BSONObj>& documents) { void fillPrivileges(const write_ops::Insert& op, std::vector<Privilege>* privileges, ActionSet* actions) { - if (op.getNamespace().isSystemDotIndexes()) { - // Special-case indexes until we have a command - privileges->push_back( - Privilege(ResourcePattern::forExactNamespace(_getIndexedNss(op.getDocuments())), - ActionType::createIndex)); - return; - } actions->addAction(ActionType::insert); } diff --git a/src/mongo/db/fts/fts_spec.cpp b/src/mongo/db/fts/fts_spec.cpp index 9022b72bb0b..5225e46106d 100644 --- a/src/mongo/db/fts/fts_spec.cpp +++ b/src/mongo/db/fts/fts_spec.cpp @@ -66,10 +66,9 @@ bool validateOverride(const string& override) { } FTSSpec::FTSSpec(const BSONObj& indexInfo) { - // indexInfo is a text index spec. Text index specs pass through fixSpec() before - // being saved to the system.indexes collection. fixSpec() enforces a schema, such that - // required fields must exist and be of the correct type (e.g. weights, - // textIndexVersion). + // indexInfo is a text index spec. Text index specs pass through fixSpec() before being + // persisted. fixSpec() enforces a schema, such that required fields must exist and be of the + // correct type (e.g. weights, textIndexVersion). massert(16739, "found invalid spec for text index", indexInfo["weights"].isABSONObj()); BSONElement textIndexVersionElt = indexInfo["textIndexVersion"]; massert(17367, diff --git a/src/mongo/db/index_builder.cpp b/src/mongo/db/index_builder.cpp index e70494335ff..778bd77df4d 100644 --- a/src/mongo/db/index_builder.cpp +++ b/src/mongo/db/index_builder.cpp @@ -134,8 +134,6 @@ void IndexBuilder::run() { NamespaceString ns(_index["ns"].String()); Lock::DBLock dlk(opCtx.get(), ns.db(), MODE_X); - OldClientContext ctx(opCtx.get(), ns.getSystemIndexesCollection()); - Database* db = DatabaseHolder::getDatabaseHolder().get(opCtx.get(), ns.db().toString()); Status status = _build(opCtx.get(), db, true, &dlk); diff --git a/src/mongo/db/index_builder.h b/src/mongo/db/index_builder.h index 1499b8cb816..835cca474a9 100644 --- a/src/mongo/db/index_builder.h +++ b/src/mongo/db/index_builder.h @@ -58,8 +58,7 @@ class OperationContext; * parent thread, waitForBgIndexStarting() must be called by the same parent thread, * before any other thread calls go() on any other IndexBuilder instance. This is * ensured by the replication system, since commands are effectively run single-threaded - * by the replication applier, and index builds are treated as commands even though they look - * like inserts on system.indexes. + * by the replication applier. * The argument "relaxConstraints" specifies whether we should honor or ignore index constraints, * The ignoring of constraints is for replication due to idempotency reasons. * The argument "initIndexTs" specifies the timestamp to be used to make the initial catalog write. diff --git a/src/mongo/db/index_rebuilder.cpp b/src/mongo/db/index_rebuilder.cpp index 376d05e5e74..cec89996944 100644 --- a/src/mongo/db/index_rebuilder.cpp +++ b/src/mongo/db/index_rebuilder.cpp @@ -86,13 +86,12 @@ void checkNS(OperationContext* opCtx, const std::list<std::string>& nsToCheck) { WriteUnitOfWork wunit(opCtx); vector<BSONObj> indexesToBuild = indexCatalog->getAndClearUnfinishedIndexes(opCtx); - // The indexes have now been removed from system.indexes, so the only record is - // in-memory. If there is a journal commit between now and when insert() rewrites - // the entry and the db crashes before the new system.indexes entry is journalled, - // the index will be lost forever. Thus, we must stay in the same WriteUnitOfWork - // to ensure that no journaling will happen between now and the entry being - // re-written in MultiIndexBlock::init(). The actual index building is done outside - // of this WUOW. + // The indexes have now been removed from persisted memory, so the only record is + // in-memory. If there is a journal commit between now and when 'indexer.init' rewrites + // the entry and the db crashes before the new persisted index state is journalled, the + // index will be lost forever. Thus, we must stay in the same WriteUnitOfWork to ensure + // that no journaling will happen between now and the entry being re-written in + // MultiIndexBlock::init(). The actual index building is done outside of this WUOW. if (indexesToBuild.empty()) { continue; diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h index f6ef0ce8ca6..86459120bfe 100644 --- a/src/mongo/db/namespace_string.h +++ b/src/mongo/db/namespace_string.h @@ -228,9 +228,6 @@ public: bool isLocal() const { return db() == kLocalDb; } - bool isSystemDotIndexes() const { - return coll() == "system.indexes"; - } bool isSystemDotProfile() const { return coll() == "system.profile"; } @@ -354,10 +351,6 @@ public: */ std::string getSisterNS(StringData local) const; - std::string getSystemIndexesCollection() const { - return db().toString() + ".system.indexes"; - } - NamespaceString getCommandNS() const { return {db(), "$cmd"}; } @@ -426,7 +419,7 @@ public: * samples: * good: * foo - * system.indexes + * system.views * bad: * $foo * @param coll - a collection name component of a namespace diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp index 4fa45882eec..a15226186b6 100644 --- a/src/mongo/db/op_observer_impl.cpp +++ b/src/mongo/db/op_observer_impl.cpp @@ -325,48 +325,30 @@ void OpObserverImpl::onCreateIndex(OperationContext* opCtx, OptionalCollectionUUID uuid, BSONObj indexDoc, bool fromMigrate) { - const NamespaceString systemIndexes{nss.getSystemIndexesCollection()}; + // TODO: uuid should no longer be optional (SERVER-36472). + invariant(uuid); - if (uuid) { - BSONObjBuilder builder; - builder.append("createIndexes", nss.coll()); - - for (const auto& e : indexDoc) { - if (e.fieldNameStringData() != "ns"_sd) - builder.append(e); - } + BSONObjBuilder builder; + builder.append("createIndexes", nss.coll()); - logOperation(opCtx, - "c", - nss.getCommandNS(), - uuid, - builder.done(), - nullptr, - fromMigrate, - getWallClockTimeForOpLog(opCtx), - {}, - kUninitializedStmtId, - {}, - false /* prepare */, - OplogSlot()); - } else { - logOperation(opCtx, - "i", - systemIndexes, - {}, - indexDoc, - nullptr, - fromMigrate, - getWallClockTimeForOpLog(opCtx), - {}, - kUninitializedStmtId, - {}, - false /* prepare */, - OplogSlot()); + for (const auto& e : indexDoc) { + if (e.fieldNameStringData() != "ns"_sd) + builder.append(e); } - AuthorizationManager::get(opCtx->getServiceContext()) - ->logOp(opCtx, "i", systemIndexes, indexDoc, nullptr); + logOperation(opCtx, + "c", + nss.getCommandNS(), + uuid, + builder.done(), + nullptr, + fromMigrate, + getWallClockTimeForOpLog(opCtx), + {}, + kUninitializedStmtId, + {}, + false /* prepare */, + OplogSlot()); } void OpObserverImpl::onInserts(OperationContext* opCtx, diff --git a/src/mongo/db/ops/insert.cpp b/src/mongo/db/ops/insert.cpp index af50aca6415..8ab64d1dcd9 100644 --- a/src/mongo/db/ops/insert.cpp +++ b/src/mongo/db/ops/insert.cpp @@ -189,9 +189,6 @@ Status userAllowedWriteNS(StringData db, StringData coll) { return Status(ErrorCodes::InvalidNamespace, str::stream() << "cannot write to '" << db << ".system.profile'"); } - if (coll == "system.indexes") { - return Status::OK(); - } return userAllowedCreateNS(db, coll); } @@ -223,7 +220,6 @@ Status userAllowedCreateNS(StringData db, StringData coll) { if (db == "system") return Status(ErrorCodes::InvalidNamespace, "cannot use 'system' database"); - if (coll.startsWith("system.")) { if (coll == "system.js") return Status::OK(); diff --git a/src/mongo/db/ops/write_ops.h b/src/mongo/db/ops/write_ops.h index c3201f7f56f..081e23876b6 100644 --- a/src/mongo/db/ops/write_ops.h +++ b/src/mongo/db/ops/write_ops.h @@ -71,12 +71,6 @@ int32_t getStmtIdForWriteAt(const T& op, size_t writePos) { return getStmtIdForWriteAt(op.getWriteCommandBase(), writePos); } -/** - * Must only be called if the insert is for the "system.indexes" namespace. Returns the actual - * namespace for which the index is being created. - */ -NamespaceString extractIndexedNamespace(const Insert& insertOp); - // TODO: Delete this getter once IDL supports defaults for object and array fields template <class T> const BSONObj& collationOf(const T& opEntry) { diff --git a/src/mongo/db/ops/write_ops_document_stream_integration_test.cpp b/src/mongo/db/ops/write_ops_document_stream_integration_test.cpp index 51cbf103722..cb0c92c0536 100644 --- a/src/mongo/db/ops/write_ops_document_stream_integration_test.cpp +++ b/src/mongo/db/ops/write_ops_document_stream_integration_test.cpp @@ -66,39 +66,4 @@ TEST(WriteOpsDocSeq, InsertDocStreamWorks) { ASSERT_EQ(conn->count(ns.ns()), 5u); } -TEST(WriteOpsDocSeq, InsertDocStreamWorksWithSystemDotIndexes) { - std::string errMsg; - auto conn = std::unique_ptr<DBClientBase>( - unittest::getFixtureConnectionString().connect("integration_test", errMsg)); - uassert(ErrorCodes::SocketException, errMsg, conn); - - NamespaceString ns("test", "doc_seq"); - conn->dropCollection(ns.ns()); - ASSERT_EQ(conn->count(ns.ns()), 0u); - - OpMsgRequest request; - request.body = BSON("insert" - << "system.indexes" - << "$db" - << ns.db()); - request.sequences = {{"documents", - { - BSON("ns" << ns.ns() << "key" << BSON("x" << 1) << "name" - << "my_special_index"), - }}}; - - const auto reply = conn->runCommand(std::move(request)); - ASSERT_EQ(int(reply->getProtocol()), int(rpc::Protocol::kOpMsg)); - auto body = reply->getCommandReply(); - ASSERT_OK(getStatusFromCommandResult(body)); - ASSERT_EQ(body["n"].Int(), 1); - - auto indexes = conn->getIndexSpecs(ns.ns()); - ASSERT_EQ(indexes.size(), 2u); // my_special_index + _id - - indexes.sort([](auto&& l, auto&& r) { return l["name"].String() < r["name"].String(); }); - ASSERT_EQ(indexes.front()["name"].String(), "_id_"); - ASSERT_EQ(indexes.back()["name"].String(), "my_special_index"); -} - } // namespace mongo diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp index 6e46309190b..d9dc53085b4 100644 --- a/src/mongo/db/ops/write_ops_exec.cpp +++ b/src/mongo/db/ops/write_ops_exec.cpp @@ -293,32 +293,6 @@ SingleWriteResult createIndex(OperationContext* opCtx, return result; } -WriteResult performCreateIndexes(OperationContext* opCtx, const write_ops::Insert& wholeOp) { - // Currently this creates each index independently. We could pass multiple indexes to - // createIndexes, but there is a lot of complexity involved in doing it correctly. For one - // thing, createIndexes only takes indexes to a single collection, but this batch could include - // different collections. Additionally, the error handling is different: createIndexes is - // all-or-nothing while inserts are supposed to behave like a sequence that either skips over - // errors or stops at the first one. These could theoretically be worked around, but it doesn't - // seem worth it since users that want faster index builds should just use the createIndexes - // command rather than a legacy emulation. - LastOpFixer lastOpFixer(opCtx, wholeOp.getNamespace()); - WriteResult out; - for (auto&& spec : wholeOp.getDocuments()) { - try { - lastOpFixer.startingOp(); - out.results.emplace_back(createIndex(opCtx, wholeOp.getNamespace(), spec)); - lastOpFixer.finishedOpSuccessfully(); - } catch (const DBException& ex) { - const bool canContinue = - handleError(opCtx, ex, wholeOp.getNamespace(), wholeOp.getWriteCommandBase(), &out); - if (!canContinue) - break; - } - } - return out; -} - void insertDocuments(OperationContext* opCtx, Collection* collection, std::vector<InsertStatement>::iterator begin, @@ -511,10 +485,6 @@ WriteResult performInserts(OperationContext* opCtx, uassertStatusOK(userAllowedWriteNS(wholeOp.getNamespace())); - if (wholeOp.getNamespace().isSystemDotIndexes()) { - return performCreateIndexes(opCtx, wholeOp); - } - DisableDocumentValidationIfTrue docValidationDisabler( opCtx, wholeOp.getWriteCommandBase().getBypassDocumentValidation()); LastOpFixer lastOpFixer(opCtx, wholeOp.getNamespace()); diff --git a/src/mongo/db/ops/write_ops_parsers.cpp b/src/mongo/db/ops/write_ops_parsers.cpp index ee98d43d17f..7abb058dd32 100644 --- a/src/mongo/db/ops/write_ops_parsers.cpp +++ b/src/mongo/db/ops/write_ops_parsers.cpp @@ -65,26 +65,7 @@ void checkOpCountForCommand(const T& op, size_t numOps) { } void validateInsertOp(const write_ops::Insert& insertOp) { - const auto& nss = insertOp.getNamespace(); const auto& docs = insertOp.getDocuments(); - - if (nss.isSystemDotIndexes()) { - // This is only for consistency with sharding. - uassert(ErrorCodes::InvalidLength, - "Insert commands to system.indexes are limited to a single insert", - docs.size() == 1); - - const auto indexedNss(extractIndexedNamespace(insertOp)); - - uassert(ErrorCodes::InvalidNamespace, - str::stream() << indexedNss.ns() << " is not a valid namespace to index", - indexedNss.isValid()); - - uassert(ErrorCodes::IllegalOperation, - str::stream() << indexedNss.ns() << " is not in the target database " << nss.db(), - nss.db().compare(indexedNss.db()) == 0); - } - checkOpCountForCommand(insertOp, docs.size()); } @@ -119,15 +100,6 @@ int32_t getStmtIdForWriteAt(const WriteCommandBase& writeCommandBase, size_t wri return kFirstStmtId + writePos; } -NamespaceString extractIndexedNamespace(const Insert& insertOp) { - invariant(insertOp.getNamespace().isSystemDotIndexes()); - - const auto& documents = insertOp.getDocuments(); - invariant(documents.size() == 1); - - return NamespaceString(documents.at(0)["ns"].str()); -} - } // namespace write_ops write_ops::Insert InsertOp::parse(const OpMsgRequest& request) { diff --git a/src/mongo/db/pipeline/document_source_change_stream_test.cpp b/src/mongo/db/pipeline/document_source_change_stream_test.cpp index f5897bd30af..c8a703726cb 100644 --- a/src/mongo/db/pipeline/document_source_change_stream_test.cpp +++ b/src/mongo/db/pipeline/document_source_change_stream_test.cpp @@ -983,34 +983,6 @@ TEST_F(ChangeStreamStageTest, MatchFiltersNoOp) { checkTransformation(noOp, boost::none); } -TEST_F(ChangeStreamStageTest, MatchFiltersCreateIndex) { - auto indexSpec = D{{"v", 2}, {"key", D{{"a", 1}}}, {"name", "a_1"_sd}, {"ns", nss.ns()}}; - NamespaceString indexNs(nss.getSystemIndexesCollection()); - bool fromMigrate = false; // At the moment this makes no difference. - auto createIndex = makeOplogEntry(OpTypeEnum::kInsert, // op type - indexNs, // namespace - indexSpec.toBson(), // o - boost::none, // uuid - fromMigrate, // fromMigrate - boost::none); // o2 - - checkTransformation(createIndex, boost::none); -} - -TEST_F(ChangeStreamStageTest, MatchFiltersCreateIndexFromMigrate) { - auto indexSpec = D{{"v", 2}, {"key", D{{"a", 1}}}, {"name", "a_1"_sd}, {"ns", nss.ns()}}; - NamespaceString indexNs(nss.getSystemIndexesCollection()); - bool fromMigrate = true; - auto createIndex = makeOplogEntry(OpTypeEnum::kInsert, // op type - indexNs, // namespace - indexSpec.toBson(), // o - boost::none, // uuid - fromMigrate, // fromMigrate - boost::none); // o2 - - checkTransformation(createIndex, boost::none); -} - TEST_F(ChangeStreamStageTest, TransformationShouldBeAbleToReParseSerializedStage) { auto expCtx = getExpCtx(); @@ -1559,13 +1531,6 @@ TEST_F(ChangeStreamStageDBTest, MatchFiltersNoOp) { checkTransformation(noOp, boost::none); } -TEST_F(ChangeStreamStageDBTest, MatchFiltersCreateIndex) { - auto indexSpec = D{{"v", 2}, {"key", D{{"a", 1}}}, {"name", "a_1"_sd}, {"ns", nss.ns()}}; - NamespaceString indexNs(nss.getSystemIndexesCollection()); - OplogEntry createIndex = makeOplogEntry(OpTypeEnum::kInsert, indexNs, indexSpec.toBson()); - checkTransformation(createIndex, boost::none); -} - TEST_F(ChangeStreamStageDBTest, DocumentKeyShouldIncludeShardKeyFromResumeToken) { const Timestamp ts(3, 45); const long long term = 4; diff --git a/src/mongo/db/repair_database_and_check_version.cpp b/src/mongo/db/repair_database_and_check_version.cpp index eb8a48c2cad..567b551c488 100644 --- a/src/mongo/db/repair_database_and_check_version.cpp +++ b/src/mongo/db/repair_database_and_check_version.cpp @@ -146,33 +146,6 @@ Status ensureAllCollectionsHaveUUIDs(OperationContext* opCtx, invariant(db); for (auto collectionIt = db->begin(); collectionIt != db->end(); ++collectionIt) { Collection* coll = *collectionIt; - // The presence of system.indexes or system.namespaces on wiredTiger may - // have undesirable results (see SERVER-32894, SERVER-34482). It is okay to - // drop these collections on wiredTiger because users are not permitted to - // store data in them. - if (coll->ns().coll() == "system.indexes" || coll->ns().coll() == "system.namespaces") { - const auto nssToDrop = coll->ns(); - LOG(1) << "Attempting to drop invalid system collection " << nssToDrop; - if (coll->numRecords(opCtx)) { - severe(LogComponent::kControl) << "Cannot drop non-empty collection " - << nssToDrop.ns(); - exitCleanly(EXIT_NEED_DOWNGRADE); - } - repl::UnreplicatedWritesBlock uwb(opCtx); - writeConflictRetry(opCtx, "dropSystemIndexes", nssToDrop.ns(), [&] { - WriteUnitOfWork wunit(opCtx); - BSONObjBuilder unusedResult; - fassert(50837, - dropCollection( - opCtx, - nssToDrop, - unusedResult, - {}, - DropCollectionSystemCollectionMode::kAllowSystemCollectionDrops)); - wunit.commit(); - }); - continue; - } // We expect all collections to have UUIDs in MongoDB 4.2 if (!coll->uuid()) { @@ -483,29 +456,6 @@ StatusWith<bool> repairDatabasesAndCheckVersion(OperationContext* opCtx) { } } - // Major versions match, check indexes - const NamespaceString systemIndexes(db->name(), "system.indexes"); - - Collection* coll = db->getCollection(opCtx, systemIndexes); - auto exec = InternalPlanner::collectionScan( - opCtx, systemIndexes.ns(), coll, PlanExecutor::NO_YIELD); - - BSONObj index; - PlanExecutor::ExecState state; - while (PlanExecutor::ADVANCED == (state = exec->getNext(&index, NULL))) { - if (index["v"].isNumber() && index["v"].numberInt() == 0) { - log() << "WARNING: The index: " << index << " was created with the deprecated" - << " v:0 format. This format will not be supported in a future release." - << startupWarningsLog; - log() << "\t To fix this, you need to rebuild this index." - << " For instructions, see http://dochub.mongodb.org/core/rebuild-v0-indexes" - << startupWarningsLog; - } - } - - // Non-yielding collection scans from InternalPlanner will never error. - invariant(PlanExecutor::IS_EOF == state); - if (replSettings.usingReplSets()) { // We only care about _id indexes and drop-pending collections if we are in a replset. checkForIdIndexesAndDropPendingCollections(opCtx, db); diff --git a/src/mongo/db/repl/apply_ops.cpp b/src/mongo/db/repl/apply_ops.cpp index 0b4262b3e85..8f3f25b8514 100644 --- a/src/mongo/db/repl/apply_ops.cpp +++ b/src/mongo/db/repl/apply_ops.cpp @@ -70,14 +70,7 @@ MONGO_FAIL_POINT_DEFINE(applyOpsPauseBetweenOperations); */ bool _parseAreOpsCrudOnly(const BSONObj& applyOpCmd) { for (const auto& elem : applyOpCmd.firstElement().Obj()) { - const char* names[] = {"ns", "op"}; - BSONElement fields[2]; - elem.Obj().getFields(2, names, fields); - BSONElement& fieldNs = fields[0]; - BSONElement& fieldOp = fields[1]; - - const char* opType = fieldOp.valuestrsafe(); - const StringData ns = fieldNs.valuestrsafe(); + const char* opType = elem.Obj().getField("op").valuestrsafe(); // All atomic ops have an opType of length 1. if (opType[0] == '\0' || opType[1] != '\0') @@ -90,8 +83,7 @@ bool _parseAreOpsCrudOnly(const BSONObj& applyOpCmd) { case 'u': break; case 'i': - if (nsToCollectionSubstring(ns) != "system.indexes") - break; + break; // Fallthrough. default: return false; @@ -152,7 +144,7 @@ Status _applyOps(OperationContext* opCtx, // NamespaceNotFound. // Additionally for inserts, we fail early on non-existent collections. auto collection = db->getCollection(opCtx, nss); - if (!collection && !nss.isSystemDotIndexes() && (*opType == 'i' || *opType == 'u')) { + if (!collection && (*opType == 'i' || *opType == 'u')) { uasserted( ErrorCodes::AtomicityFailure, str::stream() @@ -210,7 +202,7 @@ Status _applyOps(OperationContext* opCtx, } AutoGetCollection autoColl(opCtx, nss, MODE_IX); - if (!autoColl.getCollection() && !nss.isSystemDotIndexes()) { + if (!autoColl.getCollection()) { // For idempotency reasons, return success on delete operations. if (*opType == 'd') { return Status::OK(); @@ -226,54 +218,12 @@ Status _applyOps(OperationContext* opCtx, OldClientContext ctx(opCtx, nss.ns()); - if (!nss.isSystemDotIndexes()) { - // We return the status rather than merely aborting so failure of CRUD - // ops doesn't stop the applyOps from trying to process the rest of the - // ops. This is to leave the door open to parallelizing CRUD op - // application in the future. - return repl::applyOperation_inlock( - opCtx, ctx.db(), opObj, alwaysUpsert, oplogApplicationMode); - } - - auto fieldO = opObj["o"]; - BSONObj indexSpec; - NamespaceString indexNss; - std::tie(indexSpec, indexNss) = - repl::prepForApplyOpsIndexInsert(fieldO, opObj, nss); - if (!indexSpec["collation"]) { - // If the index spec does not include a collation, explicitly specify - // the simple collation, so the index does not inherit the collection - // default collation. - auto indexVersion = indexSpec["v"]; - // The index version is populated by prepForApplyOpsIndexInsert(). - invariant(indexVersion); - if (indexVersion.isNumber() && - (indexVersion.numberInt() >= - static_cast<int>(IndexDescriptor::IndexVersion::kV2))) { - BSONObjBuilder bob; - bob.append("collation", CollationSpec::kSimpleSpec); - bob.appendElements(indexSpec); - indexSpec = bob.obj(); - } - } - BSONObjBuilder command; - command.append("createIndexes", indexNss.coll()); - { - BSONArrayBuilder indexes(command.subarrayStart("indexes")); - indexes.append(indexSpec); - indexes.doneFast(); - } - const BSONObj commandObj = command.done(); - - DBDirectClient client(opCtx); - BSONObj infoObj; - client.runCommand(nss.db().toString(), commandObj, infoObj); - - // Uassert to stop applyOps only when building indexes, but not for CRUD - // ops. - uassertStatusOK(getStatusFromCommandResult(infoObj)); - - return Status::OK(); + // We return the status rather than merely aborting so failure of CRUD + // ops doesn't stop the applyOps from trying to process the rest of the + // ops. This is to leave the door open to parallelizing CRUD op + // application in the future. + return repl::applyOperation_inlock( + opCtx, ctx.db(), opObj, alwaysUpsert, oplogApplicationMode); }); } catch (const DBException& ex) { ab.append(false); diff --git a/src/mongo/db/repl/do_txn.cpp b/src/mongo/db/repl/do_txn.cpp index 62537c8c8b8..b7e91fdd030 100644 --- a/src/mongo/db/repl/do_txn.cpp +++ b/src/mongo/db/repl/do_txn.cpp @@ -70,14 +70,7 @@ MONGO_FAIL_POINT_DEFINE(doTxnPauseBetweenOperations); */ bool _areOpsCrudOnly(const BSONObj& doTxnCmd) { for (const auto& elem : doTxnCmd.firstElement().Obj()) { - const char* names[] = {"ns", "op"}; - BSONElement fields[2]; - elem.Obj().getFields(2, names, fields); - BSONElement& fieldNs = fields[0]; - BSONElement& fieldOp = fields[1]; - - const char* opType = fieldOp.valuestrsafe(); - const StringData ns = fieldNs.valuestrsafe(); + const char* opType = elem.Obj().getField("op").valuestrsafe(); // All atomic ops have an opType of length 1. if (opType[0] == '\0' || opType[1] != '\0') @@ -89,8 +82,7 @@ bool _areOpsCrudOnly(const BSONObj& doTxnCmd) { case 'u': break; case 'i': - if (nsToCollectionSubstring(ns) != "system.indexes") - break; + break; // Fallthrough. default: return false; diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 5e9890bc896..5ea63255c23 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -1024,45 +1024,6 @@ StatusWith<OplogApplication::Mode> OplogApplication::parseMode(const std::string MONGO_UNREACHABLE; } -std::pair<BSONObj, NamespaceString> prepForApplyOpsIndexInsert(const BSONElement& fieldO, - const BSONObj& op, - const NamespaceString& requestNss) { - uassert(ErrorCodes::NoSuchKey, - str::stream() << "Missing expected index spec in field 'o': " << op, - !fieldO.eoo()); - uassert(ErrorCodes::TypeMismatch, - str::stream() << "Expected object for index spec in field 'o': " << op, - fieldO.isABSONObj()); - BSONObj indexSpec = fieldO.embeddedObject(); - - std::string indexNs; - uassertStatusOK(bsonExtractStringField(indexSpec, "ns", &indexNs)); - const NamespaceString indexNss(indexNs); - uassert(ErrorCodes::InvalidNamespace, - str::stream() << "Invalid namespace in index spec: " << op, - indexNss.isValid()); - uassert(ErrorCodes::InvalidNamespace, - str::stream() << "Database name mismatch for database (" << requestNss.db() - << ") while creating index: " - << op, - requestNss.db() == indexNss.db()); - - if (!indexSpec["v"]) { - // If the "v" field isn't present in the index specification, then we assume it is a - // v=1 index from an older version of MongoDB. This is because - // (1) we haven't built v=0 indexes as the default for a long time, and - // (2) the index version has been included in the corresponding oplog entry since - // v=2 indexes were introduced. - BSONObjBuilder bob; - - bob.append("v", static_cast<int>(IndexVersion::kV1)); - bob.appendElements(indexSpec); - - indexSpec = bob.obj(); - } - - return std::make_pair(indexSpec, indexNss); -} // @return failure status if an update should have happened and the document DNE. // See replset initial sync code. Status applyOperation_inlock(OperationContext* opCtx, @@ -1222,14 +1183,6 @@ Status applyOperation_inlock(OperationContext* opCtx, str::stream() << "Oplog entry did not have 'ts' field when expected: " << redact(op)); if (*opType == 'i') { - if (requestNss.isSystemDotIndexes()) { - BSONObj indexSpec; - NamespaceString indexNss; - std::tie(indexSpec, indexNss) = - repl::prepForApplyOpsIndexInsert(fieldO, op, requestNss); - createIndexForApplyOps(opCtx, indexSpec, indexNss, incrementOpsAppliedStats, mode); - return Status::OK(); - } uassert(ErrorCodes::NamespaceNotFound, str::stream() << "Failed to apply insert due to missing collection: " << op.toString(), diff --git a/src/mongo/db/repl/oplog.h b/src/mongo/db/repl/oplog.h index 565ab7f31cb..f64a0d0dcb6 100644 --- a/src/mongo/db/repl/oplog.h +++ b/src/mongo/db/repl/oplog.h @@ -164,15 +164,6 @@ void acquireOplogCollectionForLogging(OperationContext* opCtx); void establishOplogCollectionForLogging(OperationContext* opCtx, Collection* oplog); using IncrementOpsAppliedStatsFn = stdx::function<void()>; -/** - * Take the object field of a BSONObj, the BSONObj, and the namespace of - * the operation and perform necessary validation to ensure the BSONObj is a - * properly-formed command to insert into system.indexes. This is only to - * be used for insert operations into system.indexes. It is called via applyOps. - */ -std::pair<BSONObj, NamespaceString> prepForApplyOpsIndexInsert(const BSONElement& fieldO, - const BSONObj& op, - const NamespaceString& requestNss); /** * This class represents the different modes of oplog application that are used within the diff --git a/src/mongo/db/repl/replication_coordinator.cpp b/src/mongo/db/repl/replication_coordinator.cpp index 288cabf18a6..72954386923 100644 --- a/src/mongo/db/repl/replication_coordinator.cpp +++ b/src/mongo/db/repl/replication_coordinator.cpp @@ -86,11 +86,6 @@ bool ReplicationCoordinator::isOplogDisabledFor(OperationContext* opCtx, return true; } - // <db>.system.namespaces is a MMAP-only collection and is not replicated. - if (nss.coll() == "system.namespaces"_sd) { - return true; - } - fassert(28626, opCtx->recoveryUnit()); return false; diff --git a/src/mongo/db/repl/storage_interface_impl_test.cpp b/src/mongo/db/repl/storage_interface_impl_test.cpp index 9a681f74d88..c14d6a9c00b 100644 --- a/src/mongo/db/repl/storage_interface_impl_test.cpp +++ b/src/mongo/db/repl/storage_interface_impl_test.cpp @@ -680,7 +680,7 @@ TEST_F(StorageInterfaceImplTest, TEST_F(StorageInterfaceImplTest, CreateCollectionThatAlreadyExistsFails) { auto opCtx = getOperationContext(); StorageInterfaceImpl storage; - NamespaceString nss("test.system.indexes"); + NamespaceString nss("test.foo"); createCollection(opCtx, nss); const CollectionOptions opts = generateOptionsWithUuid(); diff --git a/src/mongo/db/repl/sync_tail.cpp b/src/mongo/db/repl/sync_tail.cpp index 5e7c7b57742..ae3717efbca 100644 --- a/src/mongo/db/repl/sync_tail.cpp +++ b/src/mongo/db/repl/sync_tail.cpp @@ -271,10 +271,6 @@ Status SyncTail::syncApply(OperationContext* opCtx, Lock::DBLock dbLock(opCtx, nss.db(), MODE_X); OldClientContext ctx(opCtx, nss.ns()); return applyOp(ctx.db()); - } else if (opType == OpTypeEnum::kInsert && nss.isSystemDotIndexes()) { - Lock::DBLock dbLock(opCtx, nss.db(), MODE_X); - OldClientContext ctx(opCtx, nss.ns()); - return applyOp(ctx.db()); } else if (OplogEntry::isCrudOpType(opType)) { return writeConflictRetry(opCtx, "syncApply_CRUD", nss.ns(), [&] { // Need to throw instead of returning a status for it to be properly ignored. diff --git a/src/mongo/db/s/operation_sharding_state.cpp b/src/mongo/db/s/operation_sharding_state.cpp index b4cc2457622..88588db7ce6 100644 --- a/src/mongo/db/s/operation_sharding_state.cpp +++ b/src/mongo/db/s/operation_sharding_state.cpp @@ -79,13 +79,7 @@ void OperationShardingState::initializeClientRoutingVersions(NamespaceString nss const auto shardVersionElem = cmdObj.getField(ChunkVersion::kShardVersionField); if (!shardVersionElem.eoo()) { - auto shardVersion = uassertStatusOK(ChunkVersion::parseFromCommand(cmdObj)); - - if (nss.isSystemDotIndexes()) { - _shardVersions[nss.ns()] = ChunkVersion::IGNORED(); - } else { - _shardVersions[nss.ns()] = std::move(shardVersion); - } + _shardVersions[nss.ns()] = uassertStatusOK(ChunkVersion::parseFromCommand(cmdObj)); } const auto dbVersionElem = cmdObj.getField(kDbVersionField); diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index 7710cd8a797..adfb9176291 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -1118,7 +1118,7 @@ void receivedInsert(OperationContext* opCtx, const NamespaceString& nsString, co for (const auto& obj : insertOp.getDocuments()) { Status status = - AuthorizationSession::get(opCtx->getClient())->checkAuthForInsert(opCtx, nsString, obj); + AuthorizationSession::get(opCtx->getClient())->checkAuthForInsert(opCtx, nsString); audit::logInsertAuthzCheck(opCtx->getClient(), nsString, obj, status.code()); uassertStatusOK(status); } diff --git a/src/mongo/dbtests/clienttests.cpp b/src/mongo/dbtests/clienttests.cpp index 57666d5e899..ac4689b6dfc 100644 --- a/src/mongo/dbtests/clienttests.cpp +++ b/src/mongo/dbtests/clienttests.cpp @@ -97,9 +97,8 @@ public: }; /** - * Check that nIndexes is incremented correctly when an index builds (and that it is not - * incremented when an index fails to build), system.indexes has an entry added (or not), and - * system.namespaces has a doc added (or not). + * Check that nIndexes is incremented correctly when an index builds, and that it is not + * incremented when an index fails to build. */ class BuildIndex : public Base { public: diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp index 1193a26dd08..9e139cce693 100644 --- a/src/mongo/dbtests/querytests.cpp +++ b/src/mongo/dbtests/querytests.cpp @@ -903,9 +903,6 @@ public: _client.insert(ns, BSON("a" << 4 << "b" << 3)); ASSERT_EQUALS(ErrorCodes::DuplicateKey, dbtests::createIndex(&_opCtx, ns, BSON("a" << 1), true)); - ASSERT_EQUALS( - 0U, - _client.count("unittests.system.indexes", BSON("ns" << ns << "name" << NE << "_id_"))); } }; diff --git a/src/mongo/embedded/embedded_auth_session.cpp b/src/mongo/embedded/embedded_auth_session.cpp index dcca9e4daf4..fecb4e6d561 100644 --- a/src/mongo/embedded/embedded_auth_session.cpp +++ b/src/mongo/embedded/embedded_auth_session.cpp @@ -120,7 +120,7 @@ public: return Status::OK(); } - Status checkAuthForInsert(OperationContext*, const NamespaceString&, const BSONObj&) override { + Status checkAuthForInsert(OperationContext*, const NamespaceString&) override { return Status::OK(); } diff --git a/src/mongo/s/catalog/sharding_catalog_test.cpp b/src/mongo/s/catalog/sharding_catalog_test.cpp index 79036d4f824..fba1b651576 100644 --- a/src/mongo/s/catalog/sharding_catalog_test.cpp +++ b/src/mongo/s/catalog/sharding_catalog_test.cpp @@ -762,29 +762,21 @@ TEST_F(ShardingCatalogClientTest, GetCollectionsValidResultsNoDb) { configTargeter()->setFindHostReturnValue(HostAndPort("TestHost1")); CollectionType coll1; - coll1.setNs(NamespaceString{"test.system.indexes"}); + coll1.setNs(NamespaceString{"test.coll1"}); coll1.setUpdatedAt(network()->now()); - coll1.setUnique(true); + coll1.setUnique(false); coll1.setEpoch(OID::gen()); coll1.setKeyPattern(KeyPattern{BSON("_id" << 1)}); ASSERT_OK(coll1.validate()); CollectionType coll2; - coll2.setNs(NamespaceString{"test.coll1"}); + coll2.setNs(NamespaceString{"anotherdb.coll1"}); coll2.setUpdatedAt(network()->now()); coll2.setUnique(false); coll2.setEpoch(OID::gen()); coll2.setKeyPattern(KeyPattern{BSON("_id" << 1)}); ASSERT_OK(coll2.validate()); - CollectionType coll3; - coll3.setNs(NamespaceString{"anotherdb.coll1"}); - coll3.setUpdatedAt(network()->now()); - coll3.setUnique(false); - coll3.setEpoch(OID::gen()); - coll3.setKeyPattern(KeyPattern{BSON("_id" << 1)}); - ASSERT_OK(coll3.validate()); - const OpTime newOpTime(Timestamp(7, 6), 5); auto future = launchAsync([this, newOpTime] { @@ -798,49 +790,46 @@ TEST_F(ShardingCatalogClientTest, GetCollectionsValidResultsNoDb) { return std::move(collections); }); - onFindWithMetadataCommand( - [this, coll1, coll2, coll3, newOpTime](const RemoteCommandRequest& request) { - ASSERT_BSONOBJ_EQ(getReplSecondaryOkMetadata(), - rpc::TrackingMetadata::removeTrackingData(request.metadata)); + onFindWithMetadataCommand([this, coll1, coll2, newOpTime](const RemoteCommandRequest& request) { + ASSERT_BSONOBJ_EQ(getReplSecondaryOkMetadata(), + rpc::TrackingMetadata::removeTrackingData(request.metadata)); - const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); - ASSERT_EQ(nss, CollectionType::ConfigNS); + const NamespaceString nss(request.dbname, request.cmdObj.firstElement().String()); + ASSERT_EQ(nss, CollectionType::ConfigNS); - auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); + auto query = assertGet(QueryRequest::makeFromFindCommand(nss, request.cmdObj, false)); - ASSERT_EQ(query->nss(), CollectionType::ConfigNS); - ASSERT_BSONOBJ_EQ(query->getFilter(), BSONObj()); - ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); + ASSERT_EQ(query->nss(), CollectionType::ConfigNS); + ASSERT_BSONOBJ_EQ(query->getFilter(), BSONObj()); + ASSERT_BSONOBJ_EQ(query->getSort(), BSONObj()); - checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm); + checkReadConcern(request.cmdObj, Timestamp(0, 0), repl::OpTime::kUninitializedTerm); - ReplSetMetadata metadata(10, newOpTime, newOpTime, 100, OID(), 30, -1); - BSONObjBuilder builder; - metadata.writeToMetadata(&builder).transitional_ignore(); + ReplSetMetadata metadata(10, newOpTime, newOpTime, 100, OID(), 30, -1); + BSONObjBuilder builder; + metadata.writeToMetadata(&builder).transitional_ignore(); - return std::make_tuple(vector<BSONObj>{coll1.toBSON(), coll2.toBSON(), coll3.toBSON()}, - builder.obj()); - }); + return std::make_tuple(vector<BSONObj>{coll1.toBSON(), coll2.toBSON()}, builder.obj()); + }); const auto& actualColls = future.timed_get(kFutureTimeout); - ASSERT_EQ(3U, actualColls.size()); + ASSERT_EQ(2U, actualColls.size()); ASSERT_BSONOBJ_EQ(coll1.toBSON(), actualColls[0].toBSON()); ASSERT_BSONOBJ_EQ(coll2.toBSON(), actualColls[1].toBSON()); - ASSERT_BSONOBJ_EQ(coll3.toBSON(), actualColls[2].toBSON()); } TEST_F(ShardingCatalogClientTest, GetCollectionsValidResultsWithDb) { configTargeter()->setFindHostReturnValue(HostAndPort("TestHost1")); CollectionType coll1; - coll1.setNs(NamespaceString{"test.system.indexes"}); + coll1.setNs(NamespaceString{"test.coll1"}); coll1.setUpdatedAt(network()->now()); coll1.setUnique(true); coll1.setEpoch(OID::gen()); coll1.setKeyPattern(KeyPattern{BSON("_id" << 1)}); CollectionType coll2; - coll2.setNs(NamespaceString{"test.coll1"}); + coll2.setNs(NamespaceString{"test.coll2"}); coll2.setUpdatedAt(network()->now()); coll2.setUnique(false); coll2.setEpoch(OID::gen()); @@ -890,7 +879,7 @@ TEST_F(ShardingCatalogClientTest, GetCollectionsInvalidCollectionType) { }); CollectionType validColl; - validColl.setNs(NamespaceString{"test.system.indexes"}); + validColl.setNs(NamespaceString{"test.coll1"}); validColl.setUpdatedAt(network()->now()); validColl.setUnique(true); validColl.setEpoch(OID::gen()); diff --git a/src/mongo/s/commands/cluster_write_cmd.cpp b/src/mongo/s/commands/cluster_write_cmd.cpp index 25ad8bcb48e..9ff50ec8c59 100644 --- a/src/mongo/s/commands/cluster_write_cmd.cpp +++ b/src/mongo/s/commands/cluster_write_cmd.cpp @@ -149,7 +149,7 @@ private: std::vector<Strategy::CommandResult>* results) { // Note that this implementation will not handle targeting retries and does not completely // emulate write behavior - ChunkManagerTargeter targeter(targetingBatchItem.getRequest()->getTargetingNS()); + ChunkManagerTargeter targeter(targetingBatchItem.getRequest()->getNS()); Status status = targeter.init(opCtx); if (!status.isOK()) return status; diff --git a/src/mongo/s/commands/commands_public.cpp b/src/mongo/s/commands/commands_public.cpp index 96c448988aa..9aee19e9b97 100644 --- a/src/mongo/s/commands/commands_public.cpp +++ b/src/mongo/s/commands/commands_public.cpp @@ -475,15 +475,11 @@ public: const BSONObj& cmdObj) const override { AuthorizationSession* authzSession = AuthorizationSession::get(client); - // Check for the listIndexes ActionType on the database, or find on system.indexes for pre - // 3.0 systems. + // Check for the listIndexes ActionType on the database. const NamespaceString ns(parseNs(dbname, cmdObj)); if (authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forExactNamespace(ns), - ActionType::listIndexes) || - authzSession->isAuthorizedForActionsOnResource( - ResourcePattern::forExactNamespace(NamespaceString(dbname, "system.indexes")), - ActionType::find)) { + ActionType::listIndexes)) { return Status::OK(); } diff --git a/src/mongo/s/write_ops/batch_write_exec.cpp b/src/mongo/s/write_ops/batch_write_exec.cpp index 94cd978b401..120d7ca33f8 100644 --- a/src/mongo/s/write_ops/batch_write_exec.cpp +++ b/src/mongo/s/write_ops/batch_write_exec.cpp @@ -208,7 +208,7 @@ void BatchWriteExec::executeBatch(OperationContext* opCtx, AsyncRequestsSender ars(opCtx, Grid::get(opCtx)->getExecutorPool()->getArbitraryExecutor(), - clientRequest.getTargetingNS().db().toString(), + clientRequest.getNS().db().toString(), requests, kPrimaryOnlyReadPreference, opCtx->getTxnNumber() ? Shard::RetryPolicy::kIdempotent diff --git a/src/mongo/s/write_ops/batched_command_request.cpp b/src/mongo/s/write_ops/batched_command_request.cpp index c500bc201eb..c94f6469aac 100644 --- a/src/mongo/s/write_ops/batched_command_request.cpp +++ b/src/mongo/s/write_ops/batched_command_request.cpp @@ -77,25 +77,6 @@ const NamespaceString& BatchedCommandRequest::getNS() const { return _visit([](auto&& op) -> decltype(auto) { return op.getNamespace(); }); } -NamespaceString BatchedCommandRequest::getTargetingNS() const { - if (!isInsertIndexRequest()) { - return getNS(); - } - - const auto& documents = _insertReq->getDocuments(); - invariant(documents.size() == 1); - - return NamespaceString(documents.at(0)["ns"].str()); -} - -bool BatchedCommandRequest::isInsertIndexRequest() const { - if (_batchType != BatchedCommandRequest::BatchType_Insert) { - return false; - } - - return getNS().isSystemDotIndexes(); -} - std::size_t BatchedCommandRequest::sizeWriteOps() const { struct Visitor { auto operator()(const write_ops::Insert& op) const { @@ -163,10 +144,6 @@ BatchedCommandRequest BatchedCommandRequest::cloneInsertWithIds( BatchedCommandRequest newCmdRequest(std::move(origCmdRequest)); - if (newCmdRequest.isInsertIndexRequest()) { - return newCmdRequest; - } - const auto& origDocs = newCmdRequest._insertReq->getDocuments(); std::vector<BSONObj> newDocs; diff --git a/src/mongo/s/write_ops/batched_command_request.h b/src/mongo/s/write_ops/batched_command_request.h index 29812e1b9d0..86b418c3a9d 100644 --- a/src/mongo/s/write_ops/batched_command_request.h +++ b/src/mongo/s/write_ops/batched_command_request.h @@ -68,12 +68,6 @@ public: } const NamespaceString& getNS() const; - NamespaceString getTargetingNS() const; - - /** - * Index creation can be expressed as an insert into the 'system.indexes' namespace. - */ - bool isInsertIndexRequest() const; const auto& getInsertRequest() const { invariant(_insertReq); diff --git a/src/mongo/s/write_ops/batched_command_request_test.cpp b/src/mongo/s/write_ops/batched_command_request_test.cpp index 437655463a0..fdab37989b9 100644 --- a/src/mongo/s/write_ops/batched_command_request_test.cpp +++ b/src/mongo/s/write_ops/batched_command_request_test.cpp @@ -104,7 +104,6 @@ TEST(BatchedCommandRequest, InsertCloneWithIds) { const auto clonedRequest(BatchedCommandRequest::cloneInsertWithIds(std::move(batchedRequest))); ASSERT_EQ("xyz.abc", clonedRequest.getNS().ns()); - ASSERT_EQ("xyz.abc", clonedRequest.getTargetingNS().ns()); ASSERT(clonedRequest.getWriteCommandBase().getOrdered()); ASSERT(clonedRequest.getWriteCommandBase().getBypassDocumentValidation()); ASSERT_BSONOBJ_EQ(BSON("w" << 2), clonedRequest.getWriteConcern()); @@ -119,32 +118,5 @@ TEST(BatchedCommandRequest, InsertCloneWithIds) { ASSERT_EQ(2, insertDocs[1]["x"].numberLong()); } -TEST(BatchedCommandRequest, IndexInsertCloneWithIds) { - const auto indexSpec = BSON("v" << 1 << "key" << BSON("x" << -1) << "name" - << "Test index" - << "ns" - << "xyz.abc"); - - BatchedCommandRequest batchedRequest([&] { - write_ops::Insert insertOp(NamespaceString("xyz.system.indexes")); - insertOp.setDocuments({indexSpec}); - return insertOp; - }()); - batchedRequest.setWriteConcern(BSON("w" << 2)); - - const auto clonedRequest(BatchedCommandRequest::cloneInsertWithIds(std::move(batchedRequest))); - - ASSERT_EQ("xyz.system.indexes", clonedRequest.getNS().ns()); - ASSERT_EQ("xyz.abc", clonedRequest.getTargetingNS().ns()); - ASSERT(clonedRequest.getWriteCommandBase().getOrdered()); - ASSERT(!clonedRequest.getWriteCommandBase().getBypassDocumentValidation()); - ASSERT_BSONOBJ_EQ(BSON("w" << 2), clonedRequest.getWriteConcern()); - - const auto& insertDocs = clonedRequest.getInsertRequest().getDocuments(); - ASSERT_EQ(1u, insertDocs.size()); - - ASSERT_BSONOBJ_EQ(indexSpec, insertDocs[0]); -} - } // namespace } // namespace mongo diff --git a/src/mongo/s/write_ops/cluster_write.cpp b/src/mongo/s/write_ops/cluster_write.cpp index 421383d99ca..16159dbca3c 100644 --- a/src/mongo/s/write_ops/cluster_write.cpp +++ b/src/mongo/s/write_ops/cluster_write.cpp @@ -75,15 +75,14 @@ void ClusterWriter::write(OperationContext* opCtx, Grid::get(opCtx)->catalogClient()->writeConfigServerDirect(opCtx, request, response); } else { { - ChunkManagerTargeter targeter(request.getTargetingNS()); + ChunkManagerTargeter targeter(request.getNS()); Status targetInitStatus = targeter.init(opCtx); if (!targetInitStatus.isOK()) { toBatchError(targetInitStatus.withContext( - str::stream() << "unable to initialize targeter for" - << (request.isInsertIndexRequest() ? " index" : "") - << " write op for collection " - << request.getTargetingNS().ns()), + str::stream() + << "unable to initialize targeter for write op for collection " + << request.getNS().ns()), response); return; } @@ -91,10 +90,8 @@ void ClusterWriter::write(OperationContext* opCtx, auto swEndpoints = targeter.targetCollection(); if (!swEndpoints.isOK()) { toBatchError(swEndpoints.getStatus().withContext( - str::stream() << "unable to target" - << (request.isInsertIndexRequest() ? " index" : "") - << " write op for collection " - << request.getTargetingNS().ns()), + str::stream() << "unable to target write op for collection " + << request.getNS().ns()), response); return; } diff --git a/src/mongo/s/write_ops/write_op.cpp b/src/mongo/s/write_ops/write_op.cpp index b125f35a970..ec10197376c 100644 --- a/src/mongo/s/write_ops/write_op.cpp +++ b/src/mongo/s/write_ops/write_op.cpp @@ -53,16 +53,8 @@ const WriteErrorDetail& WriteOp::getOpError() const { Status WriteOp::targetWrites(OperationContext* opCtx, const NSTargeter& targeter, std::vector<TargetedWrite*>* targetedWrites) { - const bool isIndexInsert = _itemRef.getRequest()->isInsertIndexRequest(); - auto swEndpoints = [&]() -> StatusWith<std::vector<ShardEndpoint>> { if (_itemRef.getOpType() == BatchedCommandRequest::BatchType_Insert) { - if (isIndexInsert) { - // TODO: Remove the index targeting stuff once there is a command for it? - // TODO: Retry index writes with stale version? - return targeter.targetCollection(); - } - auto swEndpoint = targeter.targetInsert(opCtx, _itemRef.getDocument()); if (!swEndpoint.isOK()) return swEndpoint.getStatus(); @@ -82,7 +74,7 @@ Status WriteOp::targetWrites(OperationContext* opCtx, // // NOTE: Index inserts are currently specially targeted only at the current collection to avoid // creating collections everywhere. - if (swEndpoints.isOK() && swEndpoints.getValue().size() > 1u && !isIndexInsert) { + if (swEndpoints.isOK() && swEndpoints.getValue().size() > 1u) { swEndpoints = targeter.targetAllShards(opCtx); } diff --git a/src/mongo/shell/collection.js b/src/mongo/shell/collection.js index 55cafb2fac0..584136fa99e 100644 --- a/src/mongo/shell/collection.js +++ b/src/mongo/shell/collection.js @@ -641,27 +641,10 @@ DBCollection.prototype.createIndexes = function(keys, options) { indexSpecs[i] = this._indexSpec(keys[i], options); } - if (this.getMongo().writeMode() == "commands") { - for (var i = 0; i < indexSpecs.length; i++) { - delete (indexSpecs[i].ns); // ns is passed to the first element in the command. - } - return this._db.runCommand({createIndexes: this.getName(), indexes: indexSpecs}); - } else if (this.getMongo().writeMode() == "compatibility") { - // Use the downconversion machinery of the bulk api to do a safe write, report response as a - // command response - var result = this._db.getCollection("system.indexes").insert(indexSpecs, 0); - - if (result.hasWriteErrors() || result.hasWriteConcernError()) { - // Return the first error - var error = result.hasWriteErrors() ? result.getWriteErrors()[0] - : result.getWriteConcernError(); - return {ok: 0.0, code: error.code, errmsg: error.errmsg}; - } else { - return {ok: 1.0}; - } - } else { - this._db.getCollection("system.indexes").insert(indexSpecs, 0); + for (var i = 0; i < indexSpecs.length; i++) { + delete (indexSpecs[i].ns); // ns is passed to the first element in the command. } + return this._db.runCommand({createIndexes: this.getName(), indexes: indexSpecs}); }; DBCollection.prototype.ensureIndex = function(keys, options) { @@ -822,46 +805,21 @@ DBCollection.prototype.getShardVersion = function() { return this._db._adminCommand({getShardVersion: this._fullName}); }; -DBCollection.prototype._getIndexesSystemIndexes = function(filter) { - var si = this.getDB().getCollection("system.indexes"); - var query = {ns: this.getFullName()}; - if (filter) - query = Object.extend(query, filter); - return si.find(query).toArray(); -}; - -DBCollection.prototype._getIndexesCommand = function(filter) { +DBCollection.prototype.getIndexes = function(filter) { var res = this.runCommand("listIndexes", filter); if (!res.ok) { - if (res.code == 59) { - // command doesn't exist, old mongod - return null; - } - - if (res.code == 26) { - // NamespaceNotFound, for compatability, return [] + if (res.code == ErrorCodes.NamespaceNotFound) { + // For compatibility, return [] return []; } - if (res.errmsg && res.errmsg.startsWith("no such cmd")) { - return null; - } - throw _getErrorWithCode(res, "listIndexes failed: " + tojson(res)); } return new DBCommandCursor(this._db, res).toArray(); }; -DBCollection.prototype.getIndexes = function(filter) { - var res = this._getIndexesCommand(filter); - if (res) { - return res; - } - return this._getIndexesSystemIndexes(filter); -}; - DBCollection.prototype.getIndices = DBCollection.prototype.getIndexes; DBCollection.prototype.getIndexSpecs = DBCollection.prototype.getIndexes; @@ -881,16 +839,11 @@ DBCollection.prototype.hashAllDocs = function() { }; /** - * <p>Drop a specified index.</p> + * Drop a specified index. * - * <p> - * "index" is the name of the index in the system.indexes name field (run db.system.indexes.find() - *to - * see example data), or an object holding the key(s) used to create the index. - * For example: - * db.collectionName.dropIndex( "myIndexName" ); - * db.collectionName.dropIndex( { "indexKey" : 1 } ); - * </p> + * "index" is the name or key pattern of the index. For example: + * db.collectionName.dropIndex( "myIndexName" ); + * db.collectionName.dropIndex( { "indexKey" : 1 } ); * * @param {String} name or key object of index to delete. * @return A result object. result.ok will be true if successful. @@ -1032,10 +985,6 @@ DBCollection.prototype.exists = function() { return cursor.next(); } - if (res.errmsg && res.errmsg.startsWith("no such cmd")) { - return this._db.system.namespaces.findOne({name: this._fullName}); - } - throw _getErrorWithCode(res, "listCollections failed: " + tojson(res)); }; diff --git a/src/mongo/shell/db.js b/src/mongo/shell/db.js index 9f6f497d5d1..d487497de36 100644 --- a/src/mongo/shell/db.js +++ b/src/mongo/shell/db.js @@ -858,39 +858,6 @@ var DB; return this.runCommand({getpreverror: 1}); }; - DB.prototype._getCollectionInfosSystemNamespaces = function(filter) { - var all = []; - - var dbNamePrefix = this._name + "."; - - // Create a shallow copy of 'filter' in case we modify its 'name' property. Also defaults - // 'filter' to {} if the parameter was not specified. - filter = Object.extend({}, filter); - if (typeof filter.name === "string") { - // Queries on the 'name' field need to qualify the namespace with the database name for - // consistency with the command variant. - filter.name = dbNamePrefix + filter.name; - } - - var c = this.getCollection("system.namespaces").find(filter); - while (c.hasNext()) { - var infoObj = c.next(); - - if (infoObj.name.indexOf("$") >= 0 && infoObj.name.indexOf(".oplog.$") < 0) - continue; - - // Remove the database name prefix from the collection info object. - infoObj.name = infoObj.name.substring(dbNamePrefix.length); - - all.push(infoObj); - } - - // Return list of objects sorted by collection name. - return all.sort(function(coll1, coll2) { - return coll1.name.localeCompare(coll2.name); - }); - }; - DB.prototype._getCollectionInfosCommand = function( filter, nameOnly = false, authorizedCollections = false) { filter = filter || {}; @@ -949,39 +916,28 @@ var DB; */ DB.prototype.getCollectionInfos = function( filter, nameOnly = false, authorizedCollections = false) { - let oldException; try { return this._getCollectionInfosCommand(filter, nameOnly, authorizedCollections); } catch (ex) { - if (ex.code !== ErrorCodes.Unauthorized && ex.code !== ErrorCodes.CommandNotFound && - !ex.message.startsWith("no such cmd")) { + if (ex.code !== ErrorCodes.Unauthorized) { // We cannot recover from this error, propagate it. throw ex; } - oldException = ex; - } - // We have failed to run listCollections. This may be due to the command not - // existing, or authorization failing. Try to query the system.namespaces collection. - try { - return this._getCollectionInfosSystemNamespaces(filter); - } catch (ex2) { - // Querying the system.namespaces collection has failed. We may be able to compute a - // set of *some* collections which exist and we have access to from our privileges. - // For this to work, the previous operations must have failed due to authorization, - // we must be attempting to recover the names of our own collections, + // We may be able to compute a set of *some* collections which exist and we have access + // to from our privileges. For this to work, the previous operation must have failed due + // to authorization, we must be attempting to recover the names of our own collections, // and no filter can have been provided. if (nameOnly && authorizedCollections && Object.getOwnPropertyNames(filter).length === 0 && - oldException.code === ErrorCodes.Unauthorized && - ex2.code == ErrorCodes.Unauthorized) { + ex.code === ErrorCodes.Unauthorized) { print( "Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus"); return this._getCollectionInfosFromPrivileges(); } - throw oldException; + throw ex; } }; |