@ryancarson: https://x.com/ryancarson/status/2064751272834593135

X AI KOLs Following 工具

摘要

利用 Devin AI 设置自动化代理驱动灾难恢复的详细指南,涵盖两种备份策略(PITR 和异地备份)、执行行动手册以及现场破坏性测试。

https://t.co/x3iTohXm1J
查看原文
查看缓存全文

缓存时间: 2026/06/10 19:53

如何使用智能体实现灾难恢复自动化

作为早期采用者,你的智能体已经在100%地交付你的功能、修复和重构。拍拍自己的肩膀——该进阶到智能体驱动的自动化灾难恢复了。(作弊码:直接把这篇内容丢给你的智能体,然后说“实现这个”。)

数据库恢复是你整个技术栈中最吓人的按钮。它会造成破坏,很少用到,而当你真正需要它时,你会在凌晨2点惊慌失措,努力回忆哪个备份是好的。这正是那种应该写成智能体可执行的剧本的高风险、低频操作——关键在于,你必须在真正需要它之前,在真实条件下测试过它。

本文介绍我们是如何设置的:两种独立的备份策略(时间点恢复和异地转储)、智能体遵循的单一剧本、如何触发、如何验证,以及我们如何在不丢失数据的情况下,对生产环境进行真实的、具有破坏性的测试

我们使用的智能体是 @DevinAI,具体机制是 Devin 剧本——一个可复用的程序,Devin 加载并执行。我们将具体说明如何创建该剧本、Devin 如何运行它,以及(因为总有人问)剧本与技能有何不同。这些概念适用于任何有能力的编码智能体,但下面的连线是我们实际运行的。

在整个过程中,有两个标准词汇值得牢记,因为经验丰富的运维人员正是这样思考的:

  • RPO(恢复点目标): 可以承受的数据丢失量,以时间衡量。每日备份意味着RPO最多约24小时;持续PITR可缩短到秒级。
  • RTO(恢复时间目标): 允许恢复操作花费的时间。

另一个参照点是经典的 3-2-1 规则:至少 3 份数据副本,存储在 2 种不同介质/系统上,其中 1 份在异地。以下所有内容实际上只是该规则的一个具体、由智能体实现的版本,并明确设定了 RPO/RTO 目标。

为什么需要两种备份,而不是一种?

备份的黄金法则:从未恢复过的备份,只是一个希望。 单一的备份策略是单点故障。我们使用两种,因为它们的失败方式不同,覆盖不同的灾难场景:

1. 时间点恢复 (PITR) —— 你的快速“撤销”

大多数现代托管 Postgres 提供商(我们使用 @neondatabase - 它与 @vercel 集成非常容易;Supabase、RDS、Cloud SQL 等都有等效功能)会保留持续变更历史,让你可以将数据库回滚到保留窗口内的任意时刻(我们的是7天)。

  • 最佳场景: “我们刚刚在20分钟前运行了一个错误的迁移/错误的删除/有缺陷的部署。” 你将系统回滚到损坏发生前的那一刻。(极佳的RPO——秒级。)
  • 粒度: 精确到秒。
  • 速度 (RTO): 取决于提供商——不要假设“瞬间”。在 Neon 上,恢复是一个写时复制分支操作,几乎是即时的。在 RDS / Cloud SQL 上,PITR 从基础快照加上 WAL 回放配置一个全新实例,可能需要十几分钟到几小时,之后你再切换过来。了解你提供商的恢复机制,并在演练中计时,这样你的 RTO 是一个测量值,而不是猜测。
  • 杀手锏: 它是可逆的。当你恢复时,提供商会将恢复前的状态保留为单独的分支/快照。如果你的恢复操作是个错误,你可以撤销这个撤销。
  • 陷阱: 它位于与你生产数据库相同的提供商账户内。如果该账户被攻破、删除,或者提供商出现灾难性故障,你的 PITR 历史也会随之消失。

2. 异地转储 —— 你的“办公楼着火了”备份

这是一个写入不同供应商的对象存储(我们使用 AWS S3;GCS、Cloudflare R2、Backblaze B2 都可以)的备份。一个 cron 作业按计划运行(我们每天一次)。我们使用普通的 pg_dump,诚实地指出何时该工具是合适的选择:

  • 逻辑转储(pg_dump)适合中小型数据库——比如几十GB。它们简单,跨 Postgres 版本可移植,并且易于检查。但它们扩展性不佳:随着数据库增长,转储和(单线程)恢复会变得极其缓慢,并且夜间转储给出的是粗糙的RPO(最多约24小时)。
  • 对于更大或要求更高RPO的系统,升级到物理备份 + 持续的 WAL 归档到对象存储——工具如 pgBackRestWAL-GBarman。这些提供异地时间点恢复(不仅仅是夜间快照)、并行/更快的恢复,以及更好的RPO。如果你的数据库很大或者RPO目标很严格,把夜间 pg_dump 当作起点,并计划升级。

无论使用哪种机制:

  • 最佳场景: 提供商账户本身丢失、损坏或被锁定。或者你需要早于PITR窗口的备份。或者合规性要求一个不可变、可导出的副本。
  • 粒度 (RPO): 取决于你的节奏/归档(每日转储 = 潜在丢失最多约24小时;WAL归档 = 秒级)。
  • 速度 (RTO): 比PITR慢——你需要下载并重放。对于逻辑转储,恢复时间随数据库大小增长。
  • 杀手锏: 它是异地且不依赖特定供应商的。与主数据库完全独立的爆炸半径。
  • 陷阱: 逻辑转储是粗粒度的,并且只和最近一次运行一样新鲜。

同时拥有二者的意义: PITR 是你日常的、细粒度的、快速撤销。异地转储是你最坏情况下的保险。在真实事件中,你通常会一起使用它们——这正是我们演练的场景(下面详述)。

第一步:设置两种备份

在写剧本之前,这些必须存在。智能体可以帮助你构建这一切。

时间点恢复:

  • 确认你的提供商有PITR,并检查保留窗口(例如7天)。如果预算允许,延长它——窗口越长,你能恢复的灾难越多。
  • 验证恢复操作保留了之前的状态(Neon通过自动分支实现)。可逆性保证了实时测试的安全性。

异地转储:

  • 一个定时任务(GitHub Actions cron、Vercel cron、Lambda——任何合适的)运行 pg_dump,压缩并用 gzip 压缩,然后上传到不同供应商的存储桶。(扩展到生产规模时,将其替换为像 pgBackRest/WAL-G 这样写入同一存储桶的WAL归档工具。)
  • 一个开启了版本控制且具有合理生命周期/保留策略的存储桶。如果需要防勒索软件、防篡改的副本,考虑对象锁定/不可变性
  • 一个只读、最小权限的凭据,仅作用于该备份存储桶,智能体可以使用它来列出和下载转储。不要将你的根密钥交给智能体。
  • 额外功能:启用手动触发(例如 workflow_dispatch),这样你可以在几分钟内生成立即转储,而不是等待夜间运行。

💡 提示: 了解实际的转储时间,而不是 cron 表达式。我们的任务计划在03:00 UTC运行,但由于CI排队时间,实际约在04:30 UTC完成。当你在推断“我们会丢失多少数据”时,这个细节很重要。

第二步:编写剧本

在 Devin 中,剧本是一个一等公民的可复用程序,你编写一次,然后附加到任何会话中。你可以在 Devin Web 应用(设置 → 剧本)中创建,给它一个名称和一个触发宏(我们的是 !database_restore),并将主体写成一个通俗易懂、逐步的操作手册。之后,团队任何人都可以启动一个 Devin 会话,附加该剧本(或输入宏),Devin 加载这些指令并自己执行它们——调用数据库/提供商API、运行 psql、切换维护模式、并报告回来。你并不是在编写 Devin 调用的代码;你是在编写 Devin 遵循的检查清单。 (如果你使用的是另一个没有剧本概念的智能体,将相同的内容作为仓库中结构良好的 RESTORE.md 文件,并在提示中引用它,就能达到大部分效果。)

关键见解:剧本就是操作手册。 你正在编写一个细心的人会遵循的检查清单,精确到智能体可以在危险部分不即兴发挥就能执行的程度。

我们的剧本有两种模式:

  • 验证模式(默认,非破坏性): 恢复到一次性分支,检查数据看起来正确,然后丢弃。这是你按计划运行以保持诚实的方式。它不触及任何真实数据。
  • 灾难模式(破坏性,需要明确授权): 真实操作,针对生产数据库。

一个好的恢复剧本需要按顺序说明:

  • 首先进行排查。 确认确实是数据问题,并确定精确的恢复时间戳(“恢复到09:15 UTC之前的状态”)。
  • 在接触数据库之前,将应用置于维护模式,这样应用写入和cron作业会停止,你就不会在恢复过程中得到损坏的数据。(见步骤4——使其即时生效,并注意其实际限制:中间件阻止前端写入,并非阻止所有可能的写入者。)
  • 选择路径: 损坏在PITR窗口内且提供商健康 → PITR。提供商账户被攻破,或者你需要更旧的/异地副本 → S3转储
  • 首先对当前状态进行快照,即使它已损坏——将其命名为类似 main-before-restore- 这样的明显名称。这是你的“撤销之撤销”安全网。
  • 执行恢复(特定的提供商API调用或psql命令)。
  • 验证(下方步骤5)——仍然在维护模式下进行。
  • 只有验证通过后,才能解除维护模式。
  • 报告:恢复了什么,恢复到什么时间,安全分支名称,总停机时间,以及前后行数。

要将以下内容融入剧本,这样智能体就不会搬起石头砸自己的脚:

  • 硬性门控: “如果验证失败,保持维护模式开启并停止。不要在错误恢复上解除维护。”
  • 无中断的预检: 在启用维护之前,检查凭据有效性以及转储是否可下载/有效。如果S3不可达,你会在关闭网站之前就知道。
  • 永远不要在运行过程中删除安全分支。 清理是一个独立的、由人工批准的决策。
  • 灾难模式需要明确授权。

剧本与技能——有什么区别?
经验法则:如果你希望智能体自行决定何时应用某些知识,那就做成技能。如果你希望人工有意识地拉动某个杠杆,那就做成剧本。
破坏性的数据库恢复正是剧本的教科书案例,而不是技能。你绝不希望智能体自动决定覆盖生产——这是一个由人工有意拉动、需要授权的杠杆,而这正是手动附加的剧本所提供的。(技能非常适合围绕它的非破坏性习惯——例如,一个仓库技能说明“如何将计划中的验证恢复运行到一次性分支中”。)

第三步:触发智能体

我们有两种触发方式,对应两种不同情况:

真实事件(你,手动): 打开一个 Devin 会话,附加剧本或输入宏 (!database_restore),告诉它发生了什么:“我们大约在09:15 UTC执行了一次错误删除,将生产恢复到09:10。” Devin 加载剧本并逐步执行,在剧本要求暂停的地方暂停。

监督式演练(Devin 生成子 Devin): 在我们的实时测试中,我们让一个主 Devin 会话生成一个单独的 Devin 子会话,专门用于运行剧本,并在实时中观察其工作。Devin 可以启动和监控子会话,这使得操作干净整洁:

  • 子智能体在其自己的机器上从头到尾执行程序。
  • 父智能体监控进度而不干扰,并向你传递里程碑(“维护模式开启”、“恢复完成”、“已验证”、“维护模式关闭”)。
  • 你会得到一个干净、可审计的抄本,记录着确切执行了什么。

第四步:让维护模式即时生效

这是安全恢复背后默默无闻的英雄。你不可能在写入者还在操作数据库时进行干净的恢复。 你需要一个在几秒内就能:

  • 将所有流量路由到维护页面,
  • 停止应用驱动的写入
  • 并暂停cron/后台作业的开关。

要精确理解“维护模式”实际冻结了什么。 应用层中间件只会停止通过应用前端的写入。它不会自动停止:后台工作进程和队列消费者、命中其他入口点的入站Webhook、已经处于运行中的计划任务,或任何直接连接到数据库的内容。你的维护开关也必须对这些路径进行门控(我们冻结cron,并在API/服务端操作层拒绝写入),并且你应该接受在标志翻转的瞬间,仍有少量正在进行的写入可能落地。唯一真正的写入冻结是在数据库本身——例如,撤销写入权限、将数据库设为只读,或终止所有其他连接。对于短暂的恢复窗口,应用层门控加上暂停的cron通常足够;只是不要告诉自己这是一个硬性保证。

要避免的错误:将维护模式门控在需要重新部署才能修改的环境变量后面。在事件期间,等待3-5分钟来部署切换维护模式是极其痛苦的,并且会扩大你的数据丢失窗口。我们使用在每个请求的中间件中读取的低延迟边缘配置存储(我们使用Vercel Edge Config;Redis键或任何快速KV存储都可以)使其即时生效且无需重新部署

  • 一个 maintenanceMode 标志,中间件在每个请求上检查,将所有请求重定向到 /maintenance。
  • 通过API调用,标志在约1–3秒内翻转——无需重新部署
  • 故障打开(刻意做出的可用性权衡): 如果配置读取出错,默认提供流量而不是显示维护页面,这样配置存储的短暂故障就不会黑掉你的整个网站。其代价是事件期间配置中断不会自动门控写入——如果你更倾向于保证门控,则改用故障关闭。有目的地选择失败模式。
  • 额外功能:将维护页面的标题/消息/预计完成时间(ETA)存储在同一个配置中,这样你可以在不发布代码的情况下实时更新文案(“预计10:30 ET恢复”)。

我们给了智能体一个针对此功能的小型CLI(maintenance-mode on|off|status),因此剧本步骤只需一条命令。

第五步:验证它确实有效(但不影响生产)

将验证构建成一个你日常持续运行的例行程序,而不仅仅是在事件期间:

  • 计划中的验证恢复。 让智能体按计划将最新的异地转储备份恢复到一次性分支,运行完整性检查,并进行报告。如果转储备份损坏或恢复机制出问题,你在周二的下午就能知道——而不是在火情期间。
  • 有意义的完整性检查。 关键表(用户、你的核心领域表)的行数,确认所有模式都存在,并检查高写入表中最新的时间戳以确认新鲜度。
  • 凭据检查。 确认智能体的备份凭据以预期的最小权限身份进行认证,并且可以列出/读取存储桶。(关于原因详情见下方。)

⚠️ 演练能发现的错误类型。 演练通常会暴露出在纸面上看起来没问题的问题:已过期或范围错误的凭据、失去存储桶读取权限的备份身份、已过期的密钥、悄悄漂移的IAM策略。在有人实际执行路径之前,这些问题都是不可见的——而且它们在全新的、冷启动的紧急会话中最容易造成严重破坏,因为该会话没有你笔记本电脑上的缓存状态。运行演练可以在零生产影响下清除这些问题,这样你就可以集中修复凭据/策略,并在问题真正发生前重新运行。
从未测试过的备份,往往会在关键时刻辜负你。

第六步:进行一次真实的、有破坏性的测试

首先,直言不讳地说明标准实践:测试恢复的正常安全方式是非破坏性的,恢复到单独的分支/克隆/预发布实例(步骤5)。你应该按计划这样做,对于大多数团队来说,这已经足够了——它证明了转储是好的,恢复机制有效,而从不冒生产环境的风险。如果你没有进行这一步……

相似文章

NirDiamant/agents-towards-production

GitHub Trending (daily)

一个全面的开源指南,包含将AI代理转化为生产就绪产品的教程,涵盖部署、记忆、安全等。