diff options
author | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2018-12-27 14:37:48 -0500 |
---|---|---|
committer | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2018-12-27 14:37:48 -0500 |
commit | 7b72db38ae0121b3df3ac2f5bcbe6ea446ead3cb (patch) | |
tree | fcf372bdb0954f50f38a6ca6abe8d2bb5dba2339 /jstests/hooks | |
parent | 07ba0c29a19d9648cc913927ecbbbe6240532576 (diff) | |
download | mongo-7b72db38ae0121b3df3ac2f5bcbe6ea446ead3cb.tar.gz |
SERVER-38182 Avoid calling abortTransaction() after txn committed.
Diffstat (limited to 'jstests/hooks')
-rw-r--r-- | jstests/hooks/run_check_repl_dbhash_background.js | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/jstests/hooks/run_check_repl_dbhash_background.js b/jstests/hooks/run_check_repl_dbhash_background.js index 864f13a0945..5f4be783182 100644 --- a/jstests/hooks/run_check_repl_dbhash_background.js +++ b/jstests/hooks/run_check_repl_dbhash_background.js @@ -235,10 +235,23 @@ }; for (let dbName of dbNames) { + let result; + let clusterTime; let hasTransientError; + // The isTransientError() function is responsible for setting hasTransientError to true. + const isTransientError = (e) => { + if (e.hasOwnProperty('errorLabels') && + e.errorLabels.includes('TransientTransactionError')) { + hasTransientError = true; + return true; + } + + return false; + }; + do { - const clusterTime = sessions[0].getOperationTime(); + clusterTime = sessions[0].getOperationTime(); waitForSecondaries(clusterTime); for (let session of sessions) { @@ -246,44 +259,43 @@ {readConcern: {level: 'snapshot', atClusterTime: clusterTime}}); } - let commitErrorSessionId = undefined; hasTransientError = false; try { - const result = checkCollectionHashesForDB(dbName); - - for (let session of sessions) { - // commitTransaction() calls assert.commandWorked(), which may fail with a - // WriteConflict error response, which is ignored. - try { - session.commitTransaction(); - } catch (e) { - commitErrorSessionId = session.getSessionId(); - throw e; - } - } - - for (let mismatchInfo of result) { - mismatchInfo.atClusterTime = clusterTime; - results.push(mismatchInfo); - } + result = checkCollectionHashesForDB(dbName); } catch (e) { + // We abort each of the transactions started on the nodes if one of them returns an + // error while running the dbHash check. for (let session of sessions) { - if ((commitErrorSessionId === undefined) || - bsonWoCompare(session.getSessionId(), commitErrorSessionId) !== 0) { - session.abortTransaction_forTesting(); - } + session.abortTransaction_forTesting(); } - if (e.hasOwnProperty('errorLabels') && - e.errorLabels.includes('TransientTransactionError')) { - hasTransientError = true; + if (isTransientError(e)) { continue; } throw e; } + + // We then attempt to commit each of the transactions started on the nodes to confirm + // the data we read was actually majority-committed. If one of them returns an error, + // then we still try to commit the transactions started on subsequent nodes in order to + // clear their transaction state. + for (let session of sessions) { + try { + session.commitTransaction(); + } catch (e) { + if (!isTransientError(e)) { + throw e; + } + } + } } while (hasTransientError); + + for (let mismatchInfo of result) { + mismatchInfo.atClusterTime = clusterTime; + results.push(mismatchInfo); + } } for (let resetFn of resetFns) { |