In this recipe, we will see how to view the current running operations and kill some operations that are running for a long time.
We will simulate some operations on a standalone mongo instance. We need to start a standalone server listening to any port for client connections; in this case, we will stick to the default 27017
. If you are not aware how to start a standalone server, refer to Installing single node MongoDB in Chapter 1, Installing and Starting the Server. We also need to start two shells connected to the server started. One shell would be used for background index creation and another would be used to monitor the current operation and then kill it.
> db.currentOpTest.drop() > for(i = 1 ; i < 10000000 ; i++) { db.currentOpTest.insert({'i':i})}
The preceding insertion might take some time to insert 10 million documents.
i
in the document. This index creation operation is what we will be viewing from the currentOp
operation and is what we will attempt to kill from using the kill operation. Execute the following in one shell to initiate the background index creation operation. This takes fairly long time and on my laptop it took well over 100 seconds.> db.currentOpTest.ensureIndex({i:1}, {background:1})
> db.currentOp().inprog
system.indexes
and the operation will be insert. The keys to lookout for in the output document are ns
and op
, respectively. We need to note the first field of this operation, opid
. In this case, it is 11587458
. The sample output of the command is given in next section.opid
(operation ID) we got earlier:> db.killOp(11587458)
We will split our explanation into two sections, the first about the current operation details and second about killing the operation.
In our case, index creation process is the long-running operation that we intend to kill. We create a big collection with about 10 million documents and initiate a background index creation process.
On executing the db.currentOp()
operation, we get a document as the result with a field inprog
whose value is an array of other documents each representing a currently running operation. It is common to get a big list of documents on a busy system. Here is a document taken for the index creation operation:
{ "desc" : "conn12", "threadId" : "0x3be96c0", "connectionId" : 12, "opid" : 3212789, "active" : true, "secs_running" : 1, "microsecs_running" : NumberLong(729029), "op" : "query", "ns" : "test.$cmd", "query" : { "createIndexes" : "currentOpTest", "indexes" : [ { "key" : { "i" : 1 }, "name" : "i_1", "background" : 1 } ] }, "client" : "127.0.0.1:36542", "msg" : "Index Build (background) Index Build (background): 384120/1000000 38%", "progress" : { "done" : 384120, "total" : 1000000 }, "numYields" : 3003, "locks" : { "Global" : "w", "MMAPV1Journal" : "w", "Database" : "w", "Collection" : "W" "waitingForLock" : true, "lockStats" : { "Global" : { "acquireCount" : { "w" : NumberLong(3004) } }, "MMAPV1Journal" : { "acquireCount" : { "w" : NumberLong(387127) }, "acquireWaitCount" : { "w" : NumberLong(9) }, "timeAcquiringMicros" : { "w" : NumberLong(60025) } }, "Database" : { "acquireCount" : { "w" : NumberLong(3004), "W" : NumberLong(1) } }, "Collection" : { "acquireCount" : { "W" : NumberLong(3004) }, "acquireWaitCount" : { "W" : NumberLong(1) }, "timeAcquiringMicros" : { "W" : NumberLong(66) } }, "Metadata" : { "acquireCount" : { "W" : NumberLong(4) } } } }
We will see what these fields mean in the following table:
currentOp
function call as follows:> db.currentOp(true)
killOp
function. The operation is simply called as follows:> db.killOp(<operation id>)
In our case, the index creation process had the process ID 11587458 and thus it will be killed as follows:
> db.killOp(11587458)
On killing any operation, irrespective of whether the given operation ID exists or not, we see the following message on the console:
{ "info" : "attempting to kill op" }
Thus, seeing this message doesn't mean that the operation was killed. It just means that the operation if it exists will be attempted to be killed.
killOp
command is issued for it, the field killPending
in the currentOp
will start appearing for the given operation. For example, execute the following query on the shell:> db.currentOpTest.find({$where:'sleep(100000)'})
This will not return and the thread executing the query will sleep for 100 seconds. This is an operation that cannot be killed using killOp
. Try executing the command currentOp
from another shell (do not press Tab for auto completion, your shell may just hang), get the operation ID, and then kill it using the killOp
. You should see that the process still would be running if you execute the currentOp
command, but the document for the process details will now contain a new key killPending
stating that the kill for this operation is requested but pending.