Christiaan Maks
Christiaan Maks

Reputation: 3778

MongoError: Unable to acquire lock

I've been getting this error lately when running my tests. I tried it with a local MongoDB server (4.0.5) and I've tried it on Mongo Atlas but experiencing the same problem.

I tried increasing the lock timeout but that has no effect.

I'm not sure what the problem is.

{ 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)]: {} }

Upvotes: 8

Views: 21392

Answers (3)

Ofir Assulin
Ofir Assulin

Reputation: 21

I had that error using "MongoDB memory server" with replica sets. For some reason, there were 2 replica sets when we needed only one, so I removed the replica sets. In addition, I increased the lock time from 5ms cause our tests are heavy on the DB.

P.S: If you are using mongoose and want to change the "maxTransactionLockRequestTimeoutMillis" you're supposed to do something like that:

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


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

Upvotes: 2

Christiaan Maks
Christiaan Maks

Reputation: 3778

Not really a fix but a workaround. Since it only happens on my local machine during automated testing and it doesn't happen in production I can get away with this.

The Unable to acquire lock error can be prevented by setting the maxTransactionLockRequestTimeoutMillis to something higher but since I also had this error Unable to read from a snapshot due to pending collection catalog changes; please retry the operation. at the same time, I figured out the following to fix that error which in turn also fixed the first error:

My test runner (AVA) creates a new database for every test file but it seems it needs some time to settle now and adding await timeout(1000) after the mongoose.connect the problem went away. Not super happy with this solution but for testing it is good enough.

Upvotes: 8

Jeff Blanchard
Jeff Blanchard

Reputation: 133

It would be beneficial to know the query you are using that is causing the timeout as well as what indexes you have in place and how heavy the workload is. You can increase the timeout with the following command:

db.adminCommand( { setParameter: 1, maxTransactionLockRequestTimeoutMillis: 5000 })

But I would first try and run a profiler to see what is causing the contention:

https://docs.mongodb.com/manual/tutorial/manage-the-database-profiler/

Upvotes: 7

Related Questions