FAQ: Concurrency常见问题解答:并发

On this page本页内容

MongoDB allows multiple clients to read and write the same data. MongoDB允许多个客户端读写相同的数据。In order to ensure consistency, it uses locking and other concurrency control measures to prevent multiple clients from modifying the same piece of data simultaneously. 为了确保一致性,它使用锁定和其他并发控制措施来防止多个客户端同时修改同一段数据。Together, these mechanisms guarantee that all writes to a single document occur either in full or not at all and that clients never see an inconsistent view of the data.总之,这些机制保证了对单个文档的所有写入要么全部发生,要么根本不发生,而且客户端永远不会看到不一致的数据视图。

What type of locking does MongoDB use?MongoDB使用什么类型的锁定?

MongoDB uses multi-granularity locking [1] that allows operations to lock at the global, database or collection level, and allows for individual storage engines to implement their own concurrency control below the collection level (e.g., at the document-level in WiredTiger).MongoDB使用多粒度锁定[1],允许操作在全局、数据库或集合级别进行锁定,并允许单个存储引擎在集合级别以下(例如WiredTiger中的文档级别)实现自己的并发控制。

MongoDB uses reader-writer locks that allow concurrent readers shared access to a resource, such as a database or collection.MongoDB使用读写器锁,允许并发读写器共享访问资源,如数据库或集合。

In addition to a shared (S) locking mode for reads and an exclusive (X) locking mode for write operations, intent shared (IS) and intent exclusive (IX) modes indicate an intent to read or write a resource using a finer granularity lock. 除了用于读取的共享(S)锁定模式和用于写入操作的排他(X)锁定模式外,意图共享(IS)和意图排他(IX)模式还指示使用更细粒度锁读取或写入资源的意图。 When locking at a certain granularity, all higher levels are locked using an intent lock.当以特定粒度锁定时,所有更高级别都会使用意向锁锁定。

For example, when locking a collection for writing (using mode X), both the corresponding database lock and the global lock must be locked in intent exclusive (IX) mode. 例如,当锁定一个集合进行写入(使用模式X)时,相应的数据库锁和全局锁都必须在intent exclusive(IX)模式下锁定。A single database can simultaneously be locked in IS and IX mode, but an exclusive (X) lock cannot coexist with any other modes, and a shared (S) lock can only coexists with intent shared (IS) locks.单个数据库可以在IS和IX模式下同时锁定,但独占(X)锁不能与任何其他模式共存,共享(S)锁只能与意图共享(IS)锁共存。

Locks are fair, with reads and writes being queued in order. 锁是公平的,读写按顺序排队。However, to optimize throughput, when one request is granted, all other compatible requests will be granted at the same time, potentially releasing them before a conflicting request. 然而,为了优化吞吐量,当一个请求被授予时,所有其他兼容的请求将同时被授予,这可能会在冲突请求之前释放它们。 For example, consider a case in which an X lock was just released, and in which the conflict queue contains the following items:例如,考虑一个X锁刚刚被释放的情况,其中冲突队列包含以下项:

IS → IS → X → X → S → IS

In strict first-in, first-out (FIFO) ordering, only the first two IS modes would be granted. 在严格的先进先出(FIFO)排序中,只允许前两种IS模式。Instead MongoDB will actually grant all IS and S modes, and once they all drain, it will grant X, even if new IS or S requests have been queued in the meantime. 相反,MongoDB实际上将授予所有IS和S模式,一旦它们全部耗尽,它将授予X,即使同时新的IS或S请求已排队。As a grant will always move all other requests ahead in the queue, no starvation of any request is possible.由于授权总是将队列中的所有其他请求向前移动,因此任何请求都不可能被饿死。

In db.serverStatus() and db.currentOp() output, the lock modes are represented as follows:db.serverStatus()db.currentOp()输出中,锁定模式表示如下:

Lock ModeDescription描述
R Represents Shared (S) lock.
W Represents Exclusive (X) lock.
r Represents Intent Shared (IS) lock.
w Represents Intent Exclusive (IX) lock.
[1]See the Wikipedia page on Multiple granularity locking for more information.有关更多信息,请参阅维基百科多粒度锁定页面

How granular are locks in MongoDB?MongoDB中的锁粒度如何?

For most read and write operations, WiredTiger uses optimistic concurrency control. 对于大多数读写操作,WiredTiger使用乐观并发控制。WiredTiger uses only intent locks at the global, database and collection levels. WiredTiger仅在全局、数据库和收集级别使用意向锁。When the storage engine detects conflicts between two operations, one will incur a write conflict causing MongoDB to transparently retry that operation.当存储引擎检测到两个操作之间存在冲突时,其中一个操作将引发写入冲突,导致MongoDB透明地重试该操作。

Some global operations, typically short lived operations involving multiple databases, still require a global “instance-wide” lock. 一些全局操作(通常是涉及多个数据库的短期操作)仍然需要全局“实例范围”锁。Some other operations, such as collMod, still require an exclusive database lock.其他一些操作,例如collMod,仍然需要独占数据库锁。

How do I see the status of locks on my mongod instances?如何查看mongod实例上锁的状态?

For reporting on lock utilization information on locks, use any of the following methods:要报告锁的锁利用率信息,请使用以下任一方法:

Specifically, the locks document in the output of serverStatus, or the locks field in the current operation reporting provides insight into the type of locks and amount of lock contention in your mongod instance.具体来说,serverStatus输出中的locks文档或当前操作报告中的locks字段提供了对mongod实例中锁类型和锁争用量的深入了解。

In db.serverStatus() and db.currentOp() output, the lock modes are represented as follows:db.serverStatus()db.currentOp()输出中,锁定模式表示如下:

Lock Mode锁定模式Description描述
R Represents Shared (S) lock.表示共享锁。
W Represents Exclusive (X) lock.表示独占(X)锁。
r Represents Intent Shared (IS) lock.表示意图共享(IS)锁。
w Represents Intent Exclusive (IX) lock.表示意图独占(IX)锁。

To terminate an operation, use db.killOp().要终止操作,请使用db.killOp()

Does a read or write operation ever yield the lock?读或写操作是否会产生锁?

In some situations, read and write operations can yield their locks.在某些情况下,读写操作可能会产生锁。

Long running read and write operations, such as queries, updates, and deletes, yield under many conditions. 长时间运行的读写操作,如查询、更新和删除,在许多情况下都会产生错误。 MongoDB operations can also yield locks between individual document modifications in write operations that affect multiple documents like update() with the multi parameter.MongoDB操作还可以在写入操作中的单个文档修改之间产生锁,这些操作会影响多个文档,比如带有multi参数的update()

For storage engines supporting document level concurrency control, such as WiredTiger, yielding is not necessary when accessing storage as the intent locks, held at the global, database and collection level, do not block other readers and writers. 对于支持文档级并发控制的存储引擎,例如WiredTiger,在访问存储时不需要让步,因为全局、数据库和集合级别的意图锁不会阻止其他读写器。However, operations will periodically yield, such as:然而,运营将定期产生收益,例如:

What locks are taken by some common client operations?一些常见的客户端操作使用了哪些锁?

The following table lists some operations and the types of locks they use for document level locking storage engines:下表列出了文档级锁定存储引擎使用的一些操作和锁定类型:

Operation操作Database数据库Collection集合
Issue a query发问 r (Intent Shared) r (Intent Shared)
Insert data插入数据 w (Intent Exclusive) w (Intent Exclusive)
Remove data删除数据 w (Intent Exclusive) w (Intent Exclusive)
Update data更新数据 w (Intent Exclusive) w (Intent Exclusive)
Perform Aggregation执行聚合 r (Intent Shared) r (Intent Shared)
Create an index (Foreground)创建索引(前台) W (Exclusive)  
Create an index (Background)创建索引(背景) w (Intent Exclusive) w (Intent Exclusive)
List collections列出集合

r (Intent Shared)

Changed in version 4.0.在版本4.0中更改。

 
Map-reduce W (Exclusive) and R (Shared) w (Intent Exclusive) and r (Intent Shared)

Which administrative commands lock the database?哪些管理命令锁定数据库?

Certain administrative commands can exclusively lock the database for extended periods of time. 某些管理命令可以长时间以独占方式锁定数据库。In some deployments, for large databases, you may consider taking the mongod instance offline so that clients are not affected. 在一些部署中,对于大型数据库,可以考虑将mongod实例离线,这样客户端不会受到影响。For example, if a mongod is part of a replica set, take the mongod offline and let other members of the set service load while maintenance is in progress.例如,如果mongod副本集的一部分,请将mongod脱机,并在维护过程中让该集的其他成员加载服务。

The following administrative operations require an exclusive lock at the database level for extended periods:以下管理操作需要在数据库级别进行长时间的独占锁定:

Operation操作 
cloneCollectionAsCapped  
collMod  
compact  
convertToCapped  

Changed in version 4.2.

If renaming a collection within the same database, the operation takes an exclusive (W) lock on the source and target collections. 如果重命名同一数据库中的集合,该操作将对源集合和目标集合进行独占(W)锁定。Prior to MongoDB 4.2, the operation takes an exclusive (W) lock on the database when renaming within the same database.在MongoDB 4.2之前,当在同一数据库中重命名时,该操作会对数据库进行独占(W)锁定。

(renameCollection only) If the target namespace is in a different database as the source collection, the locking behavior is version dependent:如果目标命名空间与源集合位于不同的数据库中,则锁定行为取决于版本:

  • (MongoDB 4.2.2 and later) The operation takes an exclusive (W) lock on the target database when renaming a collection across databases and blocks other operations on that database until it finishes.在跨数据库重命名集合时,该操作会对目标数据库进行独占(W)锁定,并在完成之前阻止该数据库上的其他操作。
  • (MongoDB 4.2.1 and earlier) The operation takes a global exclusive (W) lock when renaming a collection across databases and blocks other operations until it finishes.在跨数据库重命名集合时,该操作将使用全局独占(W)锁,并在完成之前阻止其他操作。

The following administrative operations lock the database but only hold the lock for a very short time:以下管理操作将锁定数据库,但仅在很短的时间内保持锁定:

Operation操作 
 
 

Which administrative commands lock a collection?哪些管理命令锁定集合?

Changed in version 4.2.在版本4.2中更改。

The following administrative operations require an exclusive lock at the collection level:以下管理操作需要集合级别的独占锁:

Operation操作 
 
 
 
 

Changed in version 4.2.在版本4.2中更改。

If renaming a collection within the same database, the operation takes an exclusive (W) lock on the source and target collections. 如果重命名同一数据库中的集合,该操作将对源集合和目标集合进行独占(W)锁定。Prior to MongoDB 4.2, the operation takes an exclusive (W) lock on the database when renaming within the same database.在MongoDB 4.2之前,当在同一数据库中重命名时,该操作会对数据库进行独占(W)锁定。

(renameCollection only) If the target namespace is in a different database as the source collection, the locking behavior is version dependent:如果目标命名空间与源集合位于不同的数据库中,则锁定行为取决于版本:

  • MongoDB 4.2.2 and later The operation takes an exclusive (W) lock on the target database when renaming a collection across databases and blocks other operations on that database until it finishes.在跨数据库重命名集合时,该操作会对目标数据库进行独占(W)锁定,并在完成之前阻止该数据库上的其他操作。
  • MongoDB 4.2.1 and earlier The operation takes a global exclusive (W) lock when renaming a collection across databases and blocks other operations until it finishes.在跨数据库重命名集合时,该操作将使用全局独占(W)锁,并在完成之前阻止其他操作。

Changed in version 4.2.

  • For MongoDB 4.2.2 and later, these operations obtain an exclusive (W) lock on the collection and block other operations on the collection until finished.对于MongoDB 4.2.2及更高版本,这些操作在集合上获得独占(W)锁,并阻止集合上的其他操作,直到完成。
  • For MongoDB 4.0.0 through 4.2.1, these operations take a global exclusive (W) lock and block other operations until finished.对于MongoDB 4.0.0到4.2.1,这些操作使用全局独占(W)锁并阻止其他操作,直到完成。
replSetResizeOplog

Changed in version 4.2.在版本4.2中更改。

  • For MongoDB 4.2.2 and later, this operation takes an exclusive (W) lock on the oplog collection and blocks other operations on the collection until it finishes.对于MongoDB 4.2.2及更高版本,此操作会对oplog集合进行独占(W)锁定,并阻止集合上的其他操作,直到完成为止。
  • For MongoDB 4.2.1 and earlier, this operation takes a global exclusive (W) lock and blocks other operations until it finishes.对于MongoDB 4.2.1及更早版本,此操作将使用全局独占(W)锁并阻止其他操作,直到完成。

Prior to MongoDB 4.2, these operations took an exclusive lock on the database, blocking all operations on the database and its collections until the operation completed.在MongoDB 4.2之前,这些操作对数据库进行了独占锁定,在操作完成之前阻止了对数据库及其集合的所有操作。

Does a MongoDB operation ever lock more than one database?MongoDB操作是否锁定过多个数据库?

The following MongoDB operations may obtain and hold a lock on more than one database:以下MongoDB操作可能会获取并锁定多个数据库:

Operation操作 
db.copyDatabase() This operation obtains a global (W) exclusive lock and blocks other operations until it finishes.此操作获得全局(W)独占锁,并阻止其他操作,直到完成。

Changed in version 4.2.在版本4.2中更改。

For MongoDB 4.0.0 through 4.2.1, these operations take a global exclusive (W) lock and block other operations until finished.对于MongoDB 4.0.0到4.2.1,这些操作使用全局独占(W)锁并阻止其他操作,直到完成。

Starting in MongoDB 4.2.2, these operations only obtain an exclusive (W) collection lock instead of a global exclusive lock.从MongoDB 4.2.2开始,这些操作只获得独占(W)集合锁,而不是全局独占锁。

Prior to MongoDB 4.0, these operations obtained an exclusive (W) database lock.在MongoDB 4.0之前,这些操作获得了独占(W)数据库锁。

renameCollection

Changed in version 4.2.

For MongoDB 4.2.1 and earlier, this operation obtains a global exclusive (W) lock when renaming a collection between databases and blocks other operations until finished.对于MongoDB 4.2.1及更早版本,在数据库之间重命名集合时,此操作将获得全局独占(W)锁,并阻止其他操作,直到完成。

Starting in MongoDB 4.2.2, this operation only obtains an exclusive (W) lock on the target database, an intent shared (r) lock on the source database, and a shared (S) lock on the source collection instead of a global exclusive lock.从MongoDB 4.2.2开始,此操作仅获取目标数据库上的独占(W)锁、源数据库上的意图共享(r)锁和源集合上的共享(S)锁,而不是全局独占锁。

Changed in version 4.2.

For MongoDB 4.2.1 and earlier, this operation obtains a global exclusive (W) lock and blocks other operations until finished.对于MongoDB 4.2.1及更早版本,此操作将获得全局独占(W)锁,并在完成之前阻止其他操作。

Starting in MongoDB 4.2.2, this operation only obtains an exclusive (W) lock on the oplog collection instead of a global exclusive lock.从MongoDB 4.2.2开始,此操作仅获取oplog集合上的独占(W)锁,而不是全局独占锁。

How does sharding affect concurrency?切分如何影响并发性?

Sharding improves concurrency by distributing collections over multiple mongod instances, allowing shard servers (i.e. mongos processes) to perform any number of operations concurrently to the various downstream mongod instances.分片通过在多个mongod实例上分发集合来提高并发性,允许分片服务器(即mongos进程)对各个下游mongod实例同时执行任意数量的操作。

In a sharded cluster, locks apply to each individual shard, not to the whole cluster; i.e. each mongod instance is independent of the others in the sharded cluster and uses its own locks. 在分片集群中,锁应用于每个分片,而不是整个集群;即,每个mongod实例都独立于分片集群中的其他实例,并使用自己的The operations on one mongod instance do not block the operations on any others.一个mongod实例上的操作不会阻止任何其他实例上的操作。

How does concurrency affect a replica set primary?并发性如何影响副本集主服务器?

With replica sets, when MongoDB writes to a collection on the primary, MongoDB also writes to the primary’s oplog, which is a special collection in the local database. 对于副本集,当MongoDB写入主服务器上的集合时,MongoDB还会写入主服务器的oplog,这是本地数据库中的一个特殊集合。Therefore, MongoDB must lock both the collection’s database and the local database. 因此,MongoDB必须同时锁定集合的数据库和local数据库。The mongod must lock both databases at the same time to keep the database consistent and ensure that write operations, even with replication, are “all-or-nothing” operations.mongod必须同时锁定这两个数据库,以保持数据库的一致性,并确保写操作(即使是复制操作)是“要么全有,要么全无”的操作。

When writing to a replica set, the lock’s scope applies to the primary.写入副本集时,锁的作用域将应用于主设备

How does concurrency affect secondaries?并发性如何影响二级数据库?

In replication, MongoDB does not apply writes serially to secondaries. 复制中,MongoDB不会将写操作串行地应用于辅助设备Secondaries collect oplog entries in batches and then apply those batches in parallel. 二级数据库分批收集oplog条目,然后并行应用这些批。Writes are applied in the order that they appear in the oplog.写入将按照它们在oplog中出现的顺序应用。

Starting in MongoDB 4.0, reads which target secondaries read from a WiredTiger snapshot of the data if the secondary is undergoing replication. 从MongoDB 4.0开始,读取从数据的WiredTiger快照中读取的目标辅助设备(如果辅助设备正在进行复制)。This allows the read to occur simultaneously with replication, while still guaranteeing a consistent view of the data. 这允许读取与复制同时发生,同时仍然保证数据的一致性。Previous to MongoDB 4.0, read operations on secondaries would be blocked until any ongoing replication completes. 在MongoDB 4.0之前,在任何正在进行的复制完成之前,二级数据库上的读取操作都将被阻止。See Multithreaded Replication for more information.有关更多信息,请参阅多线程复制

Does MongoDB support transactions?MongoDB支持事务吗?

Because a single document can contain related data that would otherwise be modeled across separate parent-child tables in a relational schema, MongoDB’s atomic single-document operations already provide transaction semantics that meet the data integrity needs of the majority of applications. 由于单个文档可以包含相关数据,否则这些数据将在关系模式中的独立父子表中建模,因此MongoDB的原子单文档操作已经提供了满足大多数应用程序数据完整性需求的事务语义。One or more fields may be written in a single operation, including updates to multiple sub-documents and elements of an array. 可以在单个操作中写入一个或多个字段,包括对多个子文档和数组元素的更新。The guarantees provided by MongoDB ensure complete isolation as a document is updated; any errors cause the operation to roll back so that clients receive a consistent view of the document.MongoDB提供的保证确保文件更新时完全隔离;任何错误都会导致操作回滚,以便客户端收到文档的一致视图。

However, for situations that require atomicity of reads and writes to multiple documents (in a single or multiple collections), MongoDB supports multi-document transactions:但是,对于需要对多个文档(在单个或多个集合中)进行原子性读写的情况,MongoDB支持多文档事务:

Important

In most cases, multi-document transaction incurs a greater performance cost over single document writes, and the availability of multi-document transactions should not be a replacement for effective schema design. 在大多数情况下,与单文档写入相比,多文档事务会带来更大的性能成本,而多文档事务的可用性不应取代有效的模式设计。For many scenarios, the denormalized data model (embedded documents and arrays) will continue to be optimal for your data and use cases. 对于许多场景,非规范化数据模型(嵌入式文档和数组)将继续适合您的数据和用例。That is, for many scenarios, modeling your data appropriately will minimize the need for multi-document transactions.也就是说,对于许多场景,适当地建模数据将最大限度地减少对多文档事务的需求。

For additional transactions usage considerations (such as runtime limit and oplog size limit), see also Production Considerations.有关其他事务使用注意事项(如运行时限制和oplog大小限制),请参阅生产注意事项

What isolation guarantees does MongoDB provide?MongoDB提供了哪些隔离保证?

Depending on the read concern, clients can see the results of writes before the writes are durable. 根据读关注点的不同,客户端可以在写入持久之前查看写入的结果。To control whether the data read may be rolled back or not, clients can use the readConcern option.为了控制读取的数据是否可以回滚,客户端可以使用readConcern选项。

For information, see:有关信息,请参阅: