5.9 KiB
配置库与日志库分离
目标
LinkPort 将配置数据与持续增长的日志数据拆分,避免审计记录、命令结果和连接事件持续放大配置库,进而拖慢配置备份、启动检查和空间回收。
data/linkport.sqlite是配置库,保存目标、网关、账号、加密配置和系统设置等需要一致备份的状态。data/audit/*.sqlite是日志分片库,保存审计与日志记录,只提供追加写入和查询,不作为配置状态的来源。
日志仍使用 SQLite。当前负载以单机追加和按时间、主键查询为主,SQLite WAL 能保留单程序部署、无需额外服务和可直接备份的特性;按文件分片后也能限制单库增长。引入独立日志服务会增加部署、认证、升级和恢复成本,当前没有足以抵消这些成本的查询或吞吐需求。运行时已将命令审计、命令结果与输出、连接事件写入日志分片,并跨活动及归档分片查询。
WAL 与按大小切分
每个活动日志分片使用 SQLite WAL 模式。当天活动文件名为 YYYY-MM-DD.sqlite,轮转后的归档名为 YYYY-MM-DD.partNNNN.sqlite。切分对象是 data/audit 下的完整 SQLite 分片,不是直接截断或单独归档 SQLite 边车文件。
- 默认分片上限为
256 MiB。 - UI 提供“日志分片大小”配置,可在
16 MiB到4 GiB之间调整;边界按二进制字节计算,即1 MiB = 1024 * 1024字节。 - 每次为新命令、事件或迁移批次选择写入分片前,核算活动
.sqlite、-wal、-shm三类文件的当前总大小,并以“当前大小 + 本次写入估算值”判断是否超过上限;预计超过时先轮转,再写入新的活动分片。 - 命令记录及其结果、输出始终保存在同一个分片。结果和输出不会为满足上限而拆到其他分片;单条记录、一个提交批次或一组命令数据可能使分片超过上限,后续新写入再触发轮转。
- 调小上限后,活动分片在下一次写入前检查时轮转;调大上限只影响活动分片和后续分片。既有归档分片不自动拆分、合并或重写。
- 大小切分不是保留期策略。轮转不得自行删除旧分片;查询需要覆盖活动分片和所有封存分片,并保持既有时间、主键排序与分页语义。
轮转由单一写入协调路径串行化。实现先对活动分片执行 PRAGMA wal_checkpoint(TRUNCATE),再切换到 journal_mode=DELETE、关闭数据库句柄并清理遗留的 -wal 与 -shm 文件。随后扫描同一天已有的 partNNNN,按当前最大编号加一归档活动 .sqlite,再以原日期文件名创建新的 WAL 活动分片。该顺序使归档文件自包含,并避免复用已有 part 名称。
迁移流程
从现有 data/linkport.sqlite 迁出日志前,必须停止相关服务或进入禁止日志写入的维护状态,并备份完整 data 目录。迁移使用可恢复的小批次,不执行按时间或其他宽条件的一次性删除:
- 首次迁移先写入
pending标记。旧命令和事件以明确主键、固定小批量读取;命令与其结果、输出作为一组选择同一个目标分片。 - 将小批记录写入
data/audit/*.sqlite。插入冲突时逐字段核对既有目标记录;命令、结果、输出和事件的持久化字段不一致即停止迁移,不覆盖冲突数据。 - 目标分片事务提交成功后,才在配置库事务中按该批明确的命令 ID 或事件 ID 删除源记录,并核对命令或事件主记录的受影响行数。跨库提交中断后,下一次启动会识别目标已存在且字段相同的记录,继续完成源端删除,不会扩大删除条件。
- 所有源日志表清空后才删除旧表,并对
data/linkport.sqlite执行一次VACUUM。VACUUM成功后写入done标记并移除pending;如果VACUUM失败,pending保留,下一次启动会再次执行压缩,直到成功完成。
VACUUM 不在每批迁移后执行;它需要额外临时磁盘空间并会独占配置库。部署迁移前应确认可用空间、保持服务停止,并保留迁移前备份,直至新配置库和全部日志分片验收完成。
兼容性与运维影响
- 完整备份和恢复必须同时覆盖
data/linkport.sqlite、data/audit/*.sqlite及活动分片的 SQLite 边车文件;仅复制配置库不再包含日志。 - 迁移后,旧版本无法读取新日志分片;由于已校验记录会从配置库删除,回退必须停服并恢复迁移前的完整数据目录,不能只替换可执行文件。
- 日志查询、导出和清理显式遍历分片。配置快照只包含
data/linkport.sqlite的配置状态,不包含data/audit/*.sqlite日志;需要完整日志的运维备份必须单独覆盖全部日志分片及活动边车文件。 - 分片大小设置保存在配置库。超出
16 MiB到4 GiB范围的 API 或导入值应拒绝,不能静默截断;旧配置缺少该值时使用256 MiB。 - 迁移和轮转不得删除、覆盖现有
data/audit文件。文件命名必须稳定且避免复用已有名称,便于中断后恢复和按顺序查询。
验证状态
上述日志拆分、轮转、迁移恢复、设置接口和配置快照边界均已有运行时代码。用户运行前端构建时,vue-tsc 在 OpsPanel.vue 的日志大小边界计算处报告可选值参与除法的类型错误;该处现已改为先判断设置是否存在,再读取 minBytes 和 maxAllowedBytes。静态审查还补充了仅剩 pending 标记时的重启恢复用例,并修正事件旧表断言遗漏的查询错误检查。修复后按要求未重跑类型检查、构建或测试,未启动服务,也未执行真实数据库迁移,因此当前只声明源码与本文的一致性静态审查以及 git diff --check 通过。主代理此前已只读列出 data 下相关文件,本轮未向真实 data/linkport.sqlite 或 data/audit 写入数据。