数据修改的完整流程
这个概念,估计应该有很多人,对它了解不清楚吧。或者说是比较含糊。今天我们来一起梳理一下这个完整的流程吧。
在OceanBaseV4,以及大多数的分布式数据库中,数据的修改遵循Wal(write-ahead logging)原则。这是保证数据一致性和高可用的核心机制
—— 简单解释以下:和它英文意思一致,即,数据的完整修改流程是“先写日志,在更新主副本,然后通过Paxos协议同步给从副本”
下面让我们来完整的拆分以下这个过程吧
一、数据修改的完整流程
假设一个客户端发起一个UPDATE 请求,在V4中,整个流程如下:
1. Step1 : 请求路由到 Leader 副本所在的节点
- 客户端通过Obproxy (负载均衡组件)连接数据库,OBproxy 根据分区路由规则(就是分区的依据,如hash, range,List,Key等 ),将请求转发到该分区 Leader 副本所在的节点Observe。
eg: 用户表 分区P1的 Leader 节点在 Zone1 可用区的 Node A 节点上,那么这个请求将被路由到 Node A上
2. Step2:Leader 副本接受请求,生成事务日志
- Leader 节点的SQL引擎解析请求,检查权限,约束后,生成事务日志(Log entry),包含操作类型(如Update,数据位置(分区P),修改内容)等。
- 此时,生成的事务日志,仅在内存中构建日志,还没有写入磁盘(SStable)
3. Step3:将日志写入 Leader 本地 “日志流”
- 事务日志首先被追加到 Leader副本的本地日志流(LS)缓冲区,并按顺序刷盘持久化(落盘到leader节点的磁盘日志文件)
—— 关键原则:日志优先,日志成功写入后,才能进行后续的数据库更新。因为日志是数据回复的唯一依据,若日志未持久化,宕机情况下,数据会丢失。
4.Step4:通过Paxos协议将日志同步给Follower 副本
- Leader 副本的LS 通过Paxos协议,将新生成的日志条目广播到该LS 的所有Follower 副本
- Follower 接受数据后,先写入本地LS缓存区,并进行持久化,后返回‘成功’的结果
- 只有当多数派副本(如3个副本中的2个副本)确认持久化成功,返回‘成功’结果,Leader 副本才认为本次日志同步完成
5.Step5:Leader 副本更新内存数据,返回结果给客户端
- 日志同步成功后,Leader 副本才会将内存中缓存的修改(增删改等)应用到内存数据结构(如Memtable),并标记事务为‘已提交’
- 客户端收到‘更新成功’的响应 (对于读已提交的隔离级别,其他事务可读取到新值)
6.Step6:后台异步刷盘(进行数据的持久化)
- 内存中的修改数据 MemTable 不会立即写入磁盘数据文件(SStable),而是由后台线程 异步合并,刷盘(算法机制)
- 即使在刷盘前宕机,已持久化的日志也能在重启后通过“日志回放”重新构建内存数据,保证数据不丢失。
二、为什么不直接“先写Leader数据,再同步数据”?
-
-
数据文件体积大,同步成本高:数据文件(如SSTable)是结构化的存储格式,体积远大于日志(日志仅记录增量修改)。若直接同步数据文件,网络开销和IO成本会极高,无法支持分布式系统的扩展性。
-
日志是“最小恢复单元”:日志流是按顺序追加的,记录了所有修改的完整历史,通过日志回放可重建任意时间点的数据状态;而数据文件是“快照式”的,无法单独作为恢复依据。
-
Paxos协议本质是“日志共识”:Paxos的核心是保证“日志序列”在多个副本间的一致性(即所有副本按相同顺序接收相同的日志条目),而非直接同步数据内容。数据一致性是通过“日志一致”间接保证的。
三、LS 主副本所在的节点,也就是此LS所包含的分区的主副本的所在的节点
* 因为在V4 中一个节点上的同一个租户的所有分区公用一个LS,所以LS的主副本所在节点=该LS包含的的所有分区的主副本所在的节点。
可以给我点点赞,发发评论嘛。Thank you!
OB-QQ交流群
1057942717