MongoDB 中的 Write Concern 如何在线程级别工作?
How does Write Concern in MongoDB Work at Thread level?
据我所知,我们可以从应用程序设置写入问题,我想知道 MongoDB 将如何处理这样的场景:
假设我们在同一个数据库上有两个 task/Process(P1 和 P2)运行(数据库有一个包含三个节点的副本集,1 个主节点和 2 个辅助节点)。
P1 在日志级别启用了写关注。
P2 已在副本级别启用写关注。(二级级别)。
现在如果P1和P2都写入数据库会发生什么?
P2会不会等到P1写入的数据复制到secondary,再把自己的数据写入secondary?
或者它是如何处理的?
写入关注是针对每个操作的,并确定 MongoDB 何时向客户端报告写入成功。它与大约同时发生的其他操作无关。
如果 P1 有 "write concern enabled at journal level",我认为这意味着日志写入关注 { "j" : 1 }
,MongoDB 将不会报告 P1 发送的操作成功,直到它们被提交日记。 P2 写入的状态无关紧要。
如果 P2 有 "write concern enabled at replica level",我认为这意味着大多数写关注 { "w" : "majority" }
,那么 P2 所做的每个操作都不会被报告为成功,直到它被复制到副本集。 P1 写入的状态无关紧要。
P1 和 P2 操作不会等待对方的写关注得到满足后再继续,或类似的事情。
由于回复很长,已编辑回复以评论答案:
是的,第二次写入必须等待第一次写入释放数据库写锁(如果第一次写入产生锁,可能在多文档第一次写入的中间),但是第二次write 不必等待第一个 write 完成其整个 write concern。
例如,考虑 { "w" : "majority" }
的写入 A
和 { "w" : 1 }
的写入 B
。 A
首先到达主节点并获取写锁。 B
秒到,等待写锁。 A
写锁使用完毕并释放; B
拿了锁。 A
的写入需要复制到辅助节点以实现其写入问题——这与 B
持有写入锁同时发生。 B
完成并且 MongoDB 响应客户端写入成功。 A
完成复制到所需数量的副本集成员并且 MongoDB 响应写入成功。 A
在 B
之前发送并在 B
之前在主服务器上写入,在此期间它持有锁并阻塞 B
,但 B
先返回。阻碍 B
的不是 A
的写入问题,而是 MongoDB 不能同时对同一个数据库进行两次写入的更简单的事实。
问题是老问题,关于 Mongo 移动到 WiredTiger (2015) 3.0 版的时间。
从那时起,引擎的并发性得到显着提高,对于大多数 read/write 操作,锁定级别就是文档级别本身。
参见:https://docs.mongodb.com/manual/faq/concurrency/
因此多线程(同一进程或多进程)也提高了最严格的写入关注的性能。
据我所知,我们可以从应用程序设置写入问题,我想知道 MongoDB 将如何处理这样的场景:
假设我们在同一个数据库上有两个 task/Process(P1 和 P2)运行(数据库有一个包含三个节点的副本集,1 个主节点和 2 个辅助节点)。 P1 在日志级别启用了写关注。 P2 已在副本级别启用写关注。(二级级别)。
现在如果P1和P2都写入数据库会发生什么?
P2会不会等到P1写入的数据复制到secondary,再把自己的数据写入secondary?
或者它是如何处理的?
写入关注是针对每个操作的,并确定 MongoDB 何时向客户端报告写入成功。它与大约同时发生的其他操作无关。
如果 P1 有 "write concern enabled at journal level",我认为这意味着日志写入关注 { "j" : 1 }
,MongoDB 将不会报告 P1 发送的操作成功,直到它们被提交日记。 P2 写入的状态无关紧要。
如果 P2 有 "write concern enabled at replica level",我认为这意味着大多数写关注 { "w" : "majority" }
,那么 P2 所做的每个操作都不会被报告为成功,直到它被复制到副本集。 P1 写入的状态无关紧要。
P1 和 P2 操作不会等待对方的写关注得到满足后再继续,或类似的事情。
由于回复很长,已编辑回复以评论答案:
是的,第二次写入必须等待第一次写入释放数据库写锁(如果第一次写入产生锁,可能在多文档第一次写入的中间),但是第二次write 不必等待第一个 write 完成其整个 write concern。
例如,考虑 { "w" : "majority" }
的写入 A
和 { "w" : 1 }
的写入 B
。 A
首先到达主节点并获取写锁。 B
秒到,等待写锁。 A
写锁使用完毕并释放; B
拿了锁。 A
的写入需要复制到辅助节点以实现其写入问题——这与 B
持有写入锁同时发生。 B
完成并且 MongoDB 响应客户端写入成功。 A
完成复制到所需数量的副本集成员并且 MongoDB 响应写入成功。 A
在 B
之前发送并在 B
之前在主服务器上写入,在此期间它持有锁并阻塞 B
,但 B
先返回。阻碍 B
的不是 A
的写入问题,而是 MongoDB 不能同时对同一个数据库进行两次写入的更简单的事实。
问题是老问题,关于 Mongo 移动到 WiredTiger (2015) 3.0 版的时间。 从那时起,引擎的并发性得到显着提高,对于大多数 read/write 操作,锁定级别就是文档级别本身。
参见:https://docs.mongodb.com/manual/faq/concurrency/
因此多线程(同一进程或多进程)也提高了最严格的写入关注的性能。