Reputation: 1545
I'm atrying to kill an aggregation operation on a sharded cluster programatically. The operation is launched from Java mongo driver,
The way I've found to kill it is throw a killSessions command with the session identifier.
What I do to properly get the sessions identifier is:
MongoClient mongoClient = ....
mongoClient.startSession()
//call the aggregation stuff..
This thread keeps running, and from another thread, I use the mongoClient object to get the server session and kill it:
BsonDocument serverSession = clientSession.getServerSession().getIdentifier();
BsonBinary value = serverSession.get("id").asBinary();
Then I wrap value
inside a singleton collection of document [{ id: value}]
and call $killsessions
with this parameter. I run it on top of the mongo admin db.
The result returns me { ok: 1.0 }
, but the thread with the operation still keeps running and ends properly on the server The result of the aggregation is written to a new collection on stage $out
, so it seems it has no effect on the server session.
How can I kill, programatically, all the operations running on the aggregation? (both client & server side).
Upvotes: 2
Views: 921
Reputation: 1545
Since I needed it to kill long running processes, my solution was to use the following command to univocally identify the session to kill
db.adminCommand({"currentOp": true, "secs_running": {$gte: 100}})
get the id from the result (asumming inprog
contains only 1 operation in progress because there's no more operation running for more than 100 seconds,
{ "inprog": [{ "lsid": {here_is_the_session_id}, otherFields...}, otherInProgOps...], otherFields....}
and then pass the lsid
field (which contains id
and uid
) to killSessions
:
b.adminCommand( { killSessions: [ {here_goes_lsid} ] } )
For a more confident method to get the sessionId other fields of the inprog
array can be checked
Upvotes: 1
Reputation: 14490
killSessions works in my testing: regular find, aggregation.
Ensure you are killing the session that is used in the operation, ensure the operation is running when you kill the session (you can kill the session prior to the operation starting which will be a no-op), ensure you pass the session in properly.
If you still have trouble provide a reproducible code sample.
killSessions does not return anything hence as far as I can tell there's no way to tell if it actually did anything. But the server logs when it kills operations. 4.4 logs:
{"t":{"$date":"2020-06-16T15:55:06.872-04:00"},"s":"I", "c":"QUERY", "id":20528, "ctx":"threa
d60247","msg":"Killing cursor as part of killing session(s)","attr":{"cursorId":7290821057815339751
}}
{"t":{"$date":"2020-06-16T16:01:29.350-04:00"},"s":"I", "c":"COMMAND", "id":20706, "ctx":"thread60247","msg":"Killing op as part of killing session","attr":{"opId":18212677,"lsid":{"id":{"$uuid":"8f5474a5-8001-469b-87d4-692563f2dc0e"},"uid":{"$binary":{"base64":"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=","subType":"0"}}}}}
Upvotes: 0
Reputation: 22296
Once you start a pipeline it is running on your Mongo's process. sessions
are a way to guarantee consistency with read/write operations. not a way to kill running queries.
You want to use killOp, get the operation id using currentOp.
Upvotes: 1