summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/commands/shutdown.h3
-rw-r--r--src/mongo/db/commands/shutdown_d.cpp38
-rw-r--r--src/mongo/db/db.cpp27
3 files changed, 40 insertions, 28 deletions
diff --git a/src/mongo/db/commands/shutdown.h b/src/mongo/db/commands/shutdown.h
index c8686afc99e..e3725619f96 100644
--- a/src/mongo/db/commands/shutdown.h
+++ b/src/mongo/db/commands/shutdown.h
@@ -35,6 +35,9 @@
#include "mongo/db/jsobj.h"
namespace mongo {
+Status stepDownForShutdown(OperationContext* opCtx,
+ const Milliseconds& waitTime,
+ bool forceShutdown) noexcept;
class CmdShutdown : public BasicCommand {
public:
diff --git a/src/mongo/db/commands/shutdown_d.cpp b/src/mongo/db/commands/shutdown_d.cpp
index b6d8154c999..5bf404f682e 100644
--- a/src/mongo/db/commands/shutdown_d.cpp
+++ b/src/mongo/db/commands/shutdown_d.cpp
@@ -35,8 +35,37 @@
#include "mongo/db/commands/shutdown.h"
#include "mongo/db/repl/replication_coordinator.h"
+#include "mongo/db/s/transaction_coordinator_service.h"
+#include "mongo/util/log.h"
namespace mongo {
+
+Status stepDownForShutdown(OperationContext* opCtx,
+ const Milliseconds& waitTime,
+ bool forceShutdown) noexcept {
+ auto replCoord = repl::ReplicationCoordinator::get(opCtx);
+ // If this is a single node replica set, then we don't have to wait
+ // for any secondaries. Ignore stepdown.
+ if (replCoord->getConfig().getNumMembers() != 1) {
+ try {
+ replCoord->stepDown(opCtx, false /* force */, waitTime, Seconds(120));
+ } catch (const ExceptionFor<ErrorCodes::NotMaster>&) {
+ // Ignore not master errors.
+ } catch (const DBException& e) {
+ if (!forceShutdown) {
+ return e.toStatus();
+ }
+ // Ignore stepDown errors on force shutdown.
+ log() << "Error stepping down during force shutdown " << e.toStatus();
+ }
+
+ // Even if the ReplicationCoordinator failed to step down, ensure we still shut down the
+ // TransactionCoordinatorService (see SERVER-45009)
+ TransactionCoordinatorService::get(opCtx)->onStepDown();
+ }
+ return Status::OK();
+}
+
namespace {
class CmdShutdownMongoD : public CmdShutdown {
@@ -61,14 +90,7 @@ public:
timeoutSecs = cmdObj["timeoutSecs"].numberLong();
}
- try {
- repl::ReplicationCoordinator::get(opCtx)->stepDown(
- opCtx, force, Seconds(timeoutSecs), Seconds(120));
- } catch (const DBException& e) {
- if (e.code() != ErrorCodes::NotMaster) { // ignore not master
- throw;
- }
- }
+ uassertStatusOK(stepDownForShutdown(opCtx, Seconds(timeoutSecs), force));
// Never returns
shutdownHelper(cmdObj);
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index 4d20f50a16f..4cbafa15ee9 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -62,6 +62,7 @@
#include "mongo/db/clientcursor.h"
#include "mongo/db/commands/feature_compatibility_version.h"
#include "mongo/db/commands/feature_compatibility_version_gen.h"
+#include "mongo/db/commands/shutdown.h"
#include "mongo/db/concurrency/d_concurrency.h"
#include "mongo/db/concurrency/flow_control_ticketholder.h"
#include "mongo/db/concurrency/lock_state.h"
@@ -928,26 +929,12 @@ void shutdownTask(const ShutdownTaskArgs& shutdownArgs) {
opCtx = uniqueOpCtx.get();
}
- // If this is a single node replica set, then we don't have to wait
- // for any secondaries. Ignore stepdown.
- if (repl::ReplicationCoordinator::get(serviceContext)->getConfig().getNumMembers() != 1) {
- try {
- // For faster tests, we allow a short wait time with setParameter.
- auto waitTime = repl::waitForStepDownOnNonCommandShutdown.load()
- ? Milliseconds(Seconds(10))
- : Milliseconds(100);
- replCoord->stepDown(opCtx, false /* force */, waitTime, Seconds(120));
- } catch (const ExceptionFor<ErrorCodes::NotMaster>&) {
- // ignore not master errors
- } catch (const DBException& e) {
- log() << "Failed to stepDown in non-command initiated shutdown path "
- << e.toString();
- }
-
- // Even if the replCoordinator failed to step down, ensure we still shut down the
- // TransactionCoordinatorService (see SERVER-45009)
- TransactionCoordinatorService::get(serviceContext)->onStepDown();
- }
+ // For faster tests, we allow a short wait time with setParameter.
+ auto waitTime = repl::waitForStepDownOnNonCommandShutdown.load() ? Milliseconds(Seconds(10))
+ : Milliseconds(100);
+ const auto forceShutdown = true;
+ // stepDown should never return an error during force shutdown.
+ invariant(stepDownForShutdown(opCtx, waitTime, forceShutdown).isOK());
}
WaitForMajorityService::get(serviceContext).shutDown();