MongoDb Upsert Deadlock

本文关键字:Deadlock Upsert MongoDb | 更新日期: 2023-09-27 18:11:11

是否有可能在MongoDb的upsert操作上达到死锁?我正在对一个upsert操作执行负载测试,如下所示:

db.update(
    { foo: {a: 'xxx', b: 'yyy'}, $lt: {"order.date": someDate}}, 
    {order: order}, 
    true, false);

部署在Azure机器上,使用官方mongodb c#驱动程序。单实例,没有副本集或分片。

当我运行5000个相同的更新命令时,在200个并发线程中分配(2台机器,每个线程100个),大多数情况下它将以死锁结束。也就是说,许多电话再也没有回。我可以通过控制台从db.currentOp()中看到,许多更新仍然在那里,卡在锁定:true中,lockType:'write'。

为什么会发生死锁?这怎么可能?我该如何预防呢?有什么具体的指导方针,应该避免什么样的操作,以避免mongodb上的死锁?

$atomic是否与解决方案相关?我甚至不知道如何在c#上设置$atomic:true,尽管它可能与死锁问题无关。

MongoDb Upsert Deadlock

$atomic应该有所帮助

db.update(
    {
        $and: [
            { foo: { a: 'xxx', b: 'yyy' },
            { $lt: { 'order.date': someDate } }
        ],
        $atomic: true
    },
    { order: order },
    true,
    false
);

,你也可能需要一个$and子句。检查调用的解释,看看使用了哪些索引,等等。