本页内容

本页内容

技术参考

完整性、故障排除和恢复

网关数据库所有权

网关进程拥有每个 OpenClaw 数据库及其状态。进程内写入器收据使跨工作线程和句柄的缓存行无效;当缓存无法覆盖时,使用直接读取。切勿添加运行时外部提交探针(PRAGMA data_version、版本观察、外部观察范围);触摸时取下。外部编写者,包括 CLI、Doctor、cron、插件子级:必须使用 Gateway 或在 Gateway 停止时持有独占所有权。保留效果边界处的实时权限检查和多语句读取的一致快照。

完整性检查

每个进程负载的每个物理数据库的准入都会验证 SQLite 格式、模式、所需的索引和所需的完整性,除非它可以重复使用匹配的干净关闭密封。该进程与所有句柄和工作隔离共享承认的事实,同时数据库保持打开状态。最终关闭会释放那些内存中的有效负载。重新打开,重复使用匹配的密封件,无需验证 SQL;未检查点或失败的关闭需要重新入场。当前所有权、实时写入权限、行缓存新鲜度和持久隔离拒绝仍然是单独的检查。印章永远不会推翻已记录的腐败拒绝记录。这包括隔离存储格式检查;现有的索引持久隔离排警卫仍然观察到有记录的腐败。跨打开、范围、请求和空闲关闭也共享架构版本和表存在事实。切勿添加重复的格式检查;触摸时将其移除。使用 fstat(而不是 SQL)按卷、inode 和出生时间识别替换文件。 Migration/repair 所有者在其 DDL 之后发布新事实;医生和显式验证保留全面检查。

每个拥有的数据库旁边都可以有一个名为 <database>.seal 的常规文件,例如 openclaw.sqlite.seal。数据库准入所有者在最终接受的写入者解决、TRUNCATE 检查点完成并且本机数据库成功关闭后写入此文件。失败或未完成的清理无法发布印章。该印章包含已承认的模式和完整性事实、模式身份、上次完整验证的时间以及最终的物理文件元数据。它是可重构的验证元数据,而不是数据库状态或备份。

完成的内存索引模式收据也可以在干净关闭后保存下来。它们的范围仍然是已验证的缓存、FTS 和标记器设置,因此未更改的重新启动会跳过内存架构设置和生成的代理架构刷新。所有者控制的 FTS 和向量替换在保留承认的表合同时在提交后重新发布该收据。回滚无法发布替换收据。更改的设置、其他进程中的 DDL 或丢失或无效的密封采用普通内存模式准入路径。不正常的关闭仍然需要完整性验证。导入行回填仍在运行。

启动时,仅当其 JSON 解析、其短校验和匹配并且以下所有内容与当前数据库匹配时,准入才会接受密封:设备、索引节点、稳定诞生时间、字节大小、纳秒修改时间和模式标识。元数据来自所有者通过 fstat 保留的文件描述符,而不是数据库查询。 WAL 和回滚日志文件必须不存在或为空。最后一次完整验证不得超过 7 天;清洁关闭和密封重复使用不会提前该时间戳。在 Linux 上,Node 可以用更改时间代替不可用的出生时间,现有物理文件身份策略使用稳定的未知出生时间值。

架构标识涵盖应用程序版本、规范 SQL 定义和准入策略修订。提交和构建 ID 不会使其他兼容构建的密封失效。维护人员必须针对规范 SQL 中未反映的迁移或模式版本更改以及验证规则或序列化准入事实的更改推进策略修订。相同版本的会话专栏是入学先决条件,而不是可选的读者预测。在 STARTUP_ADDITIVE_AGENT_COLUMN_DEFINITIONS 中声明它们:相同的声明驱动安装、待修复检测和已保存目录准入。在发布任何已完成的验证事实之前,密封加载会检查这些列的已保存目录。缺少的特征本地表仍然不存在。即使架构版本未更改,缺少所需列的现有表也无法重用其密封。

启动使每个受影响的代理不可用,直到其可写准入所有者在现有维护权限下安装列并发布已提交的架构事实。会话准备和随后的读者运行;冷读者在准备会话查询之前拒绝待处理的附加修复。即使没有版本交叉调用 Doctor,相同架构管理的激活也依赖于此顺序。请勿添加独立读卡器迁移或控制器 SQL 维修。回归覆盖必须证明由同一版本安装程序安装的每个列都在准入事实中得到体现。完整的先前构建目录保留密封重复使用,无需验证 SQL;仅添加要求并不会使目录中已满足这些要求的密封件失效。

从旧的印章身份格式更新需要一次完整的验证;后续的兼容版本会重复使用新的密封件。受管理的耗尽和随后的中断使用普通关闭,并且一旦其编写者解决就可以发布印章。在成功关闭之前强制终止无法验证数据库。

匹配的印章提供先前承认的事实,而无需再次复制或检查数据库的启动状态快照、就绪情况、模式预检或完整性验证。它还避免了准备后验证扫描。丢失、畸形、陈旧或不匹配的密封件将采用正常的完整验证路径。杀死写入者、从外部更改文件、更改其模式标识或恢复不同的物理文件可防止密封重用。入院时会检查 7 天的限制;它不会引入每日运行时扫描或新计时器。

入馆后第一次写信之前,主人会解开封印。显式维护也会在检查点或重写数据库之前使其失效。该印章是允许的小型边车,仅在成功关闭后才发布。接受是原子的:部分有效负载无法提供承认的事实。发布使用带有校验和的纯文件写入:它不需要临时文件重命名或 fsync 协议。撕裂的写入无法解析或校验和验证,并回退到完整检查。如果崩溃丢失了取消链接但保留了数据库写入,则非空 WAL 或更改的文件元数据将拒绝旧的密封。如果断电导致取消链接和数据库写入都丢失,则数据库仍处于密封状态,并且该密封仍然正确。

此优化故意无法检测保留所有比较元数据的静默损坏。 SQLite正常使用时可能检测到;否则下一次完整验证会捕获它。 7 天的接纳间隔限制了旧的全面验证证据的重复使用。校验和可保护小封条免受不完整写入的影响;它不是数据库内容的哈希值。

Doctor,包括openclaw doctor --fix、显式复制文件验证、备份验证和压缩保留其完整检查,无论任何密封如何。迁移和修复所有者在突变之前进行验证,验证其更改,并在成功解决后发布新的承认的事实。他们不能将印章重复用于已更改的模式。备份和恢复发布独立的SQLite文件;即使相邻的旧海豹幸存下来,他们的新物理身份也需要重新接纳。部署控制器将迁移和恢复委托给这些本机更新所有者,因此它不会独立保留或验证密封。此印章格式不需要更改数据库架构。

代理架构迁移后,架构所有者会在其经过验证的连接仍处于打开状态时注册数据库。稍后在同一个 Doctor 进程中打开可以重用该许可,而不是重复其完整的完整性扫描。迁移前完整性检查、恢复备份和重新启动密封要求保持不变。

什么时候 检查
使用匹配的、最近的清洁关闭密封件启动 匹配校验和、模式标识、文件元数据和空日志;无需启动或准备后扫描即可重复使用已承认的事实
无需可重复使用的密封件即可启动 运行正常的完整格式、模式、规范索引、完整性和外键验证
同一进程重新打开或新的工作者 重复使用实时文件装订事实或匹配的印章;保留当前所有权和持久的隔离行检查
在待处理迁移之前 运行完整的完整性、外键、角色、架构和索引检查
迁移或修复后 通过现有所有者验证更改并发布承诺的事实
Doctor、备份验证和压缩 在接受或重写数据库之前运行全面检查

网关代理检查共享五秒的前台等待时间。当初创企业入场所有者完成检查并完成检查时,未完工的商店仍然无法使用session/model听者准备好后的准备工作。其他代理和Control UI可以同时开始。检查在前台准备就绪期间开始,并在没有空闲重试延迟的情况下继续进行。延迟可写准入在 Gateway sidecar 准备就绪后开始,最多同时打开两个数据库。缓慢打开和索引修复因此无法占用共享SQLite插件服务启动之前的工作人员。然后,代理本地会话准备同时与最多四个代理一起运行。仅有的credential/model出版和最终录取按代理完成会话准备的顺序连载;缓慢的开放或迁移并不能保持出版轮转。准备情况报告待定所需商店agentDatabases网关检查不会失败;已确认的数据库故障仍然无法就绪。验证期限、脏封闭检查和洁净封闭密封要求不变;仅仅因为前台等待过期,延迟存储永远不会被允许写入。当代理完成准入时,聊天元数据和模型列表会刷新,因此它们包括新恢复的商店。更新金丝雀保留前台检查和严格的数据库准备状态,因为它们不会激活后台代理准备。

当当前文件没有可重用的干净关闭密封时,丢失或更改的所需索引定义也会将代理推迟到同一启动所有者。前台检查比较模式元数据而不重建索引。 Sidecar 准备就绪后,SQLite 工作线程会在接纳代理之前自动修复索引。该代理的会话读写仍然不可用;健康,Control UI,并承认代理可以继续。修复日志会命名重建的索引和经过的时间。推迟的准备时间包括修复;前台 sessions.admission 没有。不重建匹配定义。修复提交之前发生的崩溃会回滚其 DDL,并且下次启动时会再次检测到剩余的漂移。物理损坏仍然需要明确的医生修复。

在实时生命周期内,当没有外部或未知进程持有写入者租约时,已承认的所有者仍然可以将其可撤销的、文件绑定的运行时证明借给另一个句柄。这包括在最后一个本地租约结束后重新开放。该证明不需要持久的清洁关闭密封。具有匹配进程 ID 和开始时间的对等租约不会消耗或阻止该印章的发布;每个句柄保留其自己的租约,直到清理完成。显式失效会撤销共享的运行时证明以及持久元数据,包括过时的准入和未解决的 Worker 清理。成功的本机关闭与读取器阻止的检查点保持验证未密封并保留实时运行时证明。稍后的最后一个编写者可以在完成检查点和本机关闭后证明该验证;关闭失败或不确定的存储错误都会撤销两者。新进程中的首次打开仍然需要匹配干净关闭元数据或准入门。在同一进程中空闲关闭会保留已承认的事实。清理工作人员和本地代理执行工作人员在他们现有的作者许可下借用了该证明。清理工作人员完成后将新的验证返回给网关。回收为每个数据库保留一个 Worker 连接,因此交替代理重用其已承认的句柄。请求仍共享存档 FIFO。每个 Worker 在 30 分钟空闲后、数据库关闭或在严重内存压力下空闲时退出;失败的清理保留其原始租约直至结算。完整性撤销和更新行为保持不变。在单向网关关闭耗尽期间,空闲的本机执行和保留的回收连接立即关闭。当最终借款人释放它们时,活跃执行结束;主动回收请求在关闭前得到解决。外部清理工作仍有待进行。仅取消并不能证明密封:最后一个租约仍必须完成其检查点和本机关闭。重新启动恢复标记和回复取消先于后台服务加入,包括计划的连续交付。耗尽超时后,进程拥有的停止或外部重新启动在接受的持久性、内存准备和数据库关闭解决后退出,而无需等待不相关的服务拆除。超时日志记录剩余工作计数。数据库所有者在验证印章之前撤销废弃的资源、加入其已接受的写入并释放其租约;活跃或失败的作家仍然会阻止认证。在数据库关闭之前接受身份验证使用、帐户保存、提及、工作树结算和沙箱删除,包括在获取本地编写器之前的准备工作。计划的交付保留其网关所有者,因此重新启动取消会影响其回复许可。每个路径的数据库报废独立完成。资源已解决的数据库可以发布其干净关闭密封,而另一个数据库仍然拥有待处理的工作。在本机关闭之前,每个路径仍会加入其已接受的写入器、挂起的打开和 WAL 维护。选定的根拒绝新的本地打开和新的资源接纳,直到每条路径都解决,包括失败的关闭;接受的清理仍然可以使用其现有的承认的连接。离线维护可以在操作策略撤销后释放已拥有的租约,同时保留其原始物理数据库托管权。该清理权限不允许新的普通工作或替换数据库。宽限期关闭后,一旦最终借用者释放缓存的本机句柄,它们也会通过正常的空闲逐出路径退出。它们不会等待重新启动标记或普通的 30 分钟空闲窗口。接受的清理可以通过正常入场重新开放,这会使密封再次失效。在数据库依赖项退出之前,所需的子代理清理在耗尽期间仍由其网关跟踪,包括子会话删除。普通RPC入场保持关闭; cleanup 保留其原始网关和会话生成。需要另一个连接的清理使用普通的准入,并在再次写入之前使密封失效。写入期间的强制退出仍然需要准入门。这不会更改架构、更新或回滚合同。

本机执行工作人员借用主机证明,而另一个句柄保留它,或者在最终关闭后重复使用匹配的密封。接收开启者重新检查物理文件身份和共享撤销单元;最终关闭释放内存中证明。当本机执行建立第一个运行时证明时,它会通过现有的准入返回该证明,以便以后的清理工作人员可以在没有主机的情况下重用它SQLite打开。主机只接受已承认的物理文件且验证状态未更改;开放期间的撤销会拒绝切换。

Startup 会在没有会话验证收据的情况下对每个数据库进行一次认证,包括带有空待验证队列的空会话源。成功的会话验证在最终授权的批量交易中记录 session_key_contract.canonical_ready。此可为空的 TEXT 列是在首次认证时添加的,而不更改架构版本。它的收据绑定了代理和物理文件生成,包括设备和索引节点。 Node 将创建时间与修改元数据区分开来的平台上包含创建时间。在 Linux 上,Node 可以将更改时间报告为出生时间,因此数据库标识使用稳定的未知创建值。现有的 Linux 收据通过同一验证所有者重新认证一次;不需要架构迁移。在以后的启动中,未更改的空存储和填充存储会重用第一个证明并检查待处理队列;普通会话写入仍然标记更改的行以进行验证。仍然需要精确的失效触发器。副本和替换文件需要自己的第一个证明,即使它们导入的待处理队列为空。该收据不证明物理完整性、替换上述完整性策略或覆盖显式进程本地撤销。老读者可以忽略可为空的列;备份和回滚保留其现有的行生存期。

Database replacement, quarantine, and failed admission discard applicable verification.普通的原生封闭可以将其保存在洁净封闭的密封中。 医生维护在耗尽代理连接后和原始维护可以运行之前丢弃记住的运行时验证. Pending migrations still run full checks, 和必需的索引修复在提交之前验证其结果, then publish the new admitted facts.所有权和当前写入权限绝不会从完整性结果中借用。

共享状态运行时打开和自动启动准备会聚合支持的架构添加,并保留旧架构版本的原子升级。新添加的受支持列在同一事务中接收其所需的内容转换。当应用程序版本更改时,打开不会对已存在的列重新运行历史行回填。跑步openclaw doctor --fix在更新维护期间修复历史记帐或遗留有效负载字段。仍包含已退役的当前模式数据库cron_run_logs表需要 Doctor 才能在运行时打开它; Doctor 将其保留的历史导入runtime = 'cron'行task_runs在删除旧表之前以原子方式进行。现有的 Doctor 迁移与 Tasks 运行时删除是分开的,后者不会添加数据复制或表删除迁移。共享状态完整性、模式、版本和所有权检查仍然存在。

架构兼容性预检可以读取代理架构标头,而无需进行完整的完整性扫描。对于普通回滚模式代理数据库和完整的 WAL 系列,只读子级会在一个新的 SQLite 事务中读取架构版本和可选写入器构建,包括已提交的 WAL 更改,而无需复制不相关的数据库内容。它的原生连接和物理身份仍然通过关闭而拥有;取消和超时等待子关闭。父级诊断不会打开或关闭实时代理文件,从而保留父级的 SQLite 锁。与之前的在线备份读取器一样,本机 SQLite 可以在静止系列重新打开后更新 SHM 读取标记或重建现有的 SHM;数据库和WAL内容保持不变。仅当数据库、WAL 和回滚日志文件未更改时,网关才会携带从准入到后来的兼容性预检的成功标头事实。再次检查已更改或不确定的文件。完全准备和可写准入保留其现有的验证和新的权限检查。

当调用者显式选择在线检查 (preserveSourceArtifacts: false) 时,共享状态模式预检使用相同的隔离读取器。版本、架构形状、代理注册表和删除日志事实共享一个读取事务,而无需复制不相关的有效负载。这允许 SQLite SHM 读取标记;它不授予迁移或修复权限。默认和显式工件保留检查保留其私有快照,继承的快照或 startup/Doctor 准入保留其现有所有者。

对于没有可重用密封的工件保留检查、不完整的 WAL 系列(其检查将创建源 sidecar)以及需要私有恢复的回滚日志,私有快照仍然是必要的。这些情况使用现有的快照所有者和截止日期;普通检查错误不会触发完整副本回退。匹配的干净关闭密封允许启动时直接读取未更改的检查点源。其他实时文件使用本机 SQLite 读取;不可变读取需要密封源或经过验证的私有或显式合并副本。 openclaw database preflight 对显式复制的文件执行发布本地形状比较。

对同一物理实时数据库的并发异步请求共享一个快照操作。当当前运行时已拥有打开的 SQLite 连接时,该所有者将提供 SQLite 的在线备份,而不是重新打开或复制实时数据库系列。每个调用者都保留一个独立的清理租约,取消只会分离该调用者,而共享操作和剩余租约保留其原始所有者和清理权限。

共享状态读取在排队之前捕获其源和生命周期权限。显式继承的快照保留其原始字节。新的工件保留副本会在每次打开主文件时检查已承认的物理文件密钥,并拒绝更改的身份,而不是进行替换。 具有不同源身份的请求不共享 a preparation.缓存的创建时元数据不被视为文件生命周期保证。

新的和继承的快照读取将准备、查询和清理保留在一项操作中。稍后保留的请求可以为较早的异步请求提供服务,而无需提前释放其保管权。现有的生成代理拥有独立于一次性 Workers 的快照子级;失去一个 Worker 不算作原生子闭包。失败的准备仍然会加入其原始清理,而未解决的清理会保留原始目录和准入。缓存的本机数据库在其路径名过期后继续使用其确切所有者等待的备份;它不会获得同步保留进度。这些更改保留架构、存储字节、保留和更新迁移。

普通观察到的配置加载,包括运行时重新加载准备,通过现有的实时共享状态读取器或工作器读取挂起的插件迁移义务,而不是复制数据库和WAL。每次读取都会看到当前提交的行;它不缓存义务或授予发布权限。未观察到的检查和继承的工件保留范围保留了私有快照。迁移发布会重新检查保护同步发布的同一本机写入事务内的当前生成。空的历史状态保留其模式,缺席的状态仍然缺席。

运行时配置发布(包括模型目录工作线程代)还通过实时共享状态读取器读取 Claw 同意来源,而不是为每一代复制数据库和 WAL。每份出版物都刷新了承诺的出处;配置摘要检查、故障处理和发布准入保持不变。显式来源检查和继承的工件保留范围仍然使用私有快照。两种优化都不会更改架构、存储的记录、保留或更新迁移。

实时快照使用SQLite的在线备份所有者和读取事务,以在写入继续时固定已提交的页面。本地读者可能会更新现有的SHM读取标记,因此工件保留计划和 Doctor 范围使用原始副本。一个WALcopy 首先捕获 main,然后捕获有界的WAL前缀,并验证同一固定的两者WAL一代。允许附加帧;重置、替换和更改捕获的字节需要再次尝试。SQLite解释私有副本中提交的帧。来源SHM保持原样。只有原始副本重用作用域IPC孩子;本机备份仍然是一次性的,需要避免Node 26完成因持久性而停滞IPC。不完整WAL系列、回滚崩溃残留和工件保留检查保留私有复制和恢复。现存的WAL和回滚日志文件可以共存而无需写入活动;检查副本并在之前进行验证SQLite恢复私人家庭。它不会丢弃已提交的WAL页、修复源或更改计划标识。快照调试遥测报告操作和所有者、主要和WAL大小、复制的字节、尝试、持续时间和结果。

更新验证重复使用准备好的演练数据库进行只读检查。需要完整的更新程序隔离标记以及数据库及其 sidecar 的物理遏制;外部路径仍然使用保留工件的副本。检查写防护保持活动状态,下一次检查会看到候选者之前的迁移步骤所做的更改。快照容量错误报告所需的估计字节数、当前可用字节数以及源是否具有实时 WAL sidecar。重试之前释放空间或移动缓存;临时快照容量故障不需要对服务安装进行架构修复。

同步 CLI 快照也会在源更改重试之间暂停,因此短暂的写入突发不会立即耗尽所有十次尝试。这些重试仅重复私有快照准备;他们不会重新发送网关命令。

私有快照文件仍然是临时工件:创建者在复制之前注册清理,并通过重命名发布完成的副本。优雅关闭会耗尽现有关闭所有者的资源,并在清理之前加入快照工作人员。清理会保留每个令牌,直到删除复制的数据,因此部分删除仍然是可恢复的。重新加载运行时模块后创建的读取器保留原始快照清理所有者。关闭会在重新加载时加入运行中的快照消费者,活动读取器仍然会阻止删除,而失败的清理会保留其保管权。当本机目录创建者确认在创建目录之前拒绝分配时,会报告原始的 staging-root 错误,并且现有快照生命周期仍然可以终止。丢失的回复和不完整的清理保留其原始清理保管权。本机终止和硬终止可以跳过该消耗。每个暂存目录都保存一个开放的 SQLite 交易作为其生命周期令牌。在检查或删除副本之前,回收会为父级和每个嵌套工作线程获取独占令牌,独立于 PID 命名空间。工人准入检查父母的令牌;退休是在句柄关闭之前提交的,因此迟到的工作人员无法重新启动它。网关在启动后安排废弃副本回收,一旦前台根工作空闲,然后在完成传递后每 15 分钟重新访问一次。每个通行证都会让位于前台工作并重新检查所有权和年龄,因此由于最近或超出预算而跳过的副本可以在不重新启动网关的情况下变得符合资格。快照分配仅创建并注册自己的令牌;同步或异步分配都不会等待回收过程。回收在 SQLite 工作线程中运行,使目录遍历和删除远离网关事件循环,并记录复制的数据字节计数。一个根的并发清理请求共享一个通道。回收需要可验证的非活动所有者和工作人员令牌,对当前暂存目录应用 15 分钟的宽限期,并每次使用 512 MiB 复制字节预算。在进行相同的所有权和年龄检查后,第一个回收的目录可能会超出该预算;然后传递停止,因此超大的中断副本可以一次取得一个进展。活动的、最近的、超出预算的或结构未知的目录保持不变。在删除和令牌释放一起解决之后,关闭和现有的回收截止日期将在目录边界停止。回收工作线程故障会发出警告,但不会阻止以后的快照分配。旧目录使用 24 小时年龄阈值,包括当前父目录下的旧子目录。在启动可能早于令牌的工作程序之前,更新程序还会将所选安装的暂存标记为与旧版兼容。当前工作人员将准入限制在现有旧父级内部,包括由已发布工作人员创建的中间 openclaw 缓存目录。回收理解该布局中的两代,并将相同的令牌和年龄规则应用于内部暂存目录。只读扫描检查令牌 I/O 之前的所有遗留活动;删除之前在锁定状态下重复验证。仍然太新的副本保留其现有时间戳。协调文件不算作复制数据或旧活动。实时或未经验证的令牌、最近的遗留副本、未知内容和符号链接都会留下警告。主数据库和备份永远不会被该所有者回收。

Doctor 期间的仅架构代理检查和重新启动检查会在一个 SQLite 读取事务中读取子进程中的元数据,而无需复制整个数据库。空文件、回滚日志、不完整的 WAL sidecar 和所有者提供的快照保留私有快照路径。如果没有可重复使用的密封,启动准备也会执行完整的完整性和外键检查。

Doctor 还通过同步工作区别名检查共享一个私有共享状态快照。下一次检查会读取最新状态,因此提交的修复是可见的,无需为每个配置的工作区拍摄单独的快照。

内存搜索和维护管理器保留每个代理发布工作人员及其承认的模式、物理身份和索引事实。获取不会打开第二个主线程读取器。工人的生命周期和经理接受的写入消耗;明确的检疫和处置仍然撤销数据库。完整内存重建使用临时影子数据库并在一个工作事务中发布其派生表。只读准入和捆绑状态读取使用检索工作线程,而无需创建或迁移丢失的数据库。释放的同步状态API保留了延迟打开的诊断读取器。

如果嵌套回滚或保存点清理失败,事务所有者将保留原始失败,丢弃暂存状态和提交后观察者,并关闭连接。捕获该故障无法恢复对废弃句柄的写入。稍后的操作必须通过其数据库所有者获取新的连接。 Doctor 插件状态导入保留早期提交的批次;中止的批次无法提交其前缀。成功回滚其保存点的普通行拒绝仍会提交可恢复导入的成功前缀。

共享缓存目标为 64 个句柄,但实时借用、同步事务和隐身状态不会被驱逐。所有者释放它们后,下一个新连接会将空闲句柄修剪回该目标。

并发运行通常在主线程上共享代理数据库的缓存写入器。工作人员和诊断人员可以打开与同一文件的其他连接;连接计数取决于操作。主代理连接在使用前设置 SQLite 的繁忙超时。超时无法解决在等待阻塞主线程时持有写入事务的工作线程:同步副本追加不会加入异步会话写入队列。事务回调必须同步完成,并且竞争写入器不得依赖主事件循环来释放其锁。

会话范围的写入会更新其现有的共享接收计数器,而不会在另一个会话注册时同步刷新主机的范围注册表。缺少受影响范围或持有已退役范围的编写者会在结算时保守地使数据库范围的收据缓存失效。初始范围注册仍使用准入所有者;实时写入权限检查保持独立。

定期代理维护使用被动 WAL 检查点和有界增量真空。检查点不会在提交时内联运行:将维护委托给工作人员(网关的代理和共享状态句柄)的编写器禁用 SQLite 的自动检查点,并跳过 10 秒仅检查点滴答;与同一存储的其他连接(例如其工作连接)在现有的 30 分钟定期传递(被动检查点加上有界增量真空)旁边内联运行这些刻度,这使共享 WAL 回填而无需主线程往返。代理连接(包括本机执行工作线程)禁用自动检查点并依赖这些维护标记,因此前台提交不会继承累积的 WAL 检查点工作。当未委派维护时,其他存储将其配置的内联阈值保留在 64 MiB 回收限制。会话回收在单独的工作写入连接上保留删除,并在提交后使用被动检查点和有界真空;长删除事务仍然可以与其他写入者竞争。全压实属于离线Doctor维护。命名网关状态数据库的运行错误保留安全的 SQLite 诊断;请参阅 存储故障故障排除 。

接受定期治疗后PASSIVE检查点完成后,WAL所有者进行一次零锁定等待TRUNCATE尝试如果观察到WAL仍超过其现有的64 MiB回收限制。并发读取器或写入器可以将回收推迟到下一个维护阶段。连接的繁忙超时随后恢复,现有检查点运行状况记录结果。这不会改变持久性、交易内容、读者生命周期、模式或历史保留;它永远不会取消直播的链接WAL。升级不需要状态迁移,旧的二进制文件可以继续读取相同的数据库。

隔离决策仅存在于专用的 openclaw-quarantine.sqlite 存储中,因此它们不会受到隔离数据库损坏的影响。验证结果被记录。

成功的可写代理准入还保留该存储作为共享状态先前存在的证据, including for unconfigured external agent databases.丢失共享状态不得将未知的删除历史记录重新创建为新状态。发布的隔离模式保留其旧的完整性接收表,但运行时不再读取或写入这些行;干净关闭证明仅存在于相邻的密封文件中。

后台验证错误保留原始名称和消息并追加有界Node code和SQLite errcode来自最多八个原因链节点的值。这些诊断不会改变结论:I/O故障仍然没有定论,而已证实的损坏会在隔离之前由数据库所有者再次确认。一个通用的disk I/O error (errcode=10)不会建立磁盘耗尽。

后台验证器通过本机退出保留其子级,并且IPC断开连接,包括发送工作失败时。失败的本机启动会在关闭后解决,无需退出事件。如果操作系统拒绝终止请求,验证程序将记录失败并继续等待本机退出;未发出信号并不意味着孩子已经停止。原工人或IPC即使终止也失败,错误仍然是报告的失败。

代理数据库维护用一个60- 共享状态数据库中的第二次租约。专用工作人员在同步完整性扫描和迁移阶段期间更新租约。维护仍然在突变和提交之前检查确切的持久所有者,并在检测信号失败或所有权过期或更改时停止。在释放租约之前完成或取消维护会停止续订;进程死亡最多只留下剩余的租约期限。

SQLite锁定争用重试时间为25租约获取预算内的 ms 间隔或心跳的持久到期时间。代理执行准入还会在进入应用程序工作之前重试争用,在第一次失败的准备解决后最多两秒钟。耗尽重试会返回争用错误,并为下一个请求留下可用的许可。停摆仍取消入场资格;已完成或输入的申请工作永远不会重播。 Doctor 的插件会话修复警告包括维护无法解决时嵌套的租约丢失原因。

Before draining heartbeats for a file capture, each state-lease owner attempts a final ordinary renewal. 捕获仍受排水后最短持久有效期读取的限制; 当文件被排除或恢复过期所有者时,它无法续订。

异步代理数据库准入在只读子进程中运行第一个完整文件完整性检查(当该检查位于写入事务之外时)。以后普通打开再利用记忆验证。维护保留其独立的全面检查。连接和所属范围将保持不变,直到本机阅读器关闭;取消和超时等待进程退出。架构更改、索引修复和压缩保留其同步阶段。

代理维护租约在其排队检查中重复使用一个完整性检查过程。每个请求都会打开和关闭自己的数据库,读取新的文件标识,并重新检查当前的维护所有者。结果和数据库句柄永远不会在请求之间缓存。失败会在调用者恢复之前退出进程,并且在释放所有权之前租约会加入所有排队的检查和子进程。对于重用的子进程,worker 的生命周期计时通过本机数据库关闭来衡量每个请求;一次性检查包括进程退出。

完整性子项允许 SQLite 在检查索引和外键时缓存最多约 64 个 MiB 数据库页。 SQLite 根据需要分配这些页面,并且当数据库关闭时缓存结束;保留的网关连接保留其现有的缓存设置。完整的完整性和外键检查仍在运行。

如果在归档或删除准备期间其可写句柄被逐出,显式会话维护终结将使用此异步准入。 它保留其在会话写入队列中的位置,并在提交之前重新检查维护和删除权限.当其原始手柄关闭而不是重新打开时,自动维护将退出。

完整性子进程以及异步和同步只读快照工作进程共享大小派生的生命周期预算。它包括五分钟的启动和关闭时间,然后预算四个文件大小IO以十倍的净空通过32 MiB/s旧磁盘的参考速率。经过验证的原始副本读取源代码并写入私有文件,然后比较两者;其他检查模式使用相同的保守余量。规模调整包括主数据库、WAL, SHM,和回滚日志。

2 GiB 数据库需要 2,860 秒,工作人员在工作完成后立即完成。大小派生的余量仅具有运行时的计时器可表示性上限。高于启动限额的预算将在调试级别的每个调用中记录一次,其中包括操作、路径、测量的大小和应用的预算。如果快照工作程序无法统计源,它会使用启动限额并让子进程报告潜在错误。

更新模式检查和候选快照使用相同的限额作为不活动看门狗。更大的呼叫者预算仍然可用,并且观察到的私人副本进展更新了截止日期。请参阅 更新如何运行。

实时快照使用在线备份工作线程。工件保留范围和同步快照副本保持源字节不变,包括 WAL 协调状态。

如果没有可重复使用的密封,完整的启动准备会在一次性子项中的一个新的只读事务中检查代理所有权、完整性、外键和模式。完整的 WAL 系列和没有日志的回滚模式数据库不需要完整的私有副本。空文件、不完整的 WAL 系列、回滚恢复和工件保留范围保留私有快照检查。父级在接受结果或释放其范围之前等待本机关闭。源数据库和WAL保持不变;本机 WAL 读者可以更新 SHM 阅读标记。迁移租约之前的准入和迁移写入之前的新鲜检查保持独立,它们之间没有共享缓存的就绪结果。

在多代理主机上启动

前台启动代理数据库检查和会话启动维护一次仅限于两个数据库。每个检查的大小派生的前景配额在其计划检查开始时开始,因此等待槽不会消耗它。例如,没有 sidecar 的 267.5 MiB 数据库需要 635 秒。这些并发性和预算改进先于此处描述的后台启动恢复;安装的版本可以有更短的预算和不同的并发性。

会话启动认证为需要新会话验证证明的数据库重用最多两个工作线程.有效收据保留其现有的快速路径。每个认证任务都有新的准入、自己的提交门和完整的会话验证。该任务关闭其数据库句柄和租用,并等待父级的关闭请求完成,然后再释放另一个数据库的线程。如果本机清理不确定,则写入者准入和清理保管权将保留,直到执行结束。

在启动过程中,到达检查的前台截止日期会记录待处理的准备,并标记代理 degraded,同时网关继续使用健康的代理。它的会话仍然不可用,并且其数据库被排除在自动迁移和普通写入之外。检查在相同的并发限制内在后台继续进行。等待期满不会造成腐败。

仅凭一次成功的检查并不能使智能体可用。网关打开每个代理的数据库并独立完成其会话验证和转录准备,然后采取FIFO轮流发布凭证、准备模型并清除未决的拒绝。当前数据库、配置、运行时所有权和删除状态在发布前保持检查状态。失败的检查或准备会导致试剂性能下降,并记录原因;它不会阻止健康的智能体。共享状态数据库故障保留其现有的启动检查。

启动删除日志检查最多使用 8 个并发读取,因此从准备就绪状态释放超过 128 个代理不会耗尽共享状态读取池。如果其他读取器使该池饱和,则启动仅重试类型化的容量拒绝,最多四次尝试,并可取消回退。删除墓碑、真正的读取失败和耗尽重试仍然会使代理降级。在等待准入之后和使用读取结果之前,会检查网关所有权和数据库身份。

配置的 ACP-only 会话存储遵循相同的延迟检查和会话准备路径,包括来自 acp.defaultAgent、acp.allowedAgents 和 ACP 运行时别名的 ID。它们不需要本机身份验证或模型发布,除非 ID 也属于配置的代理名册。

挂起的准备不会产生启动迁移警告。 Status 和 Doctor 从当前代理入院决策中得出失败的检查和准备警告,以及原因和修复指导。成功的准备将清除代理的待处理拒绝,而无需重新启动。真正的迁移警告会在启动时保留记录。这不会更改存储的状态或更新迁移行为。

在恢复挂起期间,agent database startup preparation still running 每 60 秒报告一次 agentId、phase、elapsedMs 和 phaseElapsedMs; publication-wait 也命名为 publishingAgentId。成功(agent database recovered after background inspection and preparation)和失败(agent database remains degraded)包括总计elapsedMs和phaseDurationsMs。使用阶段持续时间来区分检查、激活、open/migration 许可等待、打开、准备、迁移、发布等待、机密、模型和最终发布。这些是墙上时间,包括调度延迟,而不是 CPU 时间;进度警告并不规定最后期限或证明腐败。

检查 openclaw gateway call agents.list --json 或网关日志中受影响的代理及其原因。如果检查失败,请按照该原因的维修指南进行操作;在针对同一状态目录运行 openclaw doctor --fix 或从已验证的备份恢复受影响的数据库之前,请停止网关。修复后重新启动。网关关闭会取消并加入等待的检查和准备工作,然后再释放其所有者。关闭期间到达的结果无法重新接纳客服人员。

完整性子超时和不完整退出错误包括 lastObservedPhase:

值 最后观察
starting 父级尚未收到子级。
opening 孩子宣布进行文件身份检查并打开只读连接。
checking 连接打开,子进程宣布进行完整的完整性和外键检查。
closing 孩子在检查或出错后宣布连接清理。
result-received 父级收到最终结果并正在等待子级关闭。

这些阶段描述的是父母收到的消息,而不是孩子的确切当前位置或本地 CPU 时间。 checking 不区分完整性检查和外键检查。最终结果可以报告失败;阶段消息永远不会建立成功的验证或释放所有权。

缓慢的异步代理数据库打开包括可选的挂机时间测量:

字段 测量间隔
integrityWorkerCheckMs 子进程内部的完整完整性和外键检查,不包括打开和关闭连接。
integrityWorkerLifetimeMs 父级观察到的从分叉子项到关闭事件的时间,包括启动、IPC、清理和事件传递。
integrityOutsideWorkerMs 完整性门在子生命周期之外的剩余时间,包括父准备、调度和准入重新验证。

缺失的测量仍然不存在,包括在报告其持续时间之前杀死的子检查。这些字段与调用驱动程序的同步 integrityCheckSyncMs 和 integrityOutsideCheckMs 不同。没有一个测量 CPU 时间或隔离存储等待。父级仍然等待子级关闭,并在继续准入之前重新验证数据库和当前权限。

包含 state lease heartbeat did not become ready 的启动错误包括 phase=startup、结算触发器(timeout 或 message)以及父标记失败之前观察到的状态。 status=starting 将准备就绪状态与已记录损失的 status=lost 区分开来。 elapsedMs 测量自心跳启动开始以来的单调时间; timeoutMs 是启动等待预算,上限为 60 秒,并且是最新确认的持久租约到期时间。活动状态租约所有者在启动期间更新,直到工作线程接管,因此在繁忙的主机上缓慢启动的工作线程仍然可以准备就绪。过期或更换的所有者无法续订,并且主机续订永远不会延长 60 秒的启动上限。这些字段无法确定启动停滞或所有权丢失的原因。

心跳证明所有权,而不是迁移进度。一个活跃但卡住的维护流程可以保持其租约;在重试 Doctor 之前停止该过程。

租约到期计时器将每次等待限制在 Node 的最大计时器延迟,并在所有权到期之前重新检查截止日期。在更新或 Doctor 运行期间,向后时钟调整不能将长期剩余租约转变为立即超时。续订和持久所有权检查仍使用记录的到期时间;这不会更改存储的数据、架构或备份和回滚行为。

btrfs 和 NOCOW

SQLite 反复重写数据库页。在 btrfs 上,写时复制可能会导致大型存储碎片化,并使检查点和 fsync 变慢。新的 Linux SQLite 在创建之前将请求 chattr +C 存储在其目录中,因此数据库、WAL 和共享内存文件继承 NOCOW。缺少工具或不受支持的权限会产生警告;数据库仍然打开。 NOCOW 用 btrfs 数据校验和和压缩换取就地写入; SQLite 的完整性检查仍然适用。

Doctor 报告现有的 btrfs 存储没有 NOCOW。显式 openclaw doctor --fix 可以在其停止的网关维护所有者下重写它们。修复需要lsattr、chattr、fuser、getfacl、setfacl、GNU、mv与--exchange和--no-copy,以及至少两倍的可用空间未压缩的存储目录大小。它采用经过验证的 WAL-aware SQLite 备份,将副本流式传输到新的 NOCOW 同级中,保留所有权、模式和 access/default ACL,检查副本大小和 PRAGMA quick_check,然后自动交换目录。在清点或复制之前,Doctor 会根据已知的打开文件检查 fuser,并在每个文件系统中尝试在存储的父级中进行一次临时目录交换。内核和文件系统必须支持RENAME_EXCHANGE;不受支持的主机将商店留在原处并发出警告。医生在真正交换之前再次检查打开的存储文件。

官方 Debian 书虫 Docker 映像无法执行此可选修复:其 coreutils 9.1 mv 缺少 --exchange/--no-copy,并且不包含 fuser(psmisc 软件包)或 getfacl/setfacl (acl 封装)。派生映像需要这些工具和具有交换功能的 GNU mv,以及已安装状态卷上的 kernel/filesystem 支持。现有商店的更新仍在继续。

发布后,Doctor 会重新记录其重写的任何记录的迁移恢复原始数据库和目标数据库的重定位身份,因此 update cleanup 资格在重写后仍然有效;不再与录制内容匹配的副本将保留其原始记录并受到保护。符号链接保留其确切的链接文本和所有权,而不跟随目标(包括悬空链接),并且保留空的常规文件。该报告会命名保留的原始目录和独立备份。保留它们,直到更新的网关得到验证;不要用旧副本覆盖新的运行时状态。

在托管更新期间(OPENCLAW_UPDATE_IN_PROGRESS 为真),Doctor 仍会报告没有 NOCOW 的存储,但 --fix/--repair 会推迟重写,除非更新程序也设置了 OPENCLAW_DOCTOR_SQLITE_NOCOW_REPAIR=1。如果没有该请求,D​​octor 会打印明确的延期通知并保留商店目录。此更新程序到Doctor 环境合同允许更新程序将物理身份更改与架构迁移分开考虑。 Operator 在托管更新之外运行,保持正常的显式修复行为。

Doctor 耗尽其数据库句柄,包括活动状态目录下所有代理存储的汇集身份验证配置文件读取器,并在重写之前等待其检查人员。它使用有限的 fuser 批次检查每个存储目录中的每个常规文件,以便大目录适合操作系统的参数限制。拒绝说 store files are open (pids: …) 命名 fuser 报告的进程。拒签fuser could not establish that all handles are closed包含检验错误;检查fuser是否已安装并且可以通过/proc检查进程。两次拒绝都会将原始存储保留在原位,包括当流程检查报告权限错误时。

缺少的工具可以通过注释跳过修复。空间不足、有效的网关所有权或发布前验证失败都会导致之前的存储保留在原处。不确定的交换会停止激活并命名保留的恢复路径以供检查。不涉及SQL架构迁移。重写的数据库具有新的物理身份 (device/inode),因此下次启动时会重新运行会话验证一次,而不是重用原始身份收据。

Planner统计维护

在成功检查点后,共享状态编写器在 30 分钟的 WAL 维护过程中维护一次 SQLite 规划器统计数据。它在现有的写入者准入和交易权限下使用PRAGMA analysis_limit=1000; PRAGMA optimize=0x10002;,无需忙等待。 SQLite 仅分析统计信息丢失或过时的表,包括此维护连接尚未查询的表。在 3.46 之前受支持的 SQLite 版本上,缓存的本机准入版本选择有界 ANALYZE main,因为它们的优化器无法发现所有丢失或过时的统计信息。争用会跳过该尝试;稍后定期维护重试。仅检查点标记、数据库准入、打开和普通写入不会分析表。真空连续装置不重复分析。关闭在本机关闭之前加入接受的维护。

限制限制每个索引的采样,而不是整个数据库的总工作量或运行时间。统计数据为 SQLite- 拥有的派生数据:应用程序记录、保留和架构版本未更改。更新和回滚不需要迁移。现有的读取快照保持不变。新开读者使用最新统计数据;保留的连接可以在以后刷新后保持旧的选择性,直到正常报废为止。此策略不会向代理数据库添加重复分析; Doctor 的停止写入器相同版本媒体修复使用相同的有界统计原语。现代版本迁移使不相关的规划器统计数据保持不变。

故障排查

当基础错误提供有效值(包括通过有限原因链)时,SQLite read-only worker 故障会附加 code 和数字 SQLite errcode 诊断。调查故障时报告完整的代码后缀。快照和完整性子超时错误包括应用的预算和源文件大小;如果源统计失败,快照超时会报告未知大小。完整性子超时也保留 lastObservedPhase。单独使用通用 disk I/O error 或 SQLITE_IOERR 并不能证明磁盘已满。

共享状态数据库准入还可以跨工作传输保留本机 SQLite 结果代码。即使在创建租约之前获取失败,租约和托管工作树配置诊断也会保留底层存储故障。

状态数据库正忙

租约更新和释放使用非阻塞写入许可。竞争尝试将重试和失败处理留给租约所有者,而不记录事务锁定等待警告。普通写入等待和提交失败保留其诊断信息。

等待其他 OpenClaw 进程完成其数据库工作,然后重试该命令。 state-lifecycle 争用通常会在启动、写入或维护完成后清除。 gateway-lifecycle 保护正在运行的网关的所有权,state-handles 保护开放的数据库连接;在网关运行时,这些可以保持保留。

如果争用仍然存在,请使用相同的配置文件和状态目录设置运行 openclaw gateway status,并检查使用该状态目录的其他 OpenClaw 进程。在重试需要独占访问的操作之前,通过其服务管理器或原始终端停止阻塞网关。更喜欢这里的简单状态:--deep 添加数据库预检。 Doctor 还需要状态协调,因此在持有锁时运行它可能会因相同的争用而失败。

数据库路径无法比较

Cannot determine whether database paths alias 表示 OpenClaw 无法安全地比较尚不存在的路径。检查在最近的现有父目录下创建和删除条目的权限,然后重试。比较使用有界文件系统检查:每个缺失的后缀允许最多 8,192 个 UTF-16 代码单元,最多有 32,768 个前向文件系统观察。如果超出这些限制,请简化异常长的路径。不完整的检查清理永远不会成为缓存的路径标识结果。

A 打开本地数据库时安装检查超时

在 macOS 上,本机文件系统检查可以在挂载枚举超时后确认 APFS。对于已解析的数据库目录,OpenClaw 然后保持 WAL 启用,而不是尝试与其他打开的连接冲突的回滚模式转换。未知的文件系统、失败的本机检查和别名路径保留保守的回滚策略。网络和跨 VM 文件系统的现有规则(包括拒绝通过 SSHFS 写入)仍然适用。

A 旧版 Workshop 索引可防止共享状态读取

legacy-workshop-review-index 错误需要 openclaw doctor --fix。普通网关读取和自动迁移不会进入旧目录修复路径。健康读取保留其准备好的 SQLite 查询。

使用 OpenClaw 2026.9.4,在重试 openclaw update 之前运行 Doctor:安装的更新程序会在启动目标版本之前检查数据库完整性。

Doctor 在修复确切的已知索引之前检查数据库版本和活动所有者。它在加载依赖配置和插件状态之前恢复目录可读性,然后继续其正常的迁移和验证流程。维护租约检查可以检查较新的数据库,而不允许其运行时使用。 Doctor 仍然拒绝修复前的较新架构并报告架构不匹配;一个新的、无法验证的网关所有者仍然阻止维护。检查读取器关闭后,无法删除其私有快照会发出警告,并将清理工作留给快照所有者;它不会阻塞维护入口。可读性修复保留了审阅行和模式版本标记;无法识别的损坏和较新的数据库仍然被拒绝。

共享状态WAL不断增长

正在运行的网关会记录其现有 WAL 维护通行证的结果,通常每 30 分钟一次。 openclaw status --deep 和 Doctor 在两个连续阻止的检查点后或在一个阻止的检查点后(当 WAL 超过数据库大小的两倍和现有的 64 MiB 日志大小限制时)显示 SQLite WAL 警告。检查点错误立即发出警告。稍后完成的检查点会清除警告;单独一个大的 WAL 并不意味着检查点被阻止。文件大小观察失败与SQLite的完成结果分开记录和记录;他们不会将已完成的检查点变成失败。

定期维护在本机工作之前进行,以便网关事件循环可以继续。让步后,它重新检查相同的数据库所有者、物理文件并获取维护权限。退休取消并加入待处理的工作。 SQLite 以零繁忙超时直接处理写入者争用;维护不会等待单独的协调数据库。显式同步检查点和关闭操作保留其同步契约。这些更改不需要状态迁移。

当阻塞连接使用 OpenClaw 的跟踪查询帮助器时,警告包括观察到的 WAL 和数据库大小、检查点和总 WAL 帧、最后观察到的完整检查点、连续阻塞计数、观察时间以及最多八个进程本地活动读取器所有者。读卡器诊断仅包含有界操作标签、main/worker 所有者类型、可选的工作参与者 ID、年龄和空闲时间;它们从不包含 SQL、绑定或行内容。 SQLite 可以报告 busy=0 不完整的 PASSIVE 检查点;少于总帧数的检查点帧仍然记录被阻止的检查点。不存在的读者列表意味着阻止者未被跟踪或属于另一个进程,而不是不存在读者。

共享状态 SQLite 工作参与者在 60 秒后检查其已打开的 WAL 连接,而没有任何活动操作。一个公认的 PASSIVE 检查点积极地检查健康的连接,让参与者直到最后一次实际操作后 30 分钟;检查不会延长该期限。另一个连接的读取器可以阻止完整的检查点,而不会使该参与者变得不健康。拒绝检查点、不可用的检查或没有可检查的 WAL 连接的参与者的本地本机读取器将保留 60 秒的退休行为。检查永远不会为保留工件的读取器打开数据库。在稍后的请求打开替换参与者之前,停用会关闭本机数据库借用。从操作返回且跟踪读取器仍处于活动状态的参与者将失败结算并立即退出。

在经纪商的 64 个客户端限制下,新开仓可以在正常截止日期之前淘汰所有者确认的空闲共享状态客户端。已接受的范围、挂起的命令、维护客户端和来自另一运行时生成的客户端都受到保护。退出会在准入恢复之前加入本机清理,稍后使用透明地重新打开退出的客户端。如果没有客户符合资格,则继续拒绝容量;限制和存储的数据不会改变。

观察属于网关进程中打开的数据库句柄。当更换该手柄或网关重新启动时,它们会重置。状态和医生通过现有状态RPC读取记录的观察结果;他们不运行检查点或打开诊断数据库。在第一次观察之前,或者当较旧的网关不提供观察结果时,此警告不存在。

如果警告仍然存在,请捕获 openclaw status --deep 输出并使用 openclaw gateway restart 重新启动网关。如果警告再次出现,则报告捕获的输出。不要删除 WAL:它可能包含尚未到达主数据库文件的已提交数据。

Doctor 报告孤立会话窗口

如果 foreign_key_check 命名 session_windows 引用缺失的 session_nodes,请停止网关,运行 openclaw doctor --fix,然后在修复后重新启动。仅当Doctor仍无法修复脱机数据库时,才保留数据库和WAL并恢复经过验证的备份。 Doctor使用其现有的独家维护所有权;受管理的网关可以停止和恢复,独立运行的网关必须释放状态才能继续修复。

对于当前架构代理数据库,Doctor 首先在数据库旁边的私有 openclaw-session-window-recovery-* 目录中保留完整的 WAL-aware 副本。然后,它仅删除引用节点不存在的窗口及其相关转录记录和搜索条目。属于现有节点的Windows保持不变。该报告包括备份路径和已删除窗口计数。

如果升级还需要架构迁移,Doctor 会在孤立块阻止其迁移前备份时运行此修复,然后在允许迁移继续之前重试完整备份及其完整性检查。

修复拒绝不相关的外键违规,在提交之前检查完整性,并在修复失败时回滚删除。保持备份的私密性:它包含原始的孤立窗口及其拥有的任何历史记录。不需要更改架构,并且此修复不会识别创建孤儿的编写者。

新代理数据库准入会重新验证本机验证程序进程中缓存的完整性拒绝。干净的结果会清除旧的进程本地拒绝,因此修复的数据库不会保持阻塞状态。健康招生不会运行此恢复检查。这并不能清除启动所有权拒绝或更新模式错误,Doctor 保留其专有的维护要求。

Doctor 报告孤立任务交付行

如果 foreign_key_check 命名 task_delivery_state 引用 task_runs,则停止网关并运行 openclaw doctor --fix。当数据库结构完整并且没有不相关的外键违规或无法识别的传递表模式或触发器时,Doctor 可以恢复这种已知关系。

在删除任何孤立行之前,Doctor 会在共享数据库旁边的私有 openclaw-task-delivery-recovery-* 目录中保留完整的 WAL-aware 数据库副本和无损行导出。它的报告命名了该目录。它包含:

  • database.sqlite:修复前的数据库,包括孤立行。
  • orphan-rows.jsonl:原始交付负载,SQLite整数编码为十进制字符串,以避免精度损失。
  • manifest.json:文件哈希、行计数和保存元数据。

Doctor 仅删除现有修复事务中任务不再存在的交付行,并且在提交之前需要进行干净的完整性和外键检查。它不会伪造任务或重放交付。如果保存或后续修复步骤失败,行删除将回滚并保留任何恢复工件。清单证明了保存情况,而不是进行了修复;重新运行 Doctor 以验证是否完成。

保持这些文件的私密性:它们可以包含传送目标和其他用户数据。保留它们,直到验证更新的网关并恢复任何所需的有效负载。不要使用此原始副本覆盖较新的运行时状态。此恢复不会确定哪个写入者创建了孤立行。

为什么更新到 2026.7.2 后无法回退

直到 v2026.7.1 的每个版本都使用 agent schema 1 和 state schema 1。2026.7.2 发布线(从 v2026.7.2-beta.1 开始)会在首次启动时将你的数据库向前迁移。该迁移是单向的:数据会被重写到更新后的 schema 中,而之后安装较旧版本的 OpenClaw 并不会撤销这一点。较旧的构建会拒绝启动,并报出 newer schema version 错误,其中会指出拥有该数据库的构建。

一些较旧的包省略了架构元数据。更新程序通过 2026.7.1 识别普通 2026 稳定版本的 schema-1 合约,并在激活之前检查它,包括从本地软件包 tarball 更新时。不兼容的目标将被拒绝,而当前安装仍保留在原位。

降级二进制文件永远不会降级数据。使用托管恢复路径或使用其匹配版本还原已验证的更新前备份。保留迁移恢复原件,直至验证升级;它们不会取代完整的备份。请参阅 降级 。

Gateway 因为 newer schema version 错误而拒绝启动

一个更新的 OpenClaw 构建写入了你的数据库,而当前运行的构建更旧。错误会指出拒绝启动的安装信息——发布版本、commit 和安装根目录——以及它支持的 schema 和实际发现的 schema。

请针对安装根目录进行处理,而不是版本。一个发布版本字符串可能对应许多 main 提交、schema 级别和同版本的 schema 形态,因此两个安装都可以自称为 2026.7.2,但仍然无法对同一个数据库达成一致。预发布版本可能根本不存在于 latest npm 标签中:重新安装前请检查 npm view openclaw dist-tags,因为携带你所需 schema 的标签可能是 beta,而从 latest 重新安装可能会让情况进一步偏离。

当网关从链接源签出运行时,其状态和模式拒绝诊断报告构建 dist/ 时捕获的提交,而不是签出的当前 Git HEAD。如果该构建标识未知,请在断定版本错误之前重建结帐 (pnpm build)。

使用支持其 schema 的构建打开数据库,或者让旧版本构建指向单独的 OPENCLAW_STATE_DIR。不要通过编辑数据库来消除该错误。

Doctor、网关启动、更新状态和离线 database preflight 会优先拒绝此版本,即使旧版本无法读取新目录也是如此。安装兼容的较新版本,或恢复与旧版本匹配的备份; doctor --fix 无法修复较新的架构。这些拒绝使数据库及其 SQLite sidecar 保持不变,包括在 update status --json 期间。

配置读取还将健康指纹保存到此数据库。如果写入失败,Config health-state write failed 报告当前进程中该数据库的第一次失败。当继续尝试写入时,会抑制重复的相同故障。成功写入健康状态后,会再次报告不同的错误或失败。抑制重复项并不能解决底层数据库错误。

数据库在完整性验证失败后被隔离

后台验证器证明该文件已损坏,因此之后每次打开都会快速失败,而不会重新扫描。请从备份中恢复数据库,或者修复它,然后运行 openclaw doctor --fix 以清除隔离记录。如果隔离记录本身无法清除,doctor 会报告明确错误;请反复运行,直到它报告正常。

如果 doctor --fix 无法修复代理数据库,请停止网关,备份数据库及其 SQLite sidecar,然后针对相同的 state/config. 运行 openclaw doctor --session-sqlite recover --session-sqlite-agent <id>。恢复修复支持的索引损坏或保留带有 .corrupt-<timestamp> 后缀的损坏文件集。如果您需要以前的会话,请恢复经过验证的备份。请参阅 SQLite 维护。

媒体迁移首先使用架构准入完整性检查。健康的代理数据库不会在立即修复事务中重复进行全文件扫描。已证实的完整性故障仍然会在重试入院之前调用 Doctor 的保留索引修复。启动诊断分别标记模式准入、索引修复和隔离清理;存储的数据、模式版本和更新恢复语义保持不变。

对于共享状态或每个代理仅索引损坏,支持修复 openclaw doctor --fix。 Doctor 要求每个 integrity_check 发现都命名缺失、非唯一或计数错误的索引条目,在不使用损坏索引的情况下验证表数据,并在运行 REINDEX 之前将损坏的数据库保留在旁边的 openclaw-index-recovery-* 目录中。它会打印备份路径和命名每个重建索引的警告,然后在清除隔离之前要求进行干净的完整性和外键检查。表行被保留。页面或 B 树损坏、不可读的表数据和其他完整性故障仍然是一个拒​​绝:保留数据库及其 WAL,然后恢复经过验证的备份或使用 SQLite 恢复。运行时和启动永远不会自动执行此修复。

降级恢复

请勿使用 SQL 或更低的 PRAGMA user_version、schema_meta.schema_version 或配置编写器标记进行反向迁移。这些标记描述了持久格式;编辑它们不会恢复旧的数据合同。

按照 Downgrade 获取托管回滚路径、保留原始限制以及恢复经过验证的更新前备份。完整的恢复点包括匹配的包、配置、共享状态和每个代理数据库。在激活恢复状态时保持写入器停止。

示例:状态模式 21 到 20

模式 21 从规范的 JSON 派生会议记录选择器和有界传递保留列。 schema-20 编写器可以更改 JSON 而不更新派生列,因此仅包降级是不安全的,并且较旧的版本会拒绝迁移的数据库。

停止编写器并恢复经过验证的迁移前备份及其匹配的版本。单独保留迁移后的数据库,直至验证恢复;恢复备份会丢失备份后记录的捕获和传送状态更改,并且不会撤消已发送的消息。切勿降低架构标记、删除新列或在两个数据库之间复制单个表。

本页有帮助吗?