# 架构与组件 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 会话还通过账号版本校验,口令或身份变更使旧凭据失效。