How does concurrency work

The documentation below covers for MongoDB v2.0. v2.0 typically achieves significantly more concurrency in disk activity than v1.8 did. v2.2 will include substantial enhancements with concurrency work being by far the #1 item on the v2.2 road map.

mongos

For sharded environments, each mongos process can perform any number of operations concurrently. This results in downstream operations to mongod instances. Execution of operations at each mongod is independent; that is, one mongod does not block another.

mongod

The mongod process uses a modified reader/writer lock with dynamic yielding on page faults and long operations. Any number of concurrent read operations are allowed, but a write operation can block all other operations.

mongod threads yield their lock (read or write) in two classes of situations:

  • yield-on-page-fault – v2.0 implements a yield-on-page-fault feature which results in much more concurrency than one would achieve with a pure reader/writer lock. For common operational cases, file system page faults are detected in advanced and handled outside of any lock, then the lock is resumed. Not all fault situations yield, but many do. This results in v2.0 having much better concurrency in practice than v1.8.
  • yield-on-long-operation – mongod also yields periodically on common operations that are extremely long running. The goal here is to allow interleaving so that other operations which are quick-running can execute soon. Operations which yield include the following:
    • queries
    • multi document updates
    • multi document removes/deletes
    • bulk inserts

Write lock acquisition is greedy: a pending write lock acquisition will prevent further read lock acquisitions until fulfilled. Thus yielding by reads can be important.

Collection level locking is under development. SERVER-1240.

Viewing operations in progress

Use db.currentOp() to view operations in progress, and db.killOp() to terminate an operation.

Administrative commands and locking

Certain administrative commands can exclusively lock the mongod process for extended periods of time. Specifically, these commands block for long periods:

  • foreground index creation
  • reindex
  • compact command
  • repair database
  • creating a very large (many gigabytes) capped collection
  • validate collection command
  • lock and fsync command

On a small collection, the lock time may only be a few seconds. On very large collections, take the mongod instance offline so that clients are not effected. For example if the server is part of a replica set, let other members service load while maintenance is in progress.

The following commands are fast and will not block the system excessively:

  • dropIndex
  • getLastError
  • isMaster
  • replSetGetStatus
  • serverStatus
  • auth
  • addUser

Operations

Operation Lock type
Notes
query
read lock
yields
get more from a cursor
read lock yields
insert write lock
Inserts are normally fast and short-lived operations; exception is if the collection has many indexes and they do not fit in RAM, or if freelists are extremely long.
remove
write lock yields
update
write lock yields
map/reduce at times locked
Allows substantial concurrent operation but exclusive to other javascript execution.
create index
See notes
Default "foreground mode" building blocks for extended periods of time.
db.eval() write lock
Substantial blocking
getLastError command
non-blocking
 
serverStatus command non-blocking  

Javascript

Only one thread in the mongod process executes Javascript at a time (other database operations are often possible concurrent with this). Note ticket https://jira.mongodb.org/browse/SERVER-4258 will allow multi-threading.

Group Command

The group command takes a read lock and does not allow any other threads to execute JavaScript while it is running.

MapReduce

The mapreduce operation is composed of many small events: reads from the input collection, executions of map(), executions of reduce(), writes to the output collection, etc.

There is a javascript lock so that only one thread can execute JS code at one point in time. But most JS steps of the MR (e.g. a single map()) are very short and consequently the lock is yielded very often. Note ticket https://jira.mongodb.org/browse/SERVER-4258 will allow multi-threading.

There are also several non-JavaScript operations that MapReduce performs that take locks:

  • It reads from a collection (read lock yielded every 100 documents)
  • It inserts documents into the temporary collection (write lock for a single write)
  • It creates a final collection or merges into or replaces an existing collection (write lock)

The result is that while single-threaded, several MR jobs can be interleaved and appear to run in parallel.
Note the problematic lock can be the final write lock during post-processing, which is used to make results appear atomically. This lock can take a long time in "merge" or "reduce" output mode. A flag to disable atomicity will be added as per https://jira.mongodb.org/browse/SERVER-2581


Labels

blocking blocking Delete
concurrent concurrent Delete
locking locking Delete
concurrency concurrency Delete
multicore multicore Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

PLEASE POST QUESTIONS IN THE FORUMS: http://groups.google.com/group/mongodb-user. Post tips and clarifications here.

blog comments powered by Disqus