TableCore

Current operations

This page ends work on somebody's production server. The consequences come first.

What killing an operation actually does

`killOp` is a request, not a guarantee

  • It asks the server to stop an operation at its next interrupt point. Some operations stop immediately. Some take a while. Some cannot be interrupted at all and will finish regardless.
  • An in-flight write may be partly applied. MongoDB writes to a single document atomically, so you will not get half a document — but a multi-document write that is killed part way through has applied the documents it already reached, and there is no rollback. The same is true of an updateMany on a standalone server.
  • A killed index build stops the build. The index does not exist afterwards, and the work is lost.
  • A killed replication operation is not a local matter. Interfering with replication affects the whole set.
  • The row does not disappear when you press the button. It is marked as termination requested and goes away only when a later reading no longer shows it. Removing it optimistically would report an outcome nobody has.

The confirmation names the operation — its identifier, namespace, duration and client — and stands under the row it belongs to, because the list can be longer than the window and a confirmation you have to go looking for gets confirmed without being read. Index builds and replication operations get their own sentence, because they cost something different from a killed slow read.

Reading the list

The list is read through the $currentOp aggregation stage rather than the currentOp command. The stage works through a mongos and can be filtered on the server; the command would mean pulling every idle connection across just to discard it here.

It is a view of the whole server, not of your own operations — the ones that are certainly not the problem.

  • Duration is read in microseconds, not seconds. Using the seconds field alone would put every sub-second operation at zero, which on a healthy server is most of them.
  • Server-internal operations are marked, never hidden. Some server versions do not report the field that distinguishes them at all, so not reported is its own state rather than no.
  • The list is refreshed every second sampler reading. A second round trip per second doubles the cost of an open panel, and an operation worth killing does not vanish in two seconds.

Filtering

The filter is a different question, not a narrowed answer: namespace, operation kind and minimum duration go to the server as pipeline conditions, and idle sessions and cursors as flags on the stage itself.

A namespace you type is quoted and anchoredshop.orders becomes ^shop\.orders. You are typing a name, not a regular expression, and an unescaped dot would match any character.

A practical filter for "what is hurting right now" is a minimum duration of a few seconds with idle sessions and cursors excluded.

Permissions

Watching and killing are separate capabilities. Being refused the right to kill does not take the list away from somebody entitled to read it — the message stands beside the list rather than replacing it.

On a sharded cluster an operation identifier arrives as a string like shard01:86018. TableCore carries it back to killOp exactly as it came: parsing it into a number would either fail or name a different operation on whichever shard happened to answer.

Before you kill anything

  1. Read the namespace and the client. A long operation on a collection you recognise, from a client you recognise, is a different decision from one you do not.
  2. Check whether it is an index build or a replication operation. Both are named in the confirmation, and both cost more than they look.
  3. Ask whether killing it fixes anything. A query that examines four hundred thousand documents to return twelve will be back in a minute. The profiler tells you which query shape it is, and indexes is where the actual fix lives.