Files
ChuBlog/docs/architecture.md
T

112 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 架构与组件
ChuSQL 采用客户端 / 服务端架构。正常运行时,只有数据库服务直接访问数据文件;离线初始化与恢复由 bootstrap 完成。
## 组件与访问路径
~~~text
Web / CLI / 其他客户端
↓ TCP
chusql-server
↓
SQL 引擎 → Rust 存储层 → 磁盘
~~~
| 组件 | 职责 |
| --- | --- |
| chusql-server | 登录、会话、鉴权、SQL 执行和事务 |
| chusql-web | Web 管理界面,通过 TCP 访问服务 |
| csql | 命令行客户端,通过 TCP 执行 SQL |
| chusql-core/engine | 解析、语义检查、优化及执行 |
| chusql-core/storage | catalog、页面、B+ 树、缓存、WAL 与持久化 |
| csql-bootstrap | 安装引导及离线系统目录修复、恢复、重置 |
服务默认监听 127.0.0.1:7777,Web 默认监听 127.0.0.1:7778。配置位置和平台数据目录见 [config.md](config.md)。
## 数据目录
[storage] data_dir 是持久化数据的根目录,诊断日志由 log_files 单独指定。
| 位置 | 内容 |
| --- | --- |
| system/ | 身份、凭据、角色、授权和预定义类型目录 |
| databases/<数据库名>/ | 业务数据库的 catalog、数据与索引 |
| WAL 与检查点文件 | 已提交写入的恢复记录及刷盘进度 |
安装只初始化系统数据库,业务数据库由用户创建。表存在性以 catalog 为准,不能仅凭数据文件判断。
## 会话与并发
- 每条 TCP 连接拥有独立会话,当前数据库和事务互不影响。
- 读请求可并行,写请求由存储层协调。
- Web 与 CLI 共享服务端的权限和执行规则,不直接读写数据目录。
## SQL 查询处理
查询依次经过解析、基于 schema 的语义检查、优化和执行。库名、表名、列名及别名在语义层解析;存储层使用精确的表名键。
| 能力 | 实现与边界 |
| --- | --- |
| 派生表 | 内层独立解析,必须有别名,不能引用外层列;输出列按别名暴露 |
| WITH / CTE | 解析时展开为派生表;不支持递归或物化,多次引用分别执行 |
| ANY / ALL | 按 OR / AND 的三值逻辑求值;空集的 ANY 为假、ALL 为真 |
| 子查询复用 | Filter 和计算列按外层绑定分组;JOIN 条件按首次遇到的绑定惰性复用 |
| 成本估算 | 使用行数、不同值数和数值列的 16 桶等宽直方图 |
| 索引选择 | 优化器判断适用条件与成本,存储层管理实际索引 |
派生表可根据 schema 和透明算子估计行数并参与安全的连接重排;缺统计或可能报错时保守处理。输出列投影可下推,但保留所有计算项的求值,避免隐藏错误。内存存储提供实时行数和封顶去重统计。JOIN 条件的子查询在首次遇到外层绑定时求值,缓存仅限当前连接;空行对不触发求值,普通条件仍逐行计算。尚无半连接或通用物化。统计信息只影响计划选择,优化不能改变查询结果语义。
完整 SQL 写法及限制见 [syntax.md](syntax.md)。
## 快照事务
| 阶段 | 行为 |
| --- | --- |
| BEGIN | 将当前数据库读为会话内存快照 |
| 事务内执行 | 读取快照与自身修改,看不到其他连接后续提交 |
| SAVEPOINT | 保存当前快照;回滚可退回指定保存点 |
| COMMIT | 比对基线与现值,确认无写写冲突后原子应用差分 |
| ROLLBACK | 丢弃会话快照与保存点 |
有整数 id 的表按行比对并提交差分;其他表按整表替换提交。发生冲突时返回 serialization_failure 并保留事务,由调用方回滚或重试。事务内不支持 DDL 或切换数据库。
## WAL 与崩溃恢复
1. 一组写操作与提交标记写入 WAL,每条记录带递增 LSN。
2. 数据和 catalog 刷盘后,检查点推进到已完成提交的 LSN。
3. 按检查点截断日志前缀,保留尚未确认刷盘的记录。
4. 重启时只重放检查点之后的已提交组,丢弃未提交组,并进行幂等检查。
建表、删表、建索引、删索引和数据修改均进入 WAL。LSN 跨重启续号,SystemStatus 的 last_lsn 表示检查点 LSN。
若系统目录损坏导致服务无法启动,使用离线 bootstrap。repair、recover 与 reset 的范围及操作步骤见 [bootstrap.md](bootstrap.md)。
## 页面与空间回收
- 删除行先将槽位标记为墓碑。
- 死空间达到页大小的四分之一时,随删除整理页内活行。
- 整理保留槽位编号,索引中的页号与槽号仍有效。
- compact 通常逐页整理;存在 DROP COLUMN 留下的隐藏列时整表重写。
不进行跨页填洞;没有 ORDER BY 时仍保留当前扫描顺序,但应用应使用显式排序获得稳定结果。
## 身份、授权与系统目录
系统表统一使用 __system_ 前缀,身份与凭据目录对普通语句隐藏。SUPERUSER 拥有最高权限,system_catalog_manager 提供受限目录管理能力;两者不通过角色成员关系继承。
| 机制 | 行为 |
| --- | --- |
| 角色继承 | 沿成员关系取得权限并集;拒绝自继承与环 |
| 表级授权 | 支持 SELECT、INSERT、UPDATE、DELETE 和 ALL |
| 转授权 | WITH GRANT OPTION 允许将持有的权限授予其他身份 |
| 撤销 | 管理员撤销权限及对应转授权能力;当前不级联撤销已转授权限 |
| 对象名称 | 授权前补全为库.表,检查与持久化使用同一名称 |
类型目录说明见 [types.md](types.md),身份字段与权限边界见 [users-and-roles.md](users-and-roles.md)。
## 权限变更与会话失效
账号、属性和授权变化会标记受影响的在线连接。角色变化先展开成员关系,确定涉及的登录身份。
TCP 连接在下一次请求时返回 unauthorized 并关闭;空闲连接不被强行中断。权限逐条查询,避免继续使用旧授权。Web 会话还通过账号版本校验,口令或身份变更使旧凭据失效。