Production Considerations生产注意事项
On this page本页内容
Availability可用性Feature Compatibility功能兼容性Runtime Limit运行时间限制Oplog Size Limit操作日志大小限制WiredTiger CacheWiredTiger缓存Transactions and Security事务和安全Shard Configuration Restriction分片配置限制Sharded Clusters and Arbiters分片集群和ArbiterAcquiring Locks获取锁Pending DDL Operations and Transactions挂起的DDL操作和事务In-progress Transactions and Write Conflicts进行中事务和写入冲突In-progress Transactions and Stale Reads进行中事务和过期读取In-progress Transactions and Chunk Migration进行中事务和块迁移Outside Reads During Commit提交期间的外部读取- Errors
Additional Information附加信息
The following page lists some production considerations for running transactions. 下页列出了运行事务的一些生产注意事项。These apply whether you run transactions on replica sets or sharded clusters. 无论您在副本集还是分片集群上运行事务,这些都适用。For running transactions on sharded clusters, see also the Production Considerations (Sharded Clusters) for additional considerations that are specific to sharded clusters.有关在分片集群上运行事务的信息,请参阅生产注意事项(分片集群),以了解特定于分片集群的其他注意事项。
Availability可用性
In version 4.0, MongoDB supports multi-document transactions on replica sets.在4.0版本中,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.在4.2版本中,MongoDB引入了分布式事务,增加了对分片集群上多文档事务的支持,并整合了对副本集上多文档事务的现有支持。To use transactions on MongoDB 4.2 deployments (replica sets and sharded clusters), clients must use MongoDB drivers updated for MongoDB 4.2.要在MongoDB 4.2部署(副本集和分片集群)上使用事务,客户端必须使用为MongoDB 4.2更新的MongoDB驱动程序。
Distributed Transactions and Multi-Document Transactions分布式事务和多文档事务
Starting in MongoDB 4.2, the two terms are synonymous. Distributed transactions refer to multi-document transactions on sharded clusters and replica sets. 从MongoDB 4.2开始,这两个术语是同义词。分布式事务是指分片集群和副本集上的多文档事务。Multi-document transactions (whether on sharded clusters or replica sets) are also known as distributed transactions starting in MongoDB 4.2.多文档事务(无论是在分片集群还是副本集上)也被称为MongoDB 4.2中开始的分布式事务。
Feature Compatibility功能兼容性
To use transactions, the featureCompatibilityVersion for all members of the deployment must be at least:若要使用事务,部署的所有成员的featureCompatibilityVersion
必须至少为:
featureCompatibilityVersion | |
---|---|
4.0 | |
4.2 |
To check the fCV for a member, connect to the member and run the following command:若要检查成员的fCV,请连接到该成员并运行以下命令:
db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
For more information, see the 有关更多信息,请参阅setFeatureCompatibilityVersion
reference page.setFeatureCompatibilityVersion
参考页。
Runtime Limit运行时间限制
By default, a transaction must have a runtime of less than one minute. 默认情况下,事务的运行时间必须少于一分钟。You can modify this limit using 您可以使用transactionLifetimeLimitSeconds
for the mongod
instances. mongod
实例的transactionLifetimeLimitSeconds
来修改此限制。For sharded clusters, the parameter must be modified for all shard replica set members. 对于分片集群,必须修改所有分片副本集成员的参数。Transactions that exceeds this limit are considered expired and will be aborted by a periodic cleanup process.超过此限制的事务将被视为已过期,并将由定期清理过程中止。
For sharded clusters, you can also specify a 对于分片集群,您还可以指定maxTimeMS
limit on commitTransaction
. commitTransaction
的maxTimeMS
限制。For more information, see Sharded Clusters Transactions Time Limit.有关详细信息,请参阅分片集群事务时间限制。
Oplog Size Limit操作日志大小限制
Starting in version 4.2,从版本4.2开始,MongoDB creates as many oplog entries as necessary to the encapsulate all write operations in a transaction, instead of a single entry for all write operations in the transaction.MongoDB根据需要创建尽可能多的oplog条目来封装事务中的所有写操作,而不是为事务中的全部写操作创建一个条目。This removes the 16MB total size limit for a transaction imposed by the single oplog entry for all its write operations.这消除了单个操作日志条目对事务的所有写入操作所施加的16MB总大小限制。Although the total size limit is removed, each oplog entry still must be within the BSON document size limit of 16MB.尽管删除了总大小限制,但每个oplog条目仍然必须在BSON文档大小限制16MB的范围内。In version 4.0,在版本4.0中,MongoDB creates a single oplog (operations log) entry at the time of commit if the transaction contains any write operations.如果事务包含任何写操作,MongoDB会在提交时创建一个oplog(操作日志)条目。That is, the individual operations in the transactions do not have a corresponding oplog entry.也就是说,事务中的各个操作没有相应的oplog条目。Instead, a single oplog entry contains all of the write operations within a transaction.相反,一个oplog条目包含事务中的所有写操作。The oplog entry for the transaction must be within the BSON document size limit of 16MB.事务的操作日志条目必须在BSON文档大小限制16MB的范围内。
WiredTiger CacheWiredTiger缓存
To prevent storage cache pressure from negatively impacting the performance:要防止存储缓存压力对性能产生负面影响,请执行以下操作:
When you abandon a transaction, abort the transaction.当您放弃事务时,请中止该事务。When you encounter an error during individual operation in the transaction, abort and retry the transaction.当您在事务中的单个操作过程中遇到错误时,请中止并重试该事务。
The transactionLifetimeLimitSeconds
also ensures that expired transactions are aborted periodically to relieve storage cache pressure.transactionLifetimeLimitSeconds
还确保定期中止过期的事务,以缓解存储缓存压力。
If you have an uncommitted transaction that exceeds 5% of the 如果未提交的事务超过WiredTiger缓存大小的5%,则该事务将中止并返回写冲突错误。WiredTiger cache size
, the transaction will abort and return a write conflict error.
Transactions and Security事务和安全
If running with access control, you must have privileges for the operations in the transaction.如果使用访问控制运行,则必须对事务中的操作具有权限。If running with auditing, operations in an aborted transaction are still audited. However, there is no audit event that indicates that the transaction aborted.如果使用审核运行,则中止事务中的操作仍将被审核。但是,没有任何审核事件表明事务中止。
Shard Configuration Restriction分片配置限制
You cannot run transactions on a sharded cluster that has a shard with 您不能在具有writeConcernMajorityJournalDefault
set to false
(such as a shard with a voting member that uses the in-memory storage engine).writeConcernMajorityJournalDefault
设置为false
的分片(例如具有使用内存存储引擎的投票成员的分片)的分片集群上运行事务。
Sharded Clusters and Arbiters分片集群和仲裁器
Transactions whose write operations span multiple shards will error and abort if any transaction operation reads from or writes to a shard that contains an arbiter.如果任何事务操作从包含仲裁器的分片中读取或写入,则写入操作跨多个分片的事务将出错并中止。
Acquiring Locks获取锁
By default, transactions wait up to 默认情况下,事务最多等待5
milliseconds to acquire locks required by the operations in the transaction. 5
毫秒来获取事务中操作所需的锁。If the transaction cannot acquire its required locks within the 如果事务无法在5
milliseconds, the transaction aborts.5
毫秒内获得所需的锁,则事务将中止。
Transactions release all locks upon abort or commit.事务在中止或提交时释放所有锁。
When creating or dropping a collection immediately before starting a transaction, if the collection is accessed within the transaction, issue the create or drop operation with write concern 在启动事务之前立即创建或删除集合时,如果在事务中访问集合,请发出写关注"majority"
to ensure that the transaction can acquire the required locks."majority"
的创建或删除操作,以确保事务可以获取所需的锁。
Lock Request Timeout锁定请求超时
You can use the 您可以使用maxTransactionLockRequestTimeoutMillis
parameter to adjust how long transactions wait to acquire locks. maxTransactionLockRequestTimeoutMillis
参数来调整事务等待获取锁的时间。Increasing 增加maxTransactionLockRequestTimeoutMillis
allows operations in the transactions to wait the specified time to acquire the required locks. maxTransactionLockRequestTimeoutMillis
允许事务中的操作等待指定的时间以获取所需的锁。This can help obviate transaction aborts on momentary concurrent lock acquisitions, like fast-running metadata operations. 这可以帮助避免瞬时并发锁获取时的事务中止,如快速运行的元数据操作。However, this could possibly delay the abort of deadlocked transaction operations.但是,这可能会延迟死锁事务操作的中止。
You can also use operation-specific timeout by setting 您还可以通过将maxTransactionLockRequestTimeoutMillis
to -1
.maxTransactionLockRequestTimeoutMillis
设置为-1
来使用特定于操作的超时。
Pending DDL Operations and Transactions挂起的DDL操作和事务
If a multi-document transaction is in progress, new DDL operations that affect the same database(s) or collection(s) wait behind the transaction. 如果多文档事务正在进行,则影响同一数据库或集合的新DDL操作将在事务之后等待。While these pending DDL operations exist, new transactions that access the same database(s) or collection(s) as the pending DDL operations cannot obtain the required locks and and will abort after waiting 虽然存在这些挂起的DDL操作,但访问与挂起DDL操作相同的数据库或集合的新事务无法获得所需的锁,并且将在等待maxTransactionLockRequestTimeoutMillis
. maxTransactionLockRequestTimeoutMillis
后中止。In addition, new non-transaction operations that access the same database(s) or collection(s) will block until they reach their 此外,访问相同数据库或集合的新的非事务操作将被阻止,直到它们达到其maxTimeMS
limit.maxTimeMS
限制。
Consider the following scenarios:考虑以下场景:
DDL Operation That Requires a Collection Lock需要集合锁的DDL操作-
While an in-progress transaction is performing various CRUD operations on the当正在进行的事务对employees
collection in thehr
database, an administrator issues thedb.collection.createIndex()
DDL operation against theemployees
collection.hr
数据库中的employees
集合执行各种CRUD操作时,管理员会对employees
集合发出db.collection.createIndex()
DDL操作。createIndex()
requires an exclusive collection lock on the collection.需要对集合使用独占集合锁。Until the in-progress transaction completes, the在进行中的事务完成之前,createIndex()
operation must wait to obtain the lock.createIndex()
操作必须等待以获取锁。Any new transaction that affects the任何影响employees
collection and starts while thecreateIndex()
is pending must wait until aftercreateIndex()
completes.employees
集合并在createIndex()
挂起时启动的新事务都必须等到createIndex()
完成之后。The pending挂起的createIndex()
DDL operation does not affect transactions on other collections in thehr
database. For example, a new transaction on thecontractors
collection in thehr
database can start and complete as normal.createIndex()
DDL操作不会影响hr
数据库中其他集合上的事务。例如,hr
数据库中contractors集合上的新事务可以正常启动和完成。 DDL Operation That Requires a Database Lock需要数据库锁定的DDL操作-
While an in-progress transaction is performing various CRUD operations on the当正在进行的事务对employees
collection in thehr
database, an administrator issues thecollMod
DDL operation against thecontractors
collection in the same database.hr
数据库中的employees
集合执行各种CRUD操作时,管理员会对同一数据库中的contractors
集合发出collMod
DDL操作。collMod
requires a database lock on the parent需要对父hr
database.hr
数据库进行数据库锁定。Until the in-progress transaction completes, the在进行中的事务完成之前,collMod
operation must wait to obtain the lock.collMod
操作必须等待以获取锁。Any new transaction that affects the任何影响hr
database or any of its collections and starts while thecollMod
is pending must wait until aftercollMod
completes.hr
数据库或其任何集合并在collMod
挂起时启动的新事务都必须等到collMod
完成之后。
In either scenario, if the DDL operation remains pending for more than 在任何一种情况下,如果DDL操作的挂起时间超过maxTransactionLockRequestTimeoutMillis
, pending transactions waiting behind that operation abort. maxTransactionLockRequestTimeoutMillis
,则在该操作之后等待的挂起事务将中止。That is, the value of 也就是说,maxTransactionLockRequestTimeoutMillis
must at least cover the time required for the in-progress transaction and the pending DDL operation to complete.maxTransactionLockRequestTimeoutMillis
的值必须至少覆盖正在进行的事务和挂起的DDL操作完成所需的时间。
In-progress Transactions and Write Conflicts进行中事务和写入冲突
If a transaction is in progress and a write outside the transaction modifies a document that an operation in the transaction later tries to modify, the transaction aborts because of a write conflict.如果事务正在进行中,并且事务外部的写入操作修改了事务中的操作稍后试图修改的文档,则事务会因为写入冲突而中止。
If a transaction is in progress and has taken a lock to modify a document, when a write outside the transaction tries to modify the same document, the write waits until the transaction ends.如果事务正在进行中,并且已锁定以修改文档,则当事务外部的写入尝试修改同一文档时,写入将等待,直到事务结束。
In-progress Transactions and Stale Reads进行中事务和过期读取
Read operations inside a transaction can return stale data. That is, read operations inside a transaction are not guaranteed to see writes performed by other committed transactions or non-transactional writes. 事务中的读取操作可能会返回过时的数据。也就是说,事务内部的读取操作不能保证看到由其他提交的事务或非事务性写入执行的写入。For example, consider the following sequence: 1) a transaction is in-progress 2) a write outside the transaction deletes a document 3) a read operation inside the transaction is able to read the now-deleted document since the operation is using a snapshot from before the write.例如,考虑以下顺序:1)事务正在进行中2)事务外部的写入会删除文档3)事务内部的读取操作能够读取现在已删除的文档,因为该操作使用的是写入之前的快照。
To avoid stale reads inside transactions for a single document, you can use the 为了避免在单个文档的事务中进行过时的读取,可以使用db.collection.findOneAndUpdate()
method. db.collection.findOneAndUpdate()
方法。For example:例如:
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );
employeesCollection = session.getDatabase("hr").employees;
employeeDoc = employeesCollection.findOneAndUpdate(
{ _id: 1, employee: 1, status: "Active" },
{ $set: { employee: 1 } },
{ returnNewDocument: true }
);
If the employee document has changed outside the transaction, then the transaction aborts.如果员工文档在事务之外发生了更改,则事务将中止。If the employee document has not changed, the transaction returns the document and locks the document.如果员工文档没有更改,事务处理将返回文档并锁定文档。
In-progress Transactions and Chunk Migration进行中事务和块迁移
Chunk migration区块迁移 acquires exclusive collection locks during certain stages.在某些阶段获取独占集合锁。
If an ongoing transaction has a lock on a collection and a chunk migration that involves that collection starts, these migration stages must wait for the transaction to release the locks on the collection, thereby impacting the performance of chunk migrations.如果正在进行的事务对集合具有锁定,并且涉及该集合的块迁移开始,则这些迁移阶段必须等待事务释放对集合的锁定,从而影响块迁移的性能。
If a chunk migration interleaves with a transaction (for instance, if a transaction starts while a chunk migration is already in progress and the migration completes before the transaction takes a lock on the collection), the transaction errors during the commit and aborts.如果区块迁移与事务交错(例如,如果事务在区块迁移已经进行时开始,并且迁移在事务锁定集合之前完成),则事务在提交期间出错并中止。
Depending on how the two operations interleave, some sample errors include (the error messages have been abbreviated):根据两个操作的交错方式,一些示例错误包括(错误消息已缩写):
an error from cluster data placement change ... migration commit in progress for <namespace>
Cannot find shardId the chunk belonged to at cluster time ...
See also: 另请参阅:
Outside Reads During Commit提交期间的外部读取
During the commit for a transaction, outside read operations may try to read the same documents that will be modified by the transaction. 在事务的提交过程中,外部读取操作可能会尝试读取将由事务修改的相同文档。If the transaction writes to multiple shards, then during the commit attempt across the shards如果事务写入多个分片,那么在跨分片的提交尝试期间
- Outside reads that use read concern
"snapshot"
or"linearizable"
, or are part of causally consistent sessions (i.e. include afterClusterTime) wait for all writes of a transaction to be visible. Outside reads using other read concerns do not wait for all writes of a transaction to be visible but instead read the before-transaction version of the documents available.使用其他读取关注点的外部读取不会等待事务的所有写入都可见,而是读取可用文档的事务前版本。
Errors
Use of MongoDB 4.0 DriversMongoDB 4.0驱动程序的使用
To use transactions on MongoDB 4.2 deployments (replica sets and sharded clusters), clients must use MongoDB drivers updated for MongoDB 4.2.要在MongoDB 4.2部署(副本集和分片集群)上使用事务,客户端必须使用为MongoDB 4.2更新的MongoDB驱动程序。
On sharded clusters with multiple 在具有多个mongos
instances, performing transactions with drivers updated for MongoDB 4.0 (instead of MongoDB 4.2) will fail and can result in errors, including:mongos
实例的分片集群上,使用为MongoDB 4.0(而不是MongoDB 4.2)更新的驱动程序执行事务将失败,并可能导致错误,包括:
Your driver may return a different error. Refer to your driver's documentation for details.您的驱动程序可能会返回不同的错误。有关详细信息,请参阅您的驾驶员文档。
251 | cannot continue txnId -1 for session ... with txnId 1 |
50940 | cannot commit with no participants |