服务器保留策略
为自托管 Kaiwu 服务器配置自动清理,且不改变默认的永久保留行为。
Kaiwu 服务端保留策略为可选功能,默认处于禁用状态。
若未设置任何保留相关的环境变量,服务端将永久保留会话及其他各类记录。说明:环境变量推荐优先使用 KAIWU_ 前缀,旧版 KAIWU_ 前缀别名仍保持兼容支持。
保留策略目前覆盖的范围
保留策略由一个服务端清理工作线程实现,底层依托统一的领域注册表。注册表中的每一项分别管理自身的领域 ID、环境变量键名、策略形态及删除规则,从而确保配置解析、执行逻辑与对外公开信息所依据的领域列表始终严格一致。该策略支持清理以下内容:
- 会话
- 陈旧非活跃会话中的会话消息
- 侧链消息(生命周期更短,可单独配置)
- 账号变更记录
- 语音会话租约
- 用户动态条目
- 会话分享访问日志
- 公开分享访问日志
- 终端认证请求
- 账号认证请求
- 认证配对会话
- 重复防重键
- 全局锁
- 自动化运行记录
- 自动化运行事件
会话保留策略的工作机制
会话清理规则设计得相当克制。
当满足 KAIWU_SERVER_RETENTION__SESSIONS__MODE=delete_inactive 时,服务端仅在以下条件全部成立的前提下,才会删除整个会话树:
- 会话
updatedAt早于配置的截止时间 - 会话
lastActiveAt早于配置的截止时间 - 持久化存储的会话
active标记为false - 运行时当前未在内存中检测到该活跃会话
- 最终的删除事务在执行任何清理操作前,会再次校验相同的截止时间防线
这意味着,服务端无需检查或解密已存储的会话记录内容,即可执行当前的会话清理规则。
会话消息保留策略的工作机制
会话消息的清理规则独立于全量会话删除。当满足 KAIWU_SERVER_RETENTION__SESSION_MESSAGES__MODE=delete_older_than 时,服务端仅清理同时符合以下所有条件的消息:
- 早于配置的消息截止时间
- 所属会话的
active标记为false - 所属会话的
updatedAt与lastActiveAt均早于该截止时间 - 低于会话已读/就绪水位线,且不在保留的尾部范围内
- 所属会话当前未被运行时在内存中检测为活跃状态
最终的删除操作会再次校验该非活跃陈旧会话防线。此规则将消息内容视为不透明 JSON 处理,因此静态加密会话与明文会话均复用相同的保留清理路径。
侧链消息保留
侧链保留策略是一项附加机制,专用于子代理、嵌套工具及工作流代理的会话记录。该策略不会改动主会话记录,亦不要求父会话处于非活跃状态。仅当侧链最新存储的消息早于配置的截止时间时,该侧链才符合清理条件;因此,近期活跃的侧链会得到完整保留。符合条件的数据行将在有界的事务中分批移除。
通用的 SESSION_MESSAGES 策略语义保持不变,仍可在陈旧的非活跃会话中同时清理主链与侧链数据行。若希望永久保留主会话记录,同时让陈旧侧链自动过期,可将 SESSION_MESSAGES=keep_forever 配置为有限时长的 SESSION_SIDECHAIN_MESSAGES 策略。
已发布的 v1 版服务端功能尚不包含消息级保留策略。因此,通用消息策略与侧链消息策略仍属运维可见的配置项,在 v1 接口响应中已被忽略,以便独立升级后的服务端仍能被现存的严格 v1 客户端正常解析。
默认行为
仅在以下两个条件同时满足时,保留策略才会正式生效:
KAIWU_SERVER_RETENTION__ENABLED=1- 至少为一个保留领域配置了有限时长的策略
若保留功能处于禁用状态,或所有领域均保持为 keep_forever,则实际策略依然是对所有领域永久保留。
全局保留环境变量
以下环境变量用于控制保留工作线程本身:
KAIWU_SERVER_RETENTION__ENABLED=1
KAIWU_SERVER_RETENTION__INTERVAL_MS=3600000
KAIWU_SERVER_RETENTION__BATCH_SIZE=500
KAIWU_SERVER_RETENTION__MAX_DELETES_PER_RULE_PER_RUN=100000
KAIWU_SERVER_RETENTION__MAX_CANDIDATES_PER_RULE_PER_RUN=10000
KAIWU_SERVER_RETENTION__SWEEP_TIME_BUDGET_MS=10000
KAIWU_SERVER_RETENTION__DRY_RUN=0KAIWU_SERVER_RETENTION__ENABLED0或未设置:保留功能实际处于关闭状态1:在至少一个领域配置了有限时长策略时,允许保留工作线程运行
KAIWU_SERVER_RETENTION__INTERVAL_MS- 清理轮询间隔(单位:毫秒)
- 默认值:
3600000(1 小时)
KAIWU_SERVER_RETENTION__BATCH_SIZE- 单个数据库分页中查询或删除的最大行数
- 默认值:
500
KAIWU_SERVER_RETENTION__MAX_DELETES_PER_RULE_PER_RUN- 单次清理中各规则实际执行删除操作的硬性上限
- 默认值:
100000
KAIWU_SERVER_RETENTION__MAX_CANDIDATES_PER_RULE_PER_RUN- 单次清理中各规则审查候选记录数的硬性上限
- 默认值:
10000
KAIWU_SERVER_RETENTION__SWEEP_TIME_BUDGET_MS- 单次完整清理共享的物理时间预算
- 默认值:
10000(10 秒)
KAIWU_SERVER_RETENTION__DRY_RUN1:仅记录拟删除的内容,不实际执行删除0或未设置:正常执行删除
保留工作线程在服务端启动时读取这些配置值,立即执行一轮清理,随后按设定的间隔周期性运行。更改保留配置后,请重启服务端。在单次清理中,线程会依注册表顺序为每个启用的领域分配一个有界的数据库分页配额,随后针对仍有待处理任务的领域开启下一轮清理。当数据处理完毕,或达到行数、候选数、物理时间预算上限时,清理即行终止。下次排期清理将基于持久化游标继续检索侧链。运行成功后,系统会记录各规则的删除数、候选审查数、数据库分页数、终止原因以及该轮运行是否为演练模式。
默认 1 小时的间隔可确保数据过期处理相对及时,并在服务端积压时提供每日最多 24 次有界清理机会。系统支持设置更短的间隔,但建议将间隔维持在充裕高于单次清理时间预算的水平。工作线程会在单进程内自动跳过重叠的清理任务,并借助数据库锁防止多个服务端副本并发清理。
会话策略环境变量
会话采用专用的策略配置格式:
KAIWU_SERVER_RETENTION__SESSIONS__MODE=delete_inactive
KAIWU_SERVER_RETENTION__SESSIONS__INACTIVITY_DAYS=30支持的会话模式:
keep_foreverdelete_inactive
KAIWU_SERVER_RETENTION__SESSIONS__INACTIVITY_DAYS 必须为正整数;当模式设为 delete_inactive 时,该项为必填。
基于时效的领域策略环境变量
所有非会话类的保留领域均采用统一的双键配置模式:
KAIWU_SERVER_RETENTION__<DOMAIN>__MODE=delete_older_than
KAIWU_SERVER_RETENTION__<DOMAIN>__DAYS=30支持的时效模式:
keep_foreverdelete_older_than
支持的领域名称:
SESSION_MESSAGESSESSION_SIDECHAIN_MESSAGESACCOUNT_CHANGESVOICE_SESSION_LEASESUSER_FEED_ITEMSSESSION_SHARE_ACCESS_LOGSPUBLIC_SHARE_ACCESS_LOGSTERMINAL_AUTH_REQUESTSACCOUNT_AUTH_REQUESTSAUTH_PAIRING_SESSIONSREPEAT_KEYSGLOBAL_LOCKSAUTOMATION_RUNSAUTOMATION_RUN_EVENTS
配置示例:
KAIWU_SERVER_RETENTION__ACCOUNT_CHANGES__MODE=delete_older_than
KAIWU_SERVER_RETENTION__ACCOUNT_CHANGES__DAYS=30推荐上线流程
建议采取稳健的推进方式:
- 仅启用实际需要的规则。
- 优先开启
KAIWU_SERVER_RETENTION__DRY_RUN=1。 - 先从会话保留以及一两个短期的运维领域(如认证请求或访问日志)开始试点。
- 查看服务端日志,确认拟删除的记录完全符合预期。
- 待演练输出与目标策略确认无误后,再将
DRY_RUN改回0。
对于大多数自托管环境,推荐首选如下生产策略:
KAIWU_SERVER_RETENTION__ENABLED=1
KAIWU_SERVER_RETENTION__INTERVAL_MS=3600000
KAIWU_SERVER_RETENTION__BATCH_SIZE=500
KAIWU_SERVER_RETENTION__MAX_DELETES_PER_RULE_PER_RUN=100000
KAIWU_SERVER_RETENTION__MAX_CANDIDATES_PER_RULE_PER_RUN=10000
KAIWU_SERVER_RETENTION__SWEEP_TIME_BUDGET_MS=10000
KAIWU_SERVER_RETENTION__SESSIONS__MODE=delete_inactive
KAIWU_SERVER_RETENTION__SESSIONS__INACTIVITY_DAYS=30
KAIWU_SERVER_RETENTION__SESSION_MESSAGES__MODE=delete_older_than
KAIWU_SERVER_RETENTION__SESSION_MESSAGES__DAYS=30
KAIWU_SERVER_RETENTION__SESSION_SIDECHAIN_MESSAGES__MODE=delete_older_than
KAIWU_SERVER_RETENTION__SESSION_SIDECHAIN_MESSAGES__DAYS=14
KAIWU_SERVER_RETENTION__ACCOUNT_CHANGES__MODE=delete_older_than
KAIWU_SERVER_RETENTION__ACCOUNT_CHANGES__DAYS=30
KAIWU_SERVER_RETENTION__TERMINAL_AUTH_REQUESTS__MODE=delete_older_than
KAIWU_SERVER_RETENTION__TERMINAL_AUTH_REQUESTS__DAYS=7
KAIWU_SERVER_RETENTION__ACCOUNT_AUTH_REQUESTS__MODE=delete_older_than
KAIWU_SERVER_RETENTION__ACCOUNT_AUTH_REQUESTS__DAYS=7客户端界面呈现
Kaiwu 会向用户完整公开服务端的保留策略,方便用户清晰了解哪些数据会保留、哪些数据最终会被清理。UI 会以通用方式渲染服务端返回的领域列表;即使新版服务端新增了领域 ID 而客户端尚未提供专用文案,界面也能正常呈现。
目前,以下位置已公开该信息:
- 当前服务端的设置界面
- 登录与注册入口界面(认证前展示)
- 受有限保留策略影响的会话详情
- 已保存的服务端记录列表项
客户端首先会请求无需认证的 GET /v2/retention-policy 接口,该接口返回当前生效领域的完整数组。旧版服务端则会回退到 GET /v1/features,在 capabilities.server.retention 字段下返回;鉴于 v1 无法表达消息级策略,该旧版响应将被明确视作局部数据。
运维注意事项
- 会话保留依赖
updatedAt、lastActiveAt及active等服务端元数据进行判定,不会对存储的消息执行解密。 - 会话消息保留不会解析消息外层结构;针对加密内容与明文内容,均执行统一的会话/水位线防线逻辑。
- 账号变更保留可能会推进服务端的
changesFloor。在陈旧的账号变更记录被清理后,过于久远的/v2/changes游标可能会失效并返回410 cursor-gone。 - 保留策略执行的删除均为物理删除。系统在删除前未内置隔离区或归档阶段。
- 与所有基于时间戳的清理机制一样,保留策略依赖精准的服务端时间与正确的存储时间戳。若手动篡改数据库时间戳,或系统时钟发生严重偏差,可能导致策略误判。
数据清理后的 SQLite 维护
对于轻量级服务端 SQLite 部署,当 KAIWU_DB_PROVIDER=sqlite(或旧版 KAIWU_DB_PROVIDER=sqlite)时,后台将运行两个维护轮询:
- WAL 检查点:每隔
KAIWU_SQLITE_WAL_CHECKPOINT_INTERVAL_MS(兼容KAIWU_SQLITE_WAL_CHECKPOINT_INTERVAL_MS)毫秒执行一次,默认60000,使用PRAGMA wal_checkpoint(TRUNCATE)模式。 - 增量整理(Incremental Vacuum):每隔
KAIWU_SQLITE_INCREMENTAL_VACUUM_INTERVAL_MS(兼容KAIWU_SQLITE_INCREMENTAL_VACUUM_INTERVAL_MS)毫秒执行一次,默认21600000(6 小时),使用PRAGMA incremental_vacuum(N)模式,每批次整理KAIWU_SQLITE_INCREMENTAL_VACUUM_PAGES页,默认1000页。
这两个维护轮询均采用独立的维护数据库客户端,并遵循由 KAIWU_SQLITE_WAL_CHECKPOINT_BUSY_TIMEOUT_MS(兼容 KAIWU_SQLITE_WAL_CHECKPOINT_BUSY_TIMEOUT_MS)控制的 SQLite 忙碌超时机制(默认 5000)。将间隔配置为 0 即可禁用对应的轮询任务。服务端在运行进程中特意不执行全量 VACUUM,原因是全量整理会重写数据库并可能长时间阻塞写入;请仅在专门的停机维护窗口内执行离线全量 VACUUM。
仅在数据库创建时启用了 SQLite 增量自动清理功能,增量整理才能将页面空间实际归还给文件系统。否则,被删除的页面仅可在现有数据库文件内部复用;若要缩小文件本身的体积,仍需在离线全量 VACUUM 维护窗口内处理。
永久保留配置示例
若希望显式沿用当前的永久保留行为,可不设置任何保留环境变量,或按如下配置:
KAIWU_SERVER_RETENTION__ENABLED=030 天非活跃会话演练示例
KAIWU_SERVER_RETENTION__ENABLED=1
KAIWU_SERVER_RETENTION__DRY_RUN=1
KAIWU_SERVER_RETENTION__SESSIONS__MODE=delete_inactive
KAIWU_SERVER_RETENTION__SESSIONS__INACTIVITY_DAYS=30