我认为我们可以从应用程序中设置写入问题,我想知道MongoDB将如何处理这样的场景:
假设我们有两个任务/进程(P1和P2)在同一个数据库上运行(数据库有三个节点的副本集,1个主节点和2个辅助节点)。 P1在期刊级别启用了写入关注。 P2在副本级别启用了写入关注。(二级)。
现在如果P1和P2都写入数据库会发生什么?
P2会等待P1写入的数据被复制到辅助数据,然后将其数据写入辅助数据吗?
或者它是如何处理的?
答案 0 :(得分:2)
写操作关注是每个操作,并确定MongoDB何时向客户端报告写入成功。它与大约在同一时间发生的其他操作无关。
如果P1具有“在期刊级别启用写入关注”,我将其视为日记写入问题{ "j" : 1 }
,则MongoDB将不会报告P1发送的操作在提交到日志之前是否成功。无论P2写入的状态如何。
如果P2具有“在副本级别启用了写入关注”,我认为这意味着多数写入关注{ "w" : "majority" }
,那么在复制到大多数节点之前,每个操作P2都不会被报告为成功。副本集。无论P1写入的状态如何。
P1和P2操作不会等到对方的写入问题在他们继续之前得到满足,或类似的事情。
由于回复很长,编辑了对答案的评论回复:
是的,第二次写入必须等待第一次写入释放数据库写入锁定(如果第一次写入产生锁定,可能在多文档第一次写入的中间),但第二次写入不会不得不等待第一次写作才能完成整个写作问题。
例如,考虑使用A
编写{ "w" : "majority" }
,使用B
编写{ "w" : 1 }
。 A
首先到达主服务器并进行写锁定。 B
到达第二个并等待写锁定。 A
完成使用写锁并释放它; B
获得锁定。 A
的写入需要复制到辅助节点以实现其写入问题 - 这是在B
持有写锁定的同时发生的。 B
完成,MongoDB响应客户端写入成功。 A
完成复制到所需数量的副本集成员,MongoDB响应写入成功。在A
之前发送了B
,并在B
之前在主要内容上写了一段时间,在此期间它保持锁定并阻止B
,但B
首先返回。这不是A
的写入问题,而是B
,更简单的事实是MongoDB不能同时对同一个数据库进行两次写入。
答案 1 :(得分:0)
关于Mongo移至WiredTiger(2015)版本3.0的时间,这个问题很古老。 从那以后,引擎的并发性得到了极大的改善,对于大多数读/写操作,锁定级别是文档级别本身。
请参阅:https://docs.mongodb.com/manual/faq/concurrency/
因此,对于最严格的写问题,多线程(同一进程或多个进程)也提高了性能。