摘要
DELE只在受独占锁保护的TRANSACTION状态中为邮件加上删除标记;RSET可以在正常退出前撤回全部标记。- 只有客户端从TRANSACTION发送
QUIT才进入UPDATE。异常断线不得删除邮件,但UPDATE本身并非原子操作:发生故障时可能只删除部分标记邮件。
断掉的电话线不能替用户作决定
一台拨号上网的电脑下载三封邮件,并要求服务器删除原件。服务器逐一答复成功,却在最后一封写入本地磁盘之前掉线。如果每次DELE都立即生效,同一次故障既阻止本地保存,又毁掉远端副本。
POP3选择把代价放在更容易修复的一边。DELE使邮件在本次会话里表现得像已删除,后续命令不能再引用它的编号,但真实数据仍在maildrop中。客户端可以发送RSET清除全部标记。只有正常的QUIT把会话送入UPDATE,服务器才开始执行物理删除。
服务器知道自己发出了字节,却不知道客户端是否已经可靠落盘。协议无法检查另一端的磁盘,只能选择双方都能观察到的信号。明确告别意味着“现在可以尝试兑现这些意图”;TCP连接突然消失则不具备这种权限。
先确认接收、再放弃副本的思想早于POP3
1984年的RFC 918已经区分只读的RETR和带删除意图的RDEL。客户端收完数据后还要发送RCVD,服务器才尝试删除;RSET可以中止事务,并要求正确关闭和解锁邮箱。
1985年的POP2规范RFC 937使用ACKD确认接收并给当前邮件加删除标记,真正改变邮箱要等到会话结束或切换邮箱、释放邮箱之时。
早期命令后来被替换,问题却没有消失。在不稳定网络上,“服务器已经发出”与“客户端已经可靠拥有”不是同一事件。POP协议的演进,就是逐渐把两者之间的空隙写成公共规则。
三个状态把延迟删除变成了协议结构
1988年的RFC 1081首次定义POP3的AUTHORIZATION、TRANSACTION和UPDATE。认证成功后,服务器打开用户的maildrop并取得独占锁;客户端在TRANSACTION中列举、读取和标记邮件;QUIT触发UPDATE,服务器尝试删除标记邮件、释放锁并关闭连接。
三个状态隔开三种权力:AUTHORIZATION决定谁能进入,TRANSACTION提供稳定而可撤销的操作视图,UPDATE承担不可逆效果。因此在尚未认证时发送QUIT只会结束连接,不会进入UPDATE,因为根本没有一个已认证的邮箱事务需要兑现。
邮件编号也只属于这次工作视图。DELE之后,协议拒绝再次引用该编号,即使底层邮件仍未移除。会话的逻辑状态可以先前进,存储状态则等到边界之后再改变。
RSET把反悔设计成正常路径
RSET不是补丁式的紧急命令,而是最小POP3实现必须支持的命令。它一次撤回所有删除标记。客户端可能发现磁盘不足、某封邮件解析失败,或在退出前改变“保留服务器副本”的策略;协议允许它收回尚未生效的意图。
独占锁保护这段反悔窗口。RFC 1725明确说明,必要时锁要防止邮件在进入UPDATE前被修改或移走。否则另一客户端可能在本次会话还依赖旧编号时重排同一邮箱。
这并不是完整的数据库事务。POP3没有分布式共识、UPDATE后的撤销,也没有规定统一日志和崩溃恢复。它只把一个很窄的可逆区间定义清楚。
异常结束必须保留所有邮件
早期POP3比较清楚地描述正常流程,却没有同样清楚地描述断线。RFC 1725把“澄清连接中断行为”列为修订目的,并规定:凡不是客户端主动发送QUIT造成的终止,都不得进入UPDATE,也不得删除maildrop中的任何邮件。闲置超时同样只关闭TCP连接。
1996年成为STD 53的RFC 1939保留了这条规则,还说明原因:异常终止时,客户端可能尚未成功接收或保存邮件。
协议没有假装能证明客户端磁盘的真实状态。断线前也许已经收全,正常QUIT也不等于完成了备份。它只是选择保守的共同信号。下次重复下载可以清理;唯一副本消失往往无法补救。
QUIT是一道提交门,而不是原子性魔法
把QUIT类比为commit只能解释“越过边界”,不能带来数据库的全部保证。RFC 1939规定,服务器在UPDATE中尝试移除所有标记邮件;若资源不足或发生其他错误,可能删除其中一些、全部或一个也没有。绝对不能删除未标记邮件。无论成功与否,服务器随后释放锁并关闭连接。
因此,边界之前的保证很强:标记可以撤销,异常终止保留全部邮件。边界之后的结果却可能部分成功。如果最后答复也丢失,客户端甚至无法确定哪些已经删除。
规范选择承认这种不确定性,因为简单服务器和多样存储后端未必能实现全有或全无。DELE后的+OK只能解释为“标记已接受”,不能显示成“远端副本已经消失”。
后来的保留策略仍服从UPDATE
当把邮件留在服务器上逐渐普遍,RFC 2449用EXPIRE能力声明保留政策。EXPIRE NEVER表示政策不删除;EXPIRE 0允许服务器把成功读取的邮件视为隐式加标记,但生效点仍是会话进入UPDATE之时。
扩展可以改变哪些邮件被标记,却没有把一次读取直接变成破坏,也没有让异常断线冒充告别。小型状态机因此能承接新政策而不牺牲原有安全边界。
告别保护的是保管权,不是礼貌
客户端决定何时完成预期的读取序列,服务器决定存储删除是否成功,网络只能打断它们,不能替代客户端授予不可逆权限。POP3让不确定性的后果更偏向重复邮件和后续核对,而不是静默丢失。
先标记,允许重置,明确跨过边界,尝试删除,诚实报告部分失败——这就是机制的全部力量。删除直到告别才开始成真;即使告别之后,协议也没有谎称世界一定整齐地一次改变。
来源与边界
历史源头见RFC 918和RFC 937;首个POP3状态机见RFC 1081,其延续见RFC 1225与RFC 1460。RFC 1725明确断线规则,RFC 1939规定现行行为、部分失败和保管理由,RFC 2449补充EXPIRE。它们不证明当前部署比例、任何产品的存储实现,也不承诺原子或恰好一次删除。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
