Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

报告 006 · 真实进程与持久化边界

文档索引 · 当前设计 · 研究问题

日期:2026-09-19。类型:本机多进程与真实 SQLite 事务实验。15 个预登记场景完成,45 个独立子进程,8 次 SIGKILL,首轮执行通过全部预登记判定;其中包含预期应当暴露错误的负面对照,不能理解为所有策略都正确。没有部署 Kubernetes 或实现产品运行时。

1. 问题、环境与证据

报告 005 使用模型假设描述状态权威与原子效果。本实验将指派复核、去重和实际计数器写入数据库,直接终止工作进程并重新连接检查,检验持久化边界能覆盖哪些故障切点。节点指派属于历史分布式方案,不属于当前 TinyAGI 架构。

项目实际记录
Python3.14.7,/usr/bin/python3
SQLite3.53.4
OSLinux 6.18.52-1-lts x86_64,glibc 2.44
数据库模式每个数据库 WAL,连接 synchronous=FULL(数值 2)
故障注入子进程通过标准输入输出停在指定切点,父进程对该子进程发送 SIGKILL,等待退出码 -9 后检查数据库
隔离每例独立临时目录,实验结束清理;不连接已有服务或集群
实际效果实验数据库中计数器增加一次;不代表任意网络调用或物理效果
experiment.py SHA-256
a2c41340f2cc86a310fae882021f7cb980f314fb6467086e36545d4a0ae45be1

预登记 README.md SHA-256
0c3d52c3dd1c098cb815dc70a88b65dde2600e06acf4462f62f8c4e214dedd0b

2. 指派切换:缓存检查不是提交边界

旧进程先读到 epoch=1 与自身 BootID,停在消息屏障;父进程在数据库条件提交 epoch=2/新 BootID,再恢复旧进程。读上下文时不持有写事务。随后独立新进程提交一次,验证可继续推进。

策略改权后的旧状态写入旧 outbox 记录新执行者提交最终状态计数
使用缓存的指派检查,再无条件提交11成功2
BEGIN IMMEDIATE 内读取当前指派并共同提交00成功1

本例的原子范围是同一个 SQLite 写事务,并非“先读外部分布式锁,再写业务数据库”。结果支持把当前指派复核放在状态/outbox 的同一原子边界内,没有验证复制数据库接管、租约时钟或完整业务约束。

3. 八个崩溃切点:有持久回执仍可重复效果

原子组:计数器与回执在同一数据库事务中提交。分离组:先提交 world 数据库的计数器,再提交 provider 数据库的回执,模拟提供者记录与外部效果不能共同提交的边界。两组的 ResourceEpoch=2 均已预先持久化;本实验不测试安装代号的接管过程。

表中“有/无回执”为崩溃后重新打开数据库的观察,最后一列为新进程重投同键同参数后的计数。

策略SIGKILL 切点崩溃后效果崩溃后回执重试结果恢复后效果
同一事务before_write0无executed1
同一事务effect_written(尚未提交)0无executed1
同一事务receipt_written(尚未提交)0无executed1
同一事务committed_before_reply1有existing1
分离事务before_write0无executed1
分离事务effect_written(效果已提交)1无executed2
分离事务receipt_written(回执已提交)1有existing1
分离事务committed_before_reply1有existing1

关键反例是 crash-split-effect_written:磁盘上没有回执,不代表效果未发生。重建 Pod、换 BootID 或挂回同一份回执卷均不能自行消除这个窗口。分离组是在两个真实数据库间检验该反例,没有声称所有外部 API 都会采取相同实现。

八个场景在恢复后都额外检查:epoch=1 携带一个不同业务键被拒绝,避免“旧请求只是碰巧被去重”的假阳性;同一键换参数也均被拒绝。计数器和回执保持不变。这验证的是已保存代号的进程恢复,未验证代号丢失、倒退或高代号接管安装。

4. 并发重投与缺失存储

四次双进程场景各自在两个进程 Ready 后开放入口,争用同一业务键。每次返回一个 executed、一个 existing,计数器均为 1、回执均为 1。操作系统实际调度顺序没有枚举,也未保证锁等待一定发生;只记录这些双进程运行,不推导吞吐或广泛并发保证。

缺失存储场景返回 recovery_required,目录中没有新建文件,也未发生效果。该结果验证脚本明确写出的关闭接纳策略,不能据此认为所有提供者或数据库会自动这样处理。损坏文件、缺表、旧快照和第一次合法初始化仍需分别制定及验证流程。

5. 设计变化与限制

保持当前指派与状态/outbox 共同提交的候选,补充真实进程证据。提供者契约收紧为必须声明:业务键作用域及参数绑定、效果与回执的原子边界、保留期、重启恢复规则和可查询的事实。仅声明“幂等表持久化”不够;没有原子去重或可靠结果核对时保留 unknown,避免恢复时盲重试。

原子计数器组支持受控数据库效果在这四个切点后的单次执行,不能外推为任意外部动作恰好一次。主机 OS 和存储继续运行,故 FULL 配置加 SIGKILL 也没有验证断电耐久性。SQLite 继续只是单机实验载体,分布式权威数据库尚未选定。

实验未覆盖真实复制后端、运行中动作排空、旧备份恢复和非原子提供者的完整核对协议,也未测试 Kubernetes 控制器、CNI/CSI、节点分区、卷迁移或真实业务状态迁移。

数据可用性

本报告公开实验条件、汇总统计和失败分析。原始输入、脚本及逐次运行记录未随报告发布,因此不能仅凭本文独立复现实验。