Skip to content

Commit 7593e97

Browse files
PolPinolEvergreen Agent
authored andcommitted
SERVER-78918 Make shardCollection command shard authoritative
1 parent bc85e30 commit 7593e97

10 files changed

+465
-248
lines changed

buildscripts/resmokeconfig/fully_disabled_feature_flags.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
# its targeted tests should enable it.
1212
- featureFlagAlwaysCreateConfigTransactionsPartialIndexOnStepUp
1313
- featureFlagUpdateDocumentShardKeyUsingTransactionApi
14-
- featureFlagAuthoritativeShardCollection
1514
- featureFlagAllMongodsAreSharded
1615
- featureFlagGRPC
1716
- featureFlagReplicaSetEndpoint

jstests/sharding/update_replace_id.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,31 @@ function setUpData() {
6565
}
6666

6767
function runReplacementUpdateTestsForHashedShardKey() {
68-
// Make sure the chunk containing key {_id: -100} is on shard0.
68+
// Make sure the chunk containing key {_id: -100} is on shard0; the chunk is migrated twice to
69+
// ensure that the shard CSR has also a not-UNKOWN version. This will allow direct writes
70+
// performed later in this test to work because the filtering metadata are set.
71+
assert.commandWorked(mongosDB.adminCommand({
72+
moveChunk: mongosColl.getFullName(),
73+
find: {_id: -100},
74+
to: st.shard1.shardName,
75+
_waitForDelete: true
76+
}));
6977
assert.commandWorked(mongosDB.adminCommand({
7078
moveChunk: mongosColl.getFullName(),
7179
find: {_id: -100},
7280
to: st.shard0.shardName,
7381
_waitForDelete: true
7482
}));
7583

76-
// Make sure the chunk containing key {_id: -101} is on shard1.
84+
// Make sure the chunk containing key {_id: 101} is on shard1; the chunk is migrated twice to
85+
// ensure that the shard CSR has also a not-UNKOWN version. This will allow direct writes
86+
// performed later in this test to work because the filtering metadata are set.
87+
assert.commandWorked(mongosDB.adminCommand({
88+
moveChunk: mongosColl.getFullName(),
89+
find: {_id: 101},
90+
to: st.shard0.shardName,
91+
_waitForDelete: true
92+
}));
7793
assert.commandWorked(mongosDB.adminCommand({
7894
moveChunk: mongosColl.getFullName(),
7995
find: {_id: 101},

src/mongo/db/commands/set_feature_compatibility_version_command.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -644,8 +644,6 @@ class SetFeatureCompatibilityVersionCommand : public BasicCommand {
644644
// TODO (SERVER-77915): Remove once 8.0 (trackUnshardedCollections) becomes lastLTS.
645645
if (isDowngrading &&
646646
(feature_flags::gAuthoritativeShardCollection
647-
.isDisabledOnTargetFCVButEnabledOnOriginalFCV(requestedVersion, originalVersion) ||
648-
feature_flags::gTrackUnshardedCollectionsOnShardingCatalog
649647
.isDisabledOnTargetFCVButEnabledOnOriginalFCV(requestedVersion,
650648
originalVersion))) {
651649
ShardingDDLCoordinatorService::getService(opCtx)
@@ -1618,7 +1616,7 @@ class SetFeatureCompatibilityVersionCommand : public BasicCommand {
16181616
feature_flags::gAuthoritativeShardCollection.isEnabledOnVersion(requestedVersion)) {
16191617
ShardingDDLCoordinatorService::getService(opCtx)
16201618
->waitForCoordinatorsOfGivenTypeToComplete(
1621-
opCtx, DDLCoordinatorTypeEnum::kCreateCollectionPre71Compatible);
1619+
opCtx, DDLCoordinatorTypeEnum::kCreateCollectionPre73Compatible);
16221620
}
16231621
_maybeRemoveOldAuditConfig(opCtx, requestedVersion);
16241622

src/mongo/db/s/create_collection_coordinator.cpp

Lines changed: 379 additions & 207 deletions
Large diffs are not rendered by default.

src/mongo/db/s/create_collection_coordinator.h

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class CreateCollectionResponseProvider {
8888
virtual ~CreateCollectionResponseProvider() {}
8989
};
9090

91+
// TODO (SERVER-79304): Remove once 8.0 becomes last LTS.
9192
class CreateCollectionCoordinatorLegacy
9293
: public RecoverableShardingDDLCoordinator<CreateCollectionCoordinatorDocumentLegacy,
9394
CreateCollectionCoordinatorPhaseLegacyEnum>,
@@ -185,33 +186,54 @@ class CreateCollectionCoordinator
185186
return CreateCollectionCoordinatorPhase_serializer(phase);
186187
}
187188

189+
bool _mustAlwaysMakeProgress() override;
190+
188191
ExecutorFuture<void> _runImpl(std::shared_ptr<executor::ScopedTaskExecutor> executor,
189192
const CancellationToken& token) noexcept override;
190193

191194
ExecutorFuture<void> _cleanupOnAbort(std::shared_ptr<executor::ScopedTaskExecutor> executor,
192195
const CancellationToken& token,
193196
const Status& status) noexcept override;
194197

195-
/**
196-
* Acquires critical sections on all shards.
197-
*/
198-
void _acquireCriticalSectionsOnParticipants(
199-
OperationContext* opCtx,
200-
std::shared_ptr<executor::ScopedTaskExecutor> executor,
201-
const CancellationToken& token);
198+
// Check the command arguments passed and validate that the collection has not been tracked from
199+
// another request.
200+
void _checkPreconditions();
202201

203-
/**
204-
* Releases critical sections on all shards.
205-
*/
206-
void _releaseCriticalSectionsOnParticipants(
207-
OperationContext* opCtx,
208-
std::shared_ptr<executor::ScopedTaskExecutor> executor,
209-
const CancellationToken& token);
202+
// Enter to the critical section on the coordinator for the namespace and its buckets namespace.
203+
// Only blocks writes.
204+
void _enterWriteCriticalSectionOnCoordinator();
210205

211-
/**
212-
* Functions to encapsulate each phase
213-
*/
214-
void _checkPreconditions(std::shared_ptr<executor::ScopedTaskExecutor> executor);
206+
// Translate the request parameters and persist them in the coordinator document.
207+
void _translateRequestParameters();
208+
209+
// Ensure that the collection is created locally and build the shard key index if necessary.
210+
void _createCollectionOnCoordinator();
211+
212+
// Enter to the critical section on all the shards. Blocks writes and reads.
213+
void _enterCriticalSection(const std::shared_ptr<executor::ScopedTaskExecutor>& executor,
214+
const CancellationToken& token);
215+
216+
// Broadcast create collection to the other shards.
217+
void _createCollectionOnParticipants(
218+
const std::shared_ptr<executor::ScopedTaskExecutor>& executor);
219+
220+
// Commits the create collection operation to the sharding catalog within a transaction. After
221+
// that, it clears the filtering metadata on the primary shard.
222+
void _commitOnShardingCatalog(const std::shared_ptr<executor::ScopedTaskExecutor>& executor);
223+
224+
// Exit from the critical section on all the shards, unblocking reads and writes. On the
225+
// participant shards, it is set to clear the filtering metadata after exiting the critical
226+
// section.
227+
void _exitCriticalSection(const std::shared_ptr<executor::ScopedTaskExecutor>& executor,
228+
const CancellationToken& token);
229+
230+
// Exit critical sections on participant shards.
231+
void _exitCriticalSectionsOnParticipants(OperationContext* opCtx,
232+
bool throwIfReasonDiffers,
233+
std::shared_ptr<executor::ScopedTaskExecutor> executor,
234+
const CancellationToken& token);
235+
236+
bool _validateCreateCollectionAlreadyCommitted(OperationContext* opCtx);
215237

216238
mongo::ShardsvrCreateCollectionRequest _request;
217239

@@ -220,13 +242,11 @@ class CreateCollectionCoordinator
220242
// Set on successful completion of the coordinator
221243
boost::optional<CreateCollectionResponse> _result;
222244

223-
// The fields below are only populated if the coordinator enters in the branch where the
224-
// collection is not already sharded (i.e., they will not be present on early return)
225-
226-
boost::optional<UUID> _collectionUUID;
227-
std::unique_ptr<InitialSplitPolicy> _splitPolicy;
228-
boost::optional<InitialSplitPolicy::ShardCollectionConfig> _initialChunks;
245+
// The fields below are only populated for the first execution, they will not be present if it
246+
// is not the first run.
247+
boost::optional<UUID> _uuid;
229248
boost::optional<bool> _collectionEmpty;
249+
boost::optional<InitialSplitPolicy::ShardCollectionConfig> _initialChunks;
230250
};
231251

232252
} // namespace mongo

src/mongo/db/s/create_collection_coordinator_document.idl

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,26 @@ imports:
3838
- "mongo/s/request_types/sharded_ddl_commands.idl"
3939

4040
enums:
41+
# TODO (SERVER-79304): Remove once 8.0 becomes last LTS.
4142
CreateCollectionCoordinatorPhaseLegacy:
4243
description: "Current create collection coordinator's operation state."
4344
type: string
4445
values:
4546
kUnset: "unset"
4647
kCommit: "commit"
48+
4749
CreateCollectionCoordinatorPhase:
4850
description: "Current create collection coordinator's operation state."
4951
type: string
5052
values:
5153
kUnset: "unset"
52-
kAcquireCSOnCoordinator: "acquireCSOnCoordinator"
53-
kTranslateRequest: "translateRequest"
54-
kAcquireCSOnParticipants: "acquireCSOnParticipants"
55-
kCommit: "commit"
56-
kReleaseAllCS: "releaseAllCS"
54+
kEnterWriteCriticalSectionOnCoordinator: "enterWriteCriticalSectionOnCoordinator"
55+
kTranslateRequestParameters: "translateRequestParameters"
56+
kCreateCollectionOnCoordinator: "createCollectionOnCoordinator"
57+
kEnterCriticalSection: "enterCriticalSection"
58+
kCreateCollectionOnParticipants: "createCollectionOnParticipants"
59+
kCommitOnShardingCatalog: "commitOnShardingCatalog"
60+
kExitCriticalSection: "exitCriticalSection"
5761

5862
structs:
5963
TranslatedRequestParams:
@@ -74,8 +78,9 @@ structs:
7478
description: "Collation value from the targeted unsharded collection if this exists; otherwise, simple-collation"
7579
optional: false
7680

81+
# TODO (SERVER-79304): Remove once 8.0 becomes last LTS.
7782
CreateCollectionCoordinatorDocumentLegacy:
78-
description: "Object with neccessary fields to create a collection"
83+
description: "Object with necessary fields to create a collection"
7984
generate_comparison_operators: false
8085
strict: false
8186
chained_structs:
@@ -90,6 +95,7 @@ structs:
9095
type: TranslatedRequestParams
9196
description: "The field is populated only once the kTranslateRequest phase is completed"
9297
optional: true
98+
9399
CreateCollectionCoordinatorDocument:
94100
description: "Object with neccessary fields to create a collection"
95101
generate_comparison_operators: false
@@ -104,5 +110,9 @@ structs:
104110
default: kUnset
105111
translatedRequestParams:
106112
type: TranslatedRequestParams
107-
description: "The field is populated only once the kTranslateRequest phase is completed"
113+
description: "The field is populated only once the kTranslateRequest phase is completed."
114+
optional: true
115+
shardIds:
116+
type: array<shard_id>
117+
description: "The list of shards involved in the create collection operation."
108118
optional: true

src/mongo/db/s/sharding_ddl_coordinator.idl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ enums:
4949
kDropCollection: "dropCollection_V2"
5050
kRenameCollection: "renameCollection_V2"
5151
kCreateCollection: "createCollection_V4"
52-
kCreateCollectionPre71Compatible: "createCollection_V3"
52+
# TODO SERVER-79304: Remove once 8.0 becomes last LTS
53+
kCreateCollectionPre73Compatible: "createCollection_V3"
5354
# TODO SERVER-79064: Remove once 8.0 becomes last LTS
5455
kRefineCollectionShardKeyPre71Compatible: "refineCollectionShardKey"
5556
kRefineCollectionShardKey: "refineCollectionShardKey_V2"

src/mongo/db/s/sharding_ddl_coordinator_service.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ std::shared_ptr<ShardingDDLCoordinator> constructShardingDDLCoordinatorInstance(
112112
return std::make_shared<RefineCollectionShardKeyCoordinatorPre71Compatible>(
113113
service, std::move(initialState));
114114
break;
115-
case DDLCoordinatorTypeEnum::kCreateCollectionPre71Compatible:
115+
case DDLCoordinatorTypeEnum::kCreateCollectionPre73Compatible:
116116
return std::make_shared<CreateCollectionCoordinatorLegacy>(service,
117117
std::move(initialState));
118118
break;

src/mongo/db/s/shardsvr_create_collection_command.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ class ShardsvrCreateCollectionCommand final : public TypedCommand<ShardsvrCreate
184184
requestToForward.setTimeseries(std::move(timeseriesOptions));
185185
}
186186

187+
// TODO (SERVER-79304): Remove once 8.0 becomes last LTS.
187188
FixedFCVRegion fixedFcvRegion{opCtx};
188-
189189
auto coordinatorDoc = [&] {
190190
if (feature_flags::gAuthoritativeShardCollection.isEnabled(
191191
(*fixedFcvRegion).acquireFCVSnapshot())) {
@@ -197,7 +197,7 @@ class ShardsvrCreateCollectionCommand final : public TypedCommand<ShardsvrCreate
197197
return doc.toBSON();
198198
} else {
199199
const DDLCoordinatorTypeEnum coordType =
200-
DDLCoordinatorTypeEnum::kCreateCollectionPre71Compatible;
200+
DDLCoordinatorTypeEnum::kCreateCollectionPre73Compatible;
201201
auto doc = CreateCollectionCoordinatorDocumentLegacy();
202202
doc.setShardingDDLCoordinatorMetadata({{ns(), coordType}});
203203
doc.setShardsvrCreateCollectionRequest(requestToForward);

src/mongo/s/sharding_feature_flags.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ feature_flags:
8282
default: true
8383
version: 7.1
8484
shouldBeFCVGated: true
85+
# TODO (SERVER-79304): Remove once 8.0 becomes last LTS.
8586
featureFlagAuthoritativeShardCollection:
8687
description: "Feature flag for enabling the authoritative version of the shardCollection DDL operation."
8788
cpp_varname: feature_flags::gAuthoritativeShardCollection

0 commit comments

Comments
 (0)