FAQ: Concurrency常见问题解答:并发
On this page本页内容
What type of locking does MongoDB use?MongoDB使用什么类型的锁定?How granular are locks in MongoDB?MongoDB中的锁有多细粒度?How do I see the status of locks on my如何查看mongod
instances?mongod
实例上锁的状态?Does a read or write operation ever yield the lock?读或写操作是否会产生锁?What locks are taken by some common client operations?一些常见的客户端操作使用哪些锁?Which administrative commands lock a database?哪些管理命令锁定数据库?Which administrative commands lock a collection?哪些管理命令锁定集合?Does a MongoDB operation ever lock more than one database?MongoDB操作是否锁定过多个数据库?How does sharding affect concurrency?分片如何影响并发性?How does concurrency affect a replica set primary?并发性如何影响副本集主副本集?How does concurrency affect secondaries?并发如何影响辅助设备?Does MongoDB support transactions?MongoDB支持事务吗?What isolation guarantees does MongoDB provide?MongoDB提供了哪些隔离保证?What are lock-free read operations?什么是无锁读取操作?
MongoDB allows multiple clients to read and write the same data. MongoDB允许多个客户端读取和写入相同的数据。To ensure consistency, MongoDB uses locking and concurrency control to prevent clients from modifying the same data simultaneously. 为了确保一致性,MongoDB使用锁定和并发控制来防止客户端同时修改相同的数据。Writes to a single document occur either in full or not at all, and clients always see consistent 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 coexist with intent shared (IS) locks.单个数据库可以在IS和IX模式下同时锁定,但独占(X)锁不能与任何其他模式共存,共享(S)锁只能与意向共享(IS)锁共存。
Locks are fair, with lock requests for reads and writes queued in order. However, to optimize throughput, when one lock request is granted, all other compatible lock requests are granted at the same time, potentially releasing the locks before a conflicting lock request is performed. 锁是公平的,读写的锁请求按顺序排队。然而,为了优化吞吐量,当一个锁请求被授予时,所有其他兼容的锁请求都会同时被授予,这可能会在执行冲突的锁请求之前释放锁。For example, consider a situation where an X lock was just released and the conflict queue contains these locks:例如,考虑一种情况,其中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()
输出中,锁模式表示如下:
R | |
W | |
r | |
w |
[1] | |
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
实例上锁的状态?
mongod
instances?For reporting on lock utilization information on locks, use any of these methods:要报告锁的锁利用率信息,请使用以下任意方法:
db.serverStatus()
,db.currentOp()
,mongotop
,mongostat
, and/orthe MongoDB Cloud ManagerMongoDB Cloud Manageror Ops Manager, an on-premise solution available in MongoDB Enterprise Advanced
或Ops Manager,MongoDB Enterprise Advanced
中提供的内部部署解决方案
Specifically, the 具体地说,serverStatus输出中的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.locks
文档或当前操作报告中的locks
字段可以深入了解mongod
实例中的锁类型和锁争用量。
In 在db.serverStatus()
and db.currentOp()
output, the lock modes are represented as follows:db.serverStatus()
和db.currentOp()
输出中,锁模式表示如下:
R | |
W | |
r | |
w |
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 locks under many conditions. 长时间运行的读写操作,如查询、更新和删除,在许多情况下都会产生锁。MongoDB operations can also yield locks between individual document modifications in write operations that affect multiple documents.MongoDB操作还可以在影响多个文档的写入操作中的单个文档修改之间产生锁。
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. However, operations will periodically yield, such as:对于支持文档级并发控制的存储引擎(如WiredTiger),访问存储时不需要让步,因为全局、数据库和集合级别的意向锁不会阻止其他读写器。但是,操作会周期性地产生收益,例如:
to avoid long-lived storage transactions because these can potentially require holding a large amount of data in memory;避免长期存储事务,因为这些事务可能需要在内存中保存大量数据;to serve as interruption points so that you can kill long running operations;充当中断点,这样就可以终止长时间运行的操作;to allow operations that require exclusive access to a collection such as index/collection drops and creations.以允许需要对集合进行独占访问的操作,例如索引/集合删除和创建。
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:下表列出了一些操作以及它们用于文档级锁定存储引擎的锁类型:
r | r | |
w | w | |
w | w | |
w | w | |
r | r | |
W | ||
w | w | |
r | ||
Map-reduce | W (Exclusive) and R (Shared) | w r |
Which administrative commands lock a database?哪些管理命令锁定数据库?
Some administrative commands can exclusively lock a database for extended time periods. 某些管理命令可以在较长的时间段内以独占方式锁定数据库。For large database deployments, 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 replica set process requests while maintenance is performed.mongod
是副本集的一部分,请使mongod
脱机,并让副本集的其他成员在执行维护时处理请求。
Administrative Commands Taking Extended Locks使用扩展锁的管理命令
These administrative operations require an exclusive lock at the database level for extended periods:这些管理操作需要在数据库级别进行长时间的独占锁定:
cloneCollectionAsCapped
commandcollMod
commandcompact
commandconvertToCapped
command
In addition, the 此外,renameCollection
command and corresponding db.collection.renameCollection()
shell method take the following locks depending on the version of MongoDB:renameCollection
命令和相应的db.collection.renameCollection()
shell方法根据MongoDB的版本采用以下锁:
MongoDB 4.2.2 or later | MongoDB 4.2.0 - 4.2.1 | ||
---|---|---|---|
renameCollection database command | renameCollection command takes an exclusive (W) lock on the source and target collections.renameCollection 命令将对源集合和目标集合使用独占(W)锁。renameCollection command 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.renameCollection 命令会对目标数据库执行独占(W)锁,并阻止对该数据库的其他操作,直到操作完成。
| renameCollection command takes an exclusive (W) lock on the source and target collections.renameCollection 命令将对源集合和目标集合使用独占(W)锁。renameCollection command takes a global exclusive (W) lock when renaming a collection across databases and blocks other operations until it finishes.renameCollection 命令将使用全局独占(W)锁,并阻止其他操作,直到完成为止。
| renameCollection command takes an exclusive (W) lock on the database when renaming within the same database.renameCollection 命令在同一数据库中重命名时会对数据库执行独占(W)锁定。 |
renameCollection() shell helper method | renameCollection() method takes an exclusive (W) lock on the source and target collections.renameCollection() 方法将对源集合和目标集合使用独占(W)锁。 | renameCollection() method takes an exclusive (W) lock on the database when renaming within the same database.renameCollection() 方法在同一数据库中重命名时会对数据库执行独占(W)锁。 |
Administrative Commands Taking Brief Locks使用简短锁定的管理命令
These administrative operations lock a database but only hold the lock for a very short time:这些管理操作锁定数据库,但只在很短的时间内保持锁定:
authenticate
command and correspondingdb.auth()
shell methodauthenticate
命令和相应的db.auth()
shell方法createUser
command and correspondingdb.createUser()
shell methodcreateUser
命令和相应的db.createUser()
shell方法Does a MongoDB operation ever lock more than one database?MongoDB操作是否锁定过多个数据库?
Which administrative commands lock a collection?哪些管理命令锁定集合?
Changed in version 4.2.4.2版更改。
These administrative operations require an exclusive lock at the collection level:这些管理操作需要在集合级别使用独占锁定:
create
command and correspondingdb.createCollection()
anddb.createView()
shell methodscreate
命令和相应的db.createCollection()
和db.createView()
shell方法createIndexes
command and corresponding命令和相应的db.collection.createIndex()
anddb.collection.createIndexes()
shell methodsdb.collection.createIndex()
和db.collection.createIndexes()
shell方法drop
command and correspondingdb.collection.drop()
shell methodsdrop
命令和相应的db.collection.drop()
shell方法dropIndexes
command and correspondingdb.collection.dropIndex()
anddb.collection.dropIndexes()
shell methodsdropIndexes
命令以及相应的db.collection.dropIndex()
和db.collection.dropIndexes()
shell方法therenameCollection
command and correspondingdb.collection.renameCollection()
shell method take the following locks, depending on version:renameCollection
命令和相应的db.collection.renameCollection()
shell方法根据版本采用以下锁:For对于renameCollection
and和db.collection.renameCollection()
: 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)锁定。- For
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.MongoDB 4.2.2及更高版本当跨数据库重命名集合时,该操作对目标数据库执行独占(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.MongoDB 4.2.1及更早版本该操作在跨数据库重命名集合时使用全局独占(W)锁,并阻止其他操作直到完成。
thereIndex
command and correspondingdb.collection.reIndex()
shell method take the following locks, depending on version:reIndex
命令和相应的db.collection.reIndex()
shell方法根据版本采用以下锁: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)锁并阻止其他操作直到完成。
thereplSetResizeOplog
command takes the following locks, depending on version:replSetResizeOplog
命令根据版本采用以下锁:For MongoDB 4.2.2 and later, this operation takes an exclusive (W) lock on the对于MongoDB 4.2.2及更高版本,此操作对oplog
collection and blocks other operations on the collection until it finishes.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操作是否锁定过多个数据库?
These MongoDB operations may obtain and hold a lock on more than one database:这些MongoDB操作可能会获得并锁定多个数据库:
reIndex db.collection.reIndex() | |
renameCollection | |
replSetResizeOplog | oplog collection instead of a global exclusive lock. oplog 集合上的独占(W)锁,而不是全局独占锁。 |
How does sharding affect concurrency?分片如何影响并发性?
Sharding improves concurrency by distributing collections over multiple 分片通过在多个mongod
instances, allowing shard servers (specifically, mongos
processes) to run concurrently with the 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 对于副本集,当MongoDB写入主数据库上的集合时,MongoDB还会写入primary的oplog,这是local
database. local
数据库中的一个特殊集合。Therefore, MongoDB must lock both the collection's database and the 因此,MongoDB必须锁定集合的数据库和本地数据库。local
database. 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. Writes are applied in the order that they appear in the 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支持多文档事务:
- In version 4.0
, MongoDB supports multi-document transactions on replica sets.,MongoDB支持副本集上的多文档事务。 - In version 4.2
, MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets.,MongoDB引入了分布式事务,增加了对分片集群上多文档事务的支持,并整合了对副本集上多文档事务的现有支持。For details regarding transactions in MongoDB, see the transactions page.有关MongoDB中事务的详细信息,请参阅事务页面。
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.有关其他事务使用注意事项(如运行时限制和操作日志大小限制),请参阅生产注意事项。
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
选项。
What are lock-free read operations?什么是无锁读取操作?
New in version 5.0. 5.0版新增。
A lock-free read operation runs immediately: it is not blocked when another operation has an exclusive (X) write lock on the collection.无锁读取操作会立即运行:当另一个操作对集合具有独占(X)写入锁定时,该操作不会被阻止。
Starting in MongoDB 5.0, the following read operations are not blocked when another operation holds an exclusive (X) write lock on the collection:从MongoDB 5.0开始,当另一个操作对集合持有独占(X)写锁时,以下读取操作不会被阻止:
When writing to a collection, 在写入集合时,mapReduce
and aggregate
hold an intent exclusive (IX) lock. mapReduce
和aggregate
持有一个intent exclusive(IX)锁。Therefore, if an exclusive X lock is already held on a collection, 因此,如果集合上已持有独占X锁,则会阻止mapReduce
and aggregate
write operations are blocked.mapReduce
和aggregate
写操作。
For information, see:有关信息,请参阅: