@@ -31,6 +31,10 @@ if (typeof db === 'undefined') {
31
31
TestData = TestData || { } ;
32
32
TestData . traceExceptions = false ;
33
33
34
+ // Disable implicit sessions so FSM workloads that kill random sessions won't interrupt the
35
+ // operations in this test that aren't resilient to interruptions.
36
+ TestData . disableImplicitSessions = true ;
37
+
34
38
const conn = db . getMongo ( ) ;
35
39
const topology = DiscoverTopology . findConnectedNodes ( conn ) ;
36
40
@@ -78,35 +82,40 @@ function checkReplDbhashBackgroundThread(hosts) {
78
82
// We enable the "WTPreserveSnapshotHistoryIndefinitely" failpoint to ensure that the same
79
83
// snapshot will be available to read at on the primary and secondaries.
80
84
for ( let session of sessions ) {
81
- const db = session . getDatabase ( 'admin' ) ;
85
+ // Use the session's client directly so FSM workloads that kill random sessions won't
86
+ // interrupt these operations.
87
+ const dbNoSession = session . getClient ( ) . getDB ( 'admin' ) ;
82
88
83
- let preserveRes = assert . commandWorked ( db . runCommand ( {
89
+ let preserveRes = assert . commandWorked ( dbNoSession . runCommand ( {
84
90
configureFailPoint : 'WTPreserveSnapshotHistoryIndefinitely' ,
85
91
mode : 'alwaysOn' ,
86
92
} ) ,
87
93
debugInfo ) ;
88
94
debugInfo . push ( {
89
- "node" : db . getMongo ( ) ,
95
+ "node" : dbNoSession . getMongo ( ) ,
90
96
"session" : session ,
91
97
"preserveFailPointOpTime" : preserveRes [ 'operationTime' ]
92
98
} ) ;
93
99
94
100
resetFns . push ( ( ) => {
95
- assert . commandWorked ( db . runCommand ( {
101
+ assert . commandWorked ( dbNoSession . runCommand ( {
96
102
configureFailPoint : 'WTPreserveSnapshotHistoryIndefinitely' ,
97
103
mode : 'off' ,
98
104
} ) ) ;
99
105
} ) ;
100
106
}
101
107
102
108
for ( let session of sessions ) {
103
- const db = session . getDatabase ( 'admin' ) ;
104
- const res = assert . commandWorked ( db . runCommand ( { listDatabases : 1 , nameOnly : true } ) ) ;
109
+ // Use the session's client directly so FSM workloads that kill random sessions won't
110
+ // interrupt these operations.
111
+ const dbNoSession = session . getClient ( ) . getDB ( 'admin' ) ;
112
+ const res =
113
+ assert . commandWorked ( dbNoSession . runCommand ( { listDatabases : 1 , nameOnly : true } ) ) ;
105
114
for ( let dbInfo of res . databases ) {
106
115
dbNames . add ( dbInfo . name ) ;
107
116
}
108
117
debugInfo . push ( {
109
- "node" : db . getMongo ( ) ,
118
+ "node" : dbNoSession . getMongo ( ) ,
110
119
"session" : session ,
111
120
"listDatabaseOpTime" : res [ 'operationTime' ]
112
121
} ) ;
@@ -252,6 +261,13 @@ function checkReplDbhashBackgroundThread(hosts) {
252
261
return result ;
253
262
} ;
254
263
264
+ // Outside of checkCollectionHashesForDB(), operations in this function are not resilient to
265
+ // their session being killed by a concurrent FSM workload, so the driver sessions started above
266
+ // have not been used and will have contain null logical time values. The process for selecting
267
+ // a read timestamp below assumes each session has valid logical times, so run a dummy command
268
+ // through each session to populate its logical times.
269
+ sessions . forEach ( session => session . getDatabase ( 'admin' ) . runCommand ( { ping : 1 } ) ) ;
270
+
255
271
for ( let dbName of dbNames ) {
256
272
let result ;
257
273
let clusterTime ;
@@ -310,32 +326,34 @@ function checkReplDbhashBackgroundThread(hosts) {
310
326
signedClusterTime = sess . getClusterTime ( ) ;
311
327
}
312
328
}
313
- waitForSecondaries ( clusterTime , signedClusterTime ) ;
314
-
315
- for ( let session of sessions ) {
316
- debugInfo . push ( {
317
- "node" : session . getClient ( ) ,
318
- "session" : session ,
319
- "readAtClusterTime" : clusterTime
320
- } ) ;
321
- }
322
329
323
330
hasTransientError = false ;
324
331
performNoopWrite = false ;
325
332
326
333
try {
334
+ waitForSecondaries ( clusterTime , signedClusterTime ) ;
335
+
336
+ for ( let session of sessions ) {
337
+ debugInfo . push ( {
338
+ "node" : session . getClient ( ) ,
339
+ "session" : session ,
340
+ "readAtClusterTime" : clusterTime
341
+ } ) ;
342
+ }
343
+
327
344
result = checkCollectionHashesForDB ( dbName , clusterTime ) ;
328
345
} catch ( e ) {
329
346
if ( isTransientError ( e ) ) {
330
347
if ( performNoopWrite ) {
331
- const primarySession = sessions [ 0 ] ;
348
+ // Use the session's client directly so FSM workloads that kill random
349
+ // sessions won't interrupt appendOplogNote.
350
+ const primaryConn = sessions [ 0 ] . getClient ( ) ;
332
351
333
352
// If the no-op write fails due to the global lock not being able to be
334
353
// acquired within 1 millisecond, retry the operation again at a later
335
354
// time.
336
355
assert . commandWorkedOrFailedWithCode (
337
- primarySession . getDatabase ( dbName ) . adminCommand (
338
- { appendOplogNote : 1 , data : { } } ) ,
356
+ primaryConn . adminCommand ( { appendOplogNote : 1 , data : { } } ) ,
339
357
ErrorCodes . LockFailed ) ;
340
358
}
341
359
0 commit comments