mongo/jstests/libs/override_methods/implicitly_retry_resharding.js

61 lines
1.9 KiB
JavaScript

/**
* Overrides runCommand to retry "reshardCollection", "rewriteCollection", "moveCollection", and "unshardCollection"
* commands if they fail with retryable error codes.
*
* Errors like OplogQueryMinTsMissing, SnapshotUnavailable, and SnapshotTooOld can occur when
* initial sync runs concurrently with resharding, since initial sync does not maintain pinned history.
*/
import {getCommandName} from "jstests/libs/cmd_object_utils.js";
import {OverrideHelpers} from "jstests/libs/override_methods/override_helpers.js";
const kTimeout = 20 * 60 * 1000;
const kInterval = 100;
const kRetryableCommands = ["reshardCollection", "rewriteCollection", "moveCollection", "unshardCollection"];
const kRetryableErrorCodes = [
ErrorCodes.OplogQueryMinTsMissing,
ErrorCodes.SnapshotUnavailable,
ErrorCodes.SnapshotTooOld,
];
function isRetryableOplogOrSnapshotError(cmdObj, res) {
const commandName = getCommandName(cmdObj);
if (!kRetryableCommands.includes(commandName)) {
return false;
}
if (res && kRetryableErrorCodes.includes(res.code)) {
return true;
}
return false;
}
function runCommandWithRetries(conn, dbName, cmdName, cmdObj, func, makeFuncArgs) {
let res;
let attempt = 0;
assert.soon(
() => {
attempt++;
res = func.apply(conn, makeFuncArgs(cmdObj));
if (isRetryableOplogOrSnapshotError(cmdObj, res)) {
jsTest.log(`Retrying ${cmdName} due to error: ${tojson(res)}. Attempt: ${attempt}`);
return false; // Retry.
}
return true; // Not retry.
},
() => "Timed out while retrying command '" + tojson(cmdObj) + "', response: " + tojson(res),
kTimeout,
kInterval,
);
return res;
}
OverrideHelpers.prependOverrideInParallelShell("jstests/libs/override_methods/implicitly_retry_resharding.js");
OverrideHelpers.overrideRunCommand(runCommandWithRetries);