Details
-
Bug
-
Resolution: Fixed
-
Critical - P2
-
3.6.0-rc0
-
None
-
Fully Compatible
-
ALL
-
-
Storage 2017-11-13
-
0
Description
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()); |
}
|
Attachments
Issue Links
- 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
-