- 数据库功能层整体架构
- CS-SQL:单子表的 SQL 查询,(读事务)
- UPS-SQL:实现写事务
- MS-SQL:SQL 语句解析,包括词法分析、语法分析、预处理、生成执行计划、按照子表范围合并多个 ChunkServer 返回的部分结果,实现多表的物理操作如 join、subquery 等
- SQL 执行本地化:保持数据节点与计算节点一致,只要 ChunkServer 能实现的操作,原则上都应该由它完成
- TableScan:每个 ChunkServer scan 各自子表范围内的数据,由 MergeServer 合并 ChunkServer 返回的部分结果
- Filter:
- 对基本表的过滤集成在 TableScan 中,由 ChunkServer 完成
- 对分组后的记过执行过滤集成(Having)集成在 GroupBy 中,一般由 MergeServer 完成
- 如果能确定多每个分组的所有数据行都属于同一个子表,比如 SQL 请求只涉及一个 tablet,则 having 可以由 ChunkServer 完成
- Projection
- 对基本表的投影集成在 TableScan 中,由 ChunkServer 完成
- 对最终结果的投影有 MergeServer 完成
- GroupBy 如果读取数据只在一个子表上,由 ChunkServer 完成;否则,每台 ChunkServer 各自完成部分数据的分组操作,执行聚合运算后的部分结果,再由 MergeServer 合并最终结果
- Sort
- 如果读取的数据在一个子表上,由 ChunkServer 完成排序操作
- 由 ChunkServer 各自完成部分数据排序,再由 MergeServer 执行多路归并
- Limit 一般由 MergeServer 完成,如果请求只在一个子表上,由 ChunkServer 完成
- Distinct:类似 GroupBy,ChunkServer 完成部分去重,再由 MergeServer 完成整体去重
- MVCC 实现:写操作拆分为两步,事务版本为提交的系统时间,读事务只会读取事务开启之前提交的写事务的更新操作
- 预提交(多线程):事务执行线程先锁住待更新行,再将对数据行的操作追加到该行的未提交操作链表中
- 提交(单线程):
- 提交线程从提交队列中取出提交任务,将任务的操作日志追加到日志 buffer
- 如果日志 buffer 达到一定大小,则将 buffer 中的数据同步到备机,同时写入主机的磁盘日志文件
- 操作日志写成功后,将未提交行操作链表中的 cell 操作追加到已提交操作链表的末尾
- 释放锁并回复客户端写操作成功
- 锁机制
- 单行只写:预提交时对修改的数据行加写锁,事务提交时释放
- 多行只写:预提交时对多个数据行加写锁,事务提交时释放,采用两阶段提交实现
- 读写事务:读操作读某个版本的快照,写操作与只写事务相同
- 死锁处理:如果超过一定时间无法获取写锁,则自动回滚