mongodb MongoError:无法获取锁

643ylb08  于 2023-01-08  发布在  Go
关注(0)|答案(3)|浏览(618)

我最近在运行测试时遇到了这个错误,我在本地MongoDB服务器(4.0.5)上试过,在Mongo Atlas上也试过,但都遇到了同样的问题。
我尝试增加锁定超时,但没有效果。
我不知道是什么问题。

{ MongoError: Unable to acquire lock '{8576955153473224393: Database, 1659426125832142537}' within a max lock request timeout of '5ms' milliseconds.
    at queryCallback (/home/user/workspace/my-project/node_modules/mongodb-core/lib/cursor.js:248:25)
    at /home/user/workspace/my-project/node_modules/mongodb-core/lib/connection/pool.js:532:18
    at _combinedTickCallback (internal/process/next_tick.js:132:7)
    at process._tickDomainCallback (internal/process/next_tick.js:219:9)
  errorLabels: [ 'TransientTransactionError' ],
  operationTime: Timestamp { _bsontype: 'Timestamp', low_: 29, high_: 1548245676 },
  ok: 0,
  errmsg: 'Unable to acquire lock \'{8576955153473224393: Database, 1659426125832142537}\' within a max lock request timeout of \'5ms\' milliseconds.',
  code: 24,
  codeName: 'LockTimeout',
  '$clusterTime': 
   { clusterTime: Timestamp { _bsontype: 'Timestamp', low_: 29, high_: 1548245676 },
     signature: { hash: [Object], keyId: 0 } },
  name: 'MongoError',
  [Symbol(mongoErrorContextSymbol)]: {} }
py49o6xq

py49o6xq1#

不是真正的修复,而是一个变通方案。因为它只发生在我的本地机器在自动测试,它不会发生在生产,我可以摆脱这个问题。
Unable to acquire lock错误可以通过将maxTransactionLockRequestTimeoutMillis设置为更高的值来防止,但由于我同时也遇到了Unable to read from a snapshot due to pending collection catalog changes; please retry the operation.错误,我想出了以下方法来修复该错误,从而也修复了第一个错误:
我的测试运行器(AVA)为每个测试文件创建一个新的数据库,但现在似乎需要一些时间来解决,并在mongoose.connect之后添加await timeout(1000),问题就消失了。对这个解决方案不是很满意,但对于测试来说已经足够好了。

kcwpcxri

kcwpcxri2#

了解您正在使用的导致超时的查询、您有哪些索引以及工作负荷有多重将非常有益。您可以使用以下命令增加超时:
db.adminCommand({设置参数:1,最大事务锁定请求超时(毫秒):5000美元)
但我首先会尝试运行一个分析器,看看是什么导致了争用:
https://docs.mongodb.com/manual/tutorial/manage-the-database-profiler/

cwxwcias

cwxwcias3#

我在使用“MongoDB内存服务器”时遇到了这个错误。由于某种原因,当我们只需要一个副本集时,有两个副本集,所以我删除了副本集。另外,我增加了锁定时间,从5ms开始,因为我们的测试在数据库上很繁重。
P.S:如果您正在使用mongoose,并希望更改“maxTransactionLockRequestTimeoutMillis”,您应该这样做:

const db = await mongoose.connect(uri, mongooseOpts || defaultOpts);

await db.connection.db.admin().command({
setParameter: 1,
maxTransactionLockRequestTimeoutMillis: 3000});

相关问题