面试题答案
一键面试两阶段提交(2PC)基本流程
- 准备阶段(Prepare Phase):
- 事务协调者(通常是发起事务的节点)向所有参与事务的节点(分片节点)发送
prepare
请求。 - 每个参与节点接收到
prepare
请求后,开始执行事务操作,包括数据的修改等,但并不真正提交这些修改,而是将操作记录在日志中,同时向协调者回复ready
或abort
。若节点成功完成事务操作准备,则回复ready
;若在准备过程中出现错误,如资源不足、违反约束等,则回复abort
。
- 事务协调者(通常是发起事务的节点)向所有参与事务的节点(分片节点)发送
- 提交阶段(Commit Phase):
- 如果协调者收到所有参与节点都回复
ready
,则向所有节点发送commit
请求。每个节点收到commit
请求后,将日志中的事务操作正式提交,完成数据持久化。 - 如果协调者收到任何一个节点回复
abort
,或者在规定时间内部分节点没有响应,那么协调者向所有节点发送abort
请求,各节点回滚之前的事务操作,撤销准备阶段所做的修改。
- 如果协调者收到所有参与节点都回复
MongoDB利用2PC保证事务原子性的方式
- 事务协调:在MongoDB分片集群中,
mongos
作为事务协调者角色。当客户端发起一个跨节点事务时,mongos
负责协调各个分片节点执行2PC流程。 - 日志记录:每个分片节点在准备阶段将事务操作记录到预写日志(WAL)中,确保即使在系统崩溃等异常情况下,也能恢复到事务执行前的状态。这是保证原子性的基础,因为如果出现故障需要回滚,依赖这些日志来撤销未完成的事务操作。
- 节点间通信:
mongos
与各个分片节点之间通过可靠的网络通信来完成2PC流程的消息传递。mongos
确保prepare
、commit
或abort
等消息准确无误地发送到各分片节点,并能及时收到节点的响应。这样可以避免因消息丢失或错误导致部分节点执行不一致的情况,进而保证所有参与事务的节点要么全部提交事务,要么全部回滚事务,从而实现事务原子性。 - 故障处理:如果在2PC过程中某个节点出现故障,MongoDB有相应的机制来处理。例如,在准备阶段某个节点故障未响应
prepare
请求,mongos
会等待一段时间,若超时仍未收到响应则判定该节点故障,向其他节点发送abort
请求。对于故障恢复后的节点,MongoDB会根据日志状态来决定是继续完成事务(若之前已ready
)还是回滚事务。