-
Type: Bug
-
Resolution: Fixed
-
Priority: Critical - P2
-
Affects Version/s: 3.6.0-rc0
-
Component/s: Replication, Storage
-
None
-
Fully Compatible
-
ALL
-
-
Storage 2017-11-13
-
0
Prior to the changes from e035926 as part of SERVER-31209, serverGlobalParams.featureCompatibility.isSchemaVersion36 was immediately being to set true when {setFeatureCompatibilityVersion: "3.6"} ran as part of the upgrade process, and serverGlobalParams.featureCompatibility.version was being set to FeatureCompatibility::Version::k36 only after assigning UUIDs to all existing collections. Whether we're in schemaVersion=3.6 is instead now derived from the (featureCompatibilityVersion, targetVersion) pair; however, the okayCreation variable incorrectly permits a secondary to generate its own UUIDs (i.e. cause data to diverge from the primary) when the featureCompatibilityVersion is FeatureCompatibility::Version::kUpgradingTo36 since that's a case where schemaVersion=3.6 but we not yet fully-upgraded to 3.6.
Any time a new collection is being created under schemaVersion=3.6—regardless of whether we've fully-upgraded to 3.6 or not—the collection should be assigned a UUID by the primary and that UUID should be included in the oplog entry for the "create" command. Since (1) DatabaseImpl::createCollection() and _updateDatabaseUUIDSchemaVersion() both require that the database lock in held in MODE_X and (2) FeatureCompatibilityVersion::setTargetUpgrade() is called before updateUUIDSchemaVersion(), we're guaranteed that either (a) creating a collection must observe the change to schemaVersion=3.6 by happening after the UUID upgrade, or (b) creating a collection happens before the UUID upgrade is performed.
CollectionOptions optionsWithUUID = options; if (enableCollectionUUIDs && !optionsWithUUID.uuid && serverGlobalParams.featureCompatibility.isSchemaVersion36()) { auto coordinator = repl::ReplicationCoordinator::get(opCtx); bool okayCreation = (coordinator->getReplicationMode() != repl::ReplicationCoordinator::modeReplSet || (serverGlobalParams.featureCompatibility.getVersion() != ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo36) || coordinator->canAcceptWritesForDatabase(opCtx, nss.db()) || nss.isSystemDotProfile()); // system.profile is special as it's not replicated if (!okayCreation) { std::string msg = str::stream() << "Attempt to assign UUID to replicated collection: " << nss.ns(); severe() << msg; uasserted(ErrorCodes::InvalidOptions, msg); } optionsWithUUID.uuid.emplace(CollectionUUID::gen()); }
- is caused by
-
SERVER-31209 need to store upgrade/downgrade in progress for sharding
- Closed
- is related to
-
SERVER-31018 Secondaries generate a UUID for a replicated collection on their own if one isn't provided
- Closed
-
SERVER-30745 Prohibit unsafe comparisons against feature compatibility version
- Closed