摘要
DELE的成功响应只表示当前 maildrop 视图里的某个编号已被标记;邮件尚未移除,RSET仍能清掉全部标记。- 只有 TRANSACTION 状态中的客户端主动发送
QUIT,会话才进入 UPDATE。异常断线或空闲超时不得触发删除。 - 这条边界防止下载中断造成永久丢失,却不保证全有或全无;RFC 1939 明确允许已标记集合只删除一部分。
“已删除”首先是一条会话内事实
RFC 1081 在 1988 年已经把 POP3 会话分成 AUTHORIZATION、TRANSACTION 与 UPDATE。认证成功后,服务器打开 maildrop,并在必要时取得独占访问锁,再为当前视图中的邮件顺序编号。
DELE 4 操作的是这个视图里的位置。服务器返回成功后,后续命令再引用该编号会报错;但存储对象仍在。只要会话还处于 TRANSACTION,RSET 就能撤掉所有删除标记。
所以第一条 +OK 的证据范围很小:服务器接受了一个可逆意图。它没有证明空间已释放,也没有证明后续 UPDATE 一定成功。这里有三个不同对象——本次会话的编号、附着于编号的标记、服务器最终移除的邮件——自然语言却容易把它们压成一个“删除”。
锁保护操作数,而不是永久身份
maildrop 锁的作用,是防止邮件在 UPDATE 前被修改或移除,让 LIST 4、RETR 4 与 DELE 4 在同一事务中仍指向同一项。锁结束后,下一次打开的集合可能不同,编号也会重排。数字 4 是一次会话的操作数,不是跨会话身份。
这种安排划分了知识。客户端知道下载内容是否已安全写入本地;服务器知道 maildrop 里实际有哪些实体,并掌握移除能力。协议没有假装两端共享一份原子日志,而是让客户端先准备破坏性意图,再用明确状态转换交给服务器执行。
RFC 1225 与 RFC 1460 延续了同一顺序:标记、允许复位、由 QUIT 进入 UPDATE、移除、释放锁、响应并关闭。
连接消失不能代替同意
RFC 1725 在 1994 年把失败规则写得更明确:只要会话不是因客户端发出 QUIT 而结束,就不得进入 UPDATE,也不得移除邮件。空闲自动退出同样只关闭连接,不发送响应,不删除。
这保护的是下载与本地持久化之间的缝隙。服务器可能已经发完最后一个八位组,客户端却仍在写磁盘。若断线本身就授权删除,那么最需要保留服务器副本的故障,反而会把副本消灭。
因此 EOF、reset、进程崩溃与沉默都不是 QUIT。AUTHORIZATION 中的 QUIT 也只结束会话;只有 TRANSACTION 中已经存在 maildrop 视图和待处理标记时,它才打开 UPDATE。权力属于“命令加状态”,不属于四个字符本身。
UPDATE 不是数据库式原子提交
RFC 1939 承认了最重要的限制。服务器在 UPDATE 中尝试移除已标记邮件;若资源不足,可能只删除其中一些,也可能一个都没有,并可返回 -ERR some deleted messages not removed。无论成功失败,它都会释放锁并关闭连接;未标记邮件绝不能被移除。
边界严格,结果却可能部分完成。若最终响应在途中丢失,客户端也无法从 TCP 关闭判断服务器是完全成功、部分成功,还是根本未进入 UPDATE。重新连接后再照抄旧编号尤其危险,因为新的第 4 项可能是另一封邮件。
恢复必须从当前列表做对账。UIDL 若存在,可以帮助识别仍在的实体,却不能解释缺失原因;其他客户端或站点保留策略也可能移除邮件。缺失不是上一条 QUIT 的因果收据。
策略可以扩大标记集合,却不能搬走边界
RFC 2449 的 EXPIRE 0 表示站点不允许把邮件留在服务器。会话进入 UPDATE 时,服务器可以把所有经 RETR 下载的邮件视作隐式执行了 DELE。关键仍是“进入 UPDATE 时”:下载本身没有立即删除,异常断线也没有获得执行权。
IANA 服务名与端口号注册表 保留了 pop3 与端口 110。这只是协调记录,不证明今天的部署量或某个实现遵守上述边界。
POP3 没有制造完美提交,而是限制每一种证据能说什么:DELE +OK 说明已标记;QUIT 请求进入不可逆阶段;最终响应报告服务器所知结果;响应缺席时,只能靠后续状态对账。
来源
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
