【发布时间】:2023-01-27 01:34:42
【问题描述】:
我需要您帮助理解和解决性能问题。
我们有一个系统,我们可以批量存储一组文档(1k-4k 文档)。文件有这样的结构:{_id: ObjectId(), RepositoryId: UUID(), data...}
其中存储库 ID 对于集合中的所有实例都是相同的。我们还为 {_id: 1, RepositoryId: 1}, {RepositoryId: 1, ...} 设置了唯一索引。
在用例中是:删除具有相同 RepositoryId 的所有文档:
db.collection.deleteMany(
{ RepositoryId: UUID("SomeGUID") },
{ writeConcern: {w: "majority", j: true} }
)
然后使用与我们之前删除的相同的 RepositoryId 重新插入批次(每批 300 项):
db.collection.insertMany(
[ { RepositoryId: UUID(), data... }, ... ],
{
writeConcern: {w: 1, j: false},
ordered: false
}
)
问题是前几 (3-5) 批次的更新插入需要更多时间然后重置(第一批:10 秒,第 8 批 0.1 秒)。日志文件中也有条目:
{
"t": {
"$date": "2023-01-19T15:49:02.258+01:00"
},
"s": "I",
"c": "COMMAND",
"id": 51803,
"ctx": "conn64",
"msg": "Slow query",
"attr": {
"type": "command",
"ns": "####.$cmd",
"command": {
"update": "########",
"ordered": false,
"writeConcern": {
"w": 1,
"fsync": false,
"j": false
},
"txnNumber": 16,
"$db": "#####",
"lsid": {
"id": {
"$uuid": "6ffb319a-6003-4221-9925-710e9e2aa315"
}
},
"$clusterTime": {
"clusterTime": {
"$timestamp": {
"t": 1674139729,
"i": 5
}
},
"numYields": 0,
"reslen": 11550,
"locks": {
"ParallelBatchWriterMode": {
"acquireCount": {
"r": 600
}
},
"ReplicationStateTransition": {
"acquireCount": {
"w": 601
}
},
"Global": {
"acquireCount": {
"w": 600
}
},
"Database": {
"acquireCount": {
"w": 600
}
},
"Collection": {
"acquireCount": {
"w": 600
}
},
"Mutex": {
"acquireCount": {
"r": 600
}
}
},
"flowControl": {
"acquireCount": 300,
"timeAcquiringMicros": 379
},
"readConcern": {
"level": "local",
"provenance": "implicitDefault"
},
"writeConcern": {
"w": 1,
"j": false,
"wtimeout": 0,
"provenance": "clientSupplied"
},
"storage": {
},
"remote": "127.0.0.1:52800",
"protocol": "op_msg",
"durationMillis": 13043
}
}
}
}
是否有一些在删除后运行的后台进程会影响第一批的更新插入性能?由于应用程序另一部分的事务支持,在我们从独立副本集切换到单实例副本集之前这不是问题。这种情况不需要事务,但我们不能托管两个具有不同设置的 mongo 实例。该 DB 专用于此操作,没有其他操作在 DB 上运行(在隔离测试环境中运行)。我们如何解决它?
该问题是可重现的,似乎在测试运行中存在时间间隔(几分钟)时,首次运行不存在问题,但随后的运行出现问题。 在配备 Ryzen 7 PRO 4750U、32 GB Ram 和 Samsung 970 EVO M2 SSD 的机器上运行。 MongoDB 版本 5.0.5
【问题讨论】:
-
检查解释计划,我猜没有使用索引
{_id: 1, RepositoryId: 1}。在{ RepositoryId: 1 }上尝试索引 -
我检查了 mongodb.log 中的删除命令,它使用进程的索引。它的复合索引只是 Repository 的前缀。 (我编辑了原来的帖子以使其清楚)
标签: mongodb mongodb-replica-set