关于 diagnosing-failed-warehouse-syncs
用于逐层诊断数据仓库数据源或表同步问题的技能,适合处理失败、卡住、数据陈旧或异常的情况。它根据错误原因选择恢复操作,并要求在执行会丢弃数据的操作前取得明确批准。
主要功能
- 01定位数据源与表级故障
- 02根据错误信息判断原因
- 03选择针对性的恢复操作
- 04执行破坏性操作前确认
适用场景
- 01排查凭据失效或网络故障
- 02处理运行数小时未结束的同步
- 03修复字段变更导致的同步错误
- 04诊断 CDC 或 Webhook 问题
MCP 相关
该技能使用 PostHog MCP 工具检查数据源与表架构状态,并在确认适当后触发重载、重同步、配置更新或 Webhook 操作。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ posthog/ skills --skill diagnosing-failed-warehouse-syncs安装后在 Claude Code 中输入/diagnosing-failed-warehouse-syncs确认已加载。
详细介绍
诊断数据仓库同步失败
当数据仓库源或表同步失败、卡住或产生错误数据时,请自上而下进行排查:源 → 架构 → 恢复操作。不要直接选择“从头重新同步”——这会丢弃已同步的数据并从零开始,这通常不是首选步骤。
何时使用此技能
- 用户报告特定同步失败(例如:“我的 Stripe 源显示红色”)
- 某张表处于
Running状态的时间远超预期 - 数据仓库表中的数据已过时、缺少行或看起来已损坏
- 架构标记为
Completed,但最新的行仍未出现 - 用户在取消 / 重新加载 / 重新同步 / 删除数据之间犹豫,不确定该选哪种
- 另一个技能(通常是
auditing-warehouse-source-health)发现了失败的源或架构,用户希望进一步排查
用户报告和审计移交这两种入口使用相同的工作流;审计移交意味着你已知道要排查哪个项目,可以跳过步骤 1 中的搜索。
可用工具
| 工具 | 用途 |
|---|---|
external-data-sources-list | 列出所有源及其连接状态和最新错误 |
external-data-sources-retrieve | 获取单个源的完整详情,包括其所有架构 |
external-data-schemas-list | 列出所有源中的所有表架构,以及各表的状态和最新错误 |
external-data-schemas-retrieve | 获取单个架构的完整详情,包括 sync_type_config |
external-data-schemas-cancel | 取消当前处于 Running 状态的同步 |
external-data-schemas-reload | 使用已配置的同步方法触发同步(遵循增量设置) |
external-data-schemas-resync | 完整重新同步——清除已同步的数据并重新开始。具有破坏性 |
external-data-schemas-delete-data | 删除已同步的表,但保留架构条目 |
external-data-schemas-partial-update | 更改 sync_type / incremental_field / cdc_table_mode |
external-data-sources-partial-update | 轮换凭据后更新源的凭据(job_inputs) |
external-data-sources-reload | 重新触发某个源中每个已启用架构的同步 |
external-data-sources-refresh-schemas | 重新获取源的表列表,以发现新表 |
external-data-sources-check-cdc-prerequisites-create | 验证某个源的 Postgres CDC 设置 |
external-data-schemas-incremental-fields-create | 在源架构发生变化后刷新候选增量字段 |
external-data-sources-webhook-info-retrieve | 检查 webhook 注册状态和外部服务状态 |
external-data-sources-create-webhook-create | 重新注册已丢失或从未注册的 webhook |
external-data-sources-update-webhook-inputs-create | 在源端轮换后更新签名密钥 |
external-data-sources-delete-webhook-create | 重新注册前移除损坏的 webhook |
工作流
步骤 1 — 定位出错项
如果用户指定了来源,请直接调用 external-data-sources-retrieve。否则,先调用
external-data-sources-list 和 external-data-schemas-list,找出状态为红色的项。
有两种故障:
- 来源级故障(
ExternalDataSource.status = "Error"):连接本身已中断,可能是凭据过期、 主机不可访问或账户已停用。会影响所有表。 - 架构级故障 — 来源连接正常,但一个或多个表出错。在
external-data-schemas-list返回的序列化 API 响应中,查找status值为"Failed"、"Billing limits"或"Billing limits too low"的项。(底层模型的枚举值为BillingLimitReached和BillingLimitTooLow,但序列化器会重写这些值,因此请同时匹配人类可读形式和枚举形式,以确保万无一失。)
来源的顶层状态可能显示为 Completed,但其某个架构的状态却是 Failed — 请务必同时检查两者。
步骤 2 — 判断架构状态
在 external-data-schemas-list 的结果中,每个架构都有一个 status:
| 状态 | 含义 | 通常表示 |
|---|---|---|
Running | 正在执行同步 | 正常,除非已卡住数小时 |
Completed | 上次同步已成功完成 | 状态正常 |
Failed | 上次同步出错 — 查看 latest_error | 需要诊断 |
Paused | 用户已停用同步(should_sync = false) | 有意停用 |
Billing limits(序列化器)/ BillingLimitReached(枚举) | 团队已达到其数据仓库行数配额 | 计费问题,而非技术故障 |
Billing limits too low(序列化器)/ BillingLimitTooLow(枚举) | 团队的额度不足 | 计费问题 |
请务必结合 last_synced_at 检查状态。如果某个架构的状态为 Running,但 last_synced_at 显示是 12 小时前,则它几乎可以确定已卡住,即使状态并非 Failed。
第 3 步 — 解读 latest_error
将 latest_error 字符串映射到根本原因。常见模式:
| 错误子串 | 根本原因 | 修复 |
|---|---|---|
authentication failed、401、403、invalid credentials | 凭据已过期或轮换 | 用户轮换凭据,然后使用新的 job_inputs 执行 external-data-sources-partial-update |
Could not establish session to SSH gateway、Could not connect to your SSH tunnel | SSH 隧道配置错误或远程主机已关闭 | 用户检查 SSH 主机、密钥和堡垒机 |
Primary key required for incremental syncs | 表没有主键,且 sync_type 为 incremental/cdc | 在数据源中添加主键,或将架构切换为 full_refresh |
primary keys for this table are not unique | 声明的主键列实际上并不唯一 | 通过 partial-update 选择其他主键列 |
Integration matching query does not exist | 数据源保存的集成已被删除 | 重新创建数据源 |
column "X" does not exist、does not have a column named | 架构漂移 — 增量字段或跟踪列已被移除 | 使用 incremental-fields-create 重新检测,然后执行 partial-update |
relation "..." does not exist | 数据源表已被删除或重命名 | 移除架构或在数据源端重命名 |
SSL、connection refused、timeout、unreachable | 网络/防火墙/主机连通性 | 用户端操作 — 检查主机、端口和允许列表 |
replication slot、publication、wal_level | CDC 前置条件异常 | 运行 check-cdc-prerequisites-create;可能需要重新创建槽 |
Schema exceeds row limit、billing | 账单限制 | 升级套餐或停用该架构 |
如果 latest_error 为 null,但架构状态为 Failed,请直接获取架构信息 — 错误可能只会显示在详情视图中。
第 4 步 — 选择恢复操作
恢复操作取决于根本原因,而不仅仅是状态。根据用户的情况选择以下操作之一:
A. 暂时性故障(网络瞬断、API 临时中断)
- 迄今为止同步的数据仍然有效。
- 操作:使用
external-data-schemas-reload,按照已配置的同步方法重试。 - 增量/追加同步会从上次中断处继续。
B. 凭据已过期或轮换
- 数据源下的所有架构都因身份验证错误而失败。
- 操作:用户轮换凭据 → 使用新的
job_inputs执行external-data-sources-partial-update→ 数据源状态恢复为运行中时会自动重新加载,或使用external-data-sources-reload手动触发。
C. 架构漂移 — 列已重命名、删除或类型已更改
- 错误指出了一个与源不再匹配的特定列。
- 操作:先调用
external-data-schemas-incremental-fields-create获取当前字段,然后调用external-data-schemas-partial-update,并修正incremental_field/incremental_field_type/primary_key_columns。通常无需清除数据。
C2. 源数据库中新增或重命名了表
- 用户提到“我在 Postgres 中新增了一张表,但它没有显示”,或源表被重命名。
- 操作:调用
external-data-sources-refresh-schemas获取新增的表列表,然后为任何新 schema 配置同步。
D. 增量状态有误(重复、缺少行、数据看起来已损坏)
- Schema 状态可能为
Completed——这本身不算“失败”,而是数据有误。 - 操作:调用
external-data-schemas-resync清除已同步数据,并从源重新导入。此操作具有破坏性,但通常是解决数据质量问题的正确做法。
E. Postgres 上的 CDC 管道损坏
- 错误提到了 replication slot、publication、WAL。
- 操作:调用
external-data-sources-check-cdc-prerequisites-create列出故障项,在 Postgres 端修复,然后调用external-data-schemas-reload。如果 WAL 位置已丢失,有时无法避免执行resync。
F. 同步卡在 Running 状态数小时
- 检查
last_synced_at。如果它显示的是数小时前,且状态仍为Running,则该任务已成为孤立任务。 - 操作:调用
external-data-schemas-cancel停止任务,然后调用external-data-schemas-reload。
G. 表数据已损坏,但你想保留 schema 配置
- 操作:调用
external-data-schemas-delete-data删除已同步的表,但保留 schema 条目。此操作也会关闭同步,因此请调用external-data-schemas-partial-update并设置should_sync: true,然后重新加载。重新加载会从头重新导入,而不会丢失已配置的 sync_type/incremental_field。
H. 计费额度限制
- 这不是技术问题。请说明额度限制,建议升级套餐,或禁用优先级较低的 schema,让重要的 schema 保持在额度范围内。
I. 由 Webhook 驱动的 schema 未收到事件
- 症状:schema 的
sync_type: "webhook",初始批量同步已完成,但源端有活动时仍没有新行到达。状态可能仍显示为Completed,因为批量同步(作为安全网的定期同步)运行正常——问题出在推送路径上。 - 操作:
- 调用
external-data-sources-webhook-info-retrieve({source_id})。 - 如果
exists: false→ webhook 从未注册,或已被删除。调用create-webhook-create注册它。 - 如果
exists: true,但external_status.error已设置 → 通常是“API key doesn't have permission to read webhooks”(API 密钥没有读取 webhook 的权限)或类似错误。Webhook 可能已在源端的控制台中被删除。请重新创建。 - 如果
external_status.status不为"enabled"→ 源已禁用 webhook(通常是因为多次投递失败)。请重新启用或重新注册。 - 如果载荷已到达,但签名验证失败 → 签名密钥已轮换。请从源端的控制台获取新密钥,并调用
update-webhook-inputs-create({source_id}, {inputs: {signing_secret: "..."}})。
- 调用
- 修复后,请检查源端的 webhook 日志,确认 PostHog 现在已返回 2xx。
第 5 步——执行破坏性操作前先确认
以下三种恢复操作会丢弃数据,且无法撤销:
external-data-schemas-resync— 清除已同步的行,并从头重新导入external-data-schemas-delete-data— 删除已同步的表external-data-sources-destroy— 删除源及其所有 schema
在调用任何一项操作前,务必先说明你建议的修复方案,并等待明确批准。“先试试 resync”很少是合适的默认做法。
交互示例
User: "Our Stripe sync is broken, can you check?"
Agent:
- external-data-sources-list → find Stripe source, status = Error
- external-data-sources-retrieve({id}) → latest_error: "authentication failed: 401 Unauthorized"
- Report: "Your Stripe source's API key is no longer authenticating.
All 8 tables under it are failing with 401s. This usually means the key was rotated on the Stripe side.
To fix:
1. Grab a fresh restricted API key from the Stripe dashboard.
2. I'll update the source with the new key.
3. Syncs will resume automatically — no data loss.
Paste the new key here when ready."
User: "sk_live_..."
Agent:
- external-data-sources-partial-update({id}, {job_inputs: {stripe_secret_key: "sk_live_..."}})
- external-data-sources-reload({id}) to trigger retry
- Report: "Updated and re-triggered. Check back in a few minutes — latest_error should clear."
重要说明
- 诊断时,来源状态优先于架构状态。 如果来源状态为
Error,其下的所有内容都无法正常工作; 修复来源通常就能一次性修复其所有架构。 Running并不总是表示运行正常。 请交叉检查last_synced_at。如果同步卡在Running,需要先执行cancel,再执行reload,而不是resync。- 重新同步具有破坏性。 它会丢弃已同步的数据。只有在数据本身有问题(重复、缺少行、损坏),或恢复确实需要从头开始时(CDC 中丢失了 WAL 位置)才建议这样做。绝不要将其作为应对临时错误的首选方案。
- 删除数据会保留配置。 当用户说“我只想把这张表从头开始”时,优先选择
delete-data+reload,而不是resync+ 新建架构条目——这样可以保留已配置的 sync_type / incremental_field / PK 设置。delete-data会关闭同步,因此在重新加载前请设置should_sync: true。 - 故障可能出在目标端,而不是来源端。 有些项目除了将来源数据同步到 PostHog 外,也会同步到自己的数据库。出现这种情况时,
latest_error会以目标端名称为前缀,例如:customer postgres: connection refused。这是客户的数据库拒绝了写入,而不是来源提取失败——请检查他们的数据库及凭据,而不是来源端。所有目标端共用同一个生命周期,因此任何一个无法访问的目标端都会阻塞整个同步,包括 PostHog。 - 账单限制不是技术故障。 不要尝试通过重试或重新配置来解决。请转给账单团队处理。
- Webhook 故障可能被正常状态掩盖。 如果 Webhook 类型的架构通过批量回退同步成功,即使推送通道已损坏,状态仍会显示为
Completed。当用户在 Webhook 架构上说“我的数据已经延迟好几个小时”时,请先调用webhook-info-retrieve,再查看架构状态。Webhook 问题不会显示在external-data-schemas-list中。