...
BugZero found this defect 2610 days ago.
If a secondary during steady-state replication receives an oplog entry for creating a collection without a UUID while it is in featureCompatibilityVersion=3.6, then it must abort because the alternative is data corruption. Note: This issue was only found due to a race condition in the "setFeatureCompatibilityVersion" command allowing for this possibility (SERVER-31017). I suspect it is possible to simulate this more easily in sync_tail_test.cpp by using the multiSyncApply_noAbort() function. 2017-09-10T10:58:45.756-0400 2017-09-10T10:58:45.752-0400 E QUERY [thread1] Error: [{ 2017-09-10T10:58:45.756-0400 "name" : "mycoll", 2017-09-10T10:58:45.756-0400 "type" : "collection", 2017-09-10T10:58:45.756-0400 "options" : { 2017-09-10T10:58:45.757-0400 2017-09-10T10:58:45.757-0400 }, 2017-09-10T10:58:45.757-0400 "info" : { 2017-09-10T10:58:45.757-0400 "readOnly" : false 2017-09-10T10:58:45.757-0400 }, 2017-09-10T10:58:45.757-0400 "idIndex" : { 2017-09-10T10:58:45.757-0400 "v" : 2, 2017-09-10T10:58:45.757-0400 "key" : { 2017-09-10T10:58:45.757-0400 "_id" : 1 2017-09-10T10:58:45.757-0400 }, 2017-09-10T10:58:45.758-0400 "name" : "_id_", 2017-09-10T10:58:45.758-0400 "ns" : "test.mycoll" 2017-09-10T10:58:45.758-0400 } 2017-09-10T10:58:45.758-0400 }] != [{ 2017-09-10T10:58:45.758-0400 "name" : "mycoll", 2017-09-10T10:58:45.758-0400 "type" : "collection", 2017-09-10T10:58:45.758-0400 "options" : { 2017-09-10T10:58:45.758-0400 2017-09-10T10:58:45.758-0400 }, 2017-09-10T10:58:45.758-0400 "info" : { 2017-09-10T10:58:45.758-0400 "readOnly" : false, 2017-09-10T10:58:45.759-0400 "uuid" : UUID("440a716d-c32d-49d0-a39b-87c564ac61c6") 2017-09-10T10:58:45.759-0400 }, 2017-09-10T10:58:45.759-0400 "idIndex" : { 2017-09-10T10:58:45.759-0400 "v" : 2, 2017-09-10T10:58:45.759-0400 "key" : { 2017-09-10T10:58:45.759-0400 "_id" : 1 2017-09-10T10:58:45.760-0400 }, 2017-09-10T10:58:45.760-0400 "name" : "_id_", 2017-09-10T10:58:45.760-0400 "ns" : "test.mycoll" 2017-09-10T10:58:45.760-0400 } 2017-09-10T10:58:45.760-0400 }] are not equal : Expected primary and secondary to have the same collection metadata :
xgen-internal-githook commented on Fri, 29 Sep 2017 21:09:42 +0000: Author: {'email': 'geert@mongodb.com', 'name': 'Geert Bosch', 'username': 'GeertBosch'} Message: SERVER-31018 Fix lint Branch: master https://github.com/mongodb/mongo/commit/87b23ef60c1d3c32d98e5c38c598664223434a80 xgen-internal-githook commented on Fri, 29 Sep 2017 20:21:43 +0000: Author: {'email': 'geert@mongodb.com', 'name': 'Geert Bosch', 'username': 'GeertBosch'} Message: SERVER-31018 Prevent secondaries from generating UUIDs for replicated collections Branch: master https://github.com/mongodb/mongo/commit/ffe44d0f3cd68721a9cdc34d0974fad604f0f4c7
python buildscripts/resmoke.py --suites=no_server server31018.js repro_server31018.js (function() { "use strict"; load("jstests/libs/parallelTester.js"); // for ScopedThread and CountDownLatch const rst = new ReplSetTest({nodes: 2}); rst.startSet(); rst.initiate(); function setFCV(host, version, barrier) { const conn = new Mongo(host); barrier.countDown(); barrier.await(); try { assert.commandWorked(conn.adminCommand({setFeatureCompatibilityVersion: version})); return {ok: 1}; } catch (e) { return {ok: 0, error: e.toString(), stack: e.stack}; } } const primary = rst.getPrimary(); const secondary = rst.getSecondary(); const primaryDB = primary.getDB("test"); const secondaryDB = secondary.getDB("test"); while (true) { // We create two threads: one to set the server's featureCompatibilityVersion to "3.4" and // another to set the server's featureCompatibilityVersion to "3.6". { const barrier = new CountDownLatch(2); const thread34 = new ScopedThread(setFCV, primary.host, "3.4", barrier); const thread36 = new ScopedThread(setFCV, primary.host, "3.6", barrier); thread34.start(); thread36.start(); thread34.join(); thread36.join(); assert.commandWorked(thread34.returnData()); assert.commandWorked(thread36.returnData()); } // If the thread that sets the server's featureCompatibilityVersion to "3.4" did its update // to the featureCompatibilityVersion document last, then we reset the server's // featureCompatibilityVersion to "3.6" and try again. { const res = assert.commandWorked( primaryDB.adminCommand({getParameter: 1, featureCompatibilityVersion: 1})); if (res.featureCompatibilityVersion === "3.4") { assert.commandWorked( primaryDB.adminCommand({setFeatureCompatibilityVersion: "3.6"})); continue; } } // Otherwise, we implicitly create a collection via an insert operation and verify that the // collection has identical metadata on the primary and the secondary. { primaryDB.mycoll.drop(); assert.writeOK(primaryDB.mycoll.insert({}, {writeConcern: {w: 2}})); const primaryCollectionInfos = primaryDB.getCollectionInfos({name: "mycoll"}); assert.eq(1, primaryCollectionInfos.length, tojson(primaryCollectionInfos)); const secondaryCollectionInfos = secondaryDB.getCollectionInfos({name: "mycoll"}); assert.eq(1, secondaryCollectionInfos.length, tojson(secondaryCollectionInfos)); assert.eq(primaryCollectionInfos[0], secondaryCollectionInfos[0], "Expected primary and secondary to have the same collection metadata"); } } rst.stopSet(); })();