diagnosing-failed-warehouse-syncs について
失敗、停止、遅延、または不正なデータウェアハウス同期を診断するスキルです。エラーに応じて復旧方法を選び、データを破棄する操作の前には明示的な承認を求めます。
主な機能
- 01ソースとテーブルの障害特定
- 02エラー詳細に基づく原因診断
- 03原因に応じた復旧操作の選択
- 04破壊的操作の前の確認
活用シーン
- 01認証情報やネットワークエラーの調査
- 02進行中のまま停止した同期の復旧
- 03スキーマ変更による同期エラーの修正
- 04CDCや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 | 1 つのソースの詳細と、そのすべてのスキーマを取得します |
external-data-schemas-list | すべてのソースにわたるすべてのテーブルスキーマと、テーブルごとのステータスおよび最新のエラーを取得します |
external-data-schemas-retrieve | sync_type_config を含む、1 つのスキーマの詳細を取得します |
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 を使って、どれが赤くなっているかを確認します。
失敗には 2 種類あります。
- ソースレベル(
ExternalDataSource.status = "Error"):接続自体に問題があります。認証情報の期限切れ、 ホストに到達できない、アカウントが無効になっているなどが原因です。すべてのテーブルに影響します。 - スキーマレベル — ソースへの接続は正常ですが、1 つ以上のテーブルでエラーが発生しています。
external-data-schemas-listの シリアライズされた API レスポンスで、statusの値が"Failed"、"Billing limits"、または"Billing limits too low"となっているものを探します。(基盤となるモデルの列挙値はBillingLimitReachedとBillingLimitTooLowですが、 シリアライザーが書き換えるため、念のため人間が読める値と列挙値の両方で照合してください。)
ソース全体のステータスが Completed でも、その中のスキーマの 1 つが 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を実行 → ソースのステータスが running に戻ると自動的に再読み込みされます。または、external-data-sources-reloadで手動で実行します。
C. スキーマの変化 — 列の名前変更、削除、または型の変更
- エラーに、ソースと一致しなくなった特定の列が記載されています。
- 対処:
external-data-schemas-incremental-fields-createで現在のフィールドを取得し、修正したincremental_field/incremental_field_type/primary_key_columnsを指定してexternal-data-schemas-partial-updateを実行します。通常、データを消去する必要はありません。
C2. ソースデータベースでテーブルが追加または名前変更された
- 「Postgres に新しいテーブルを追加したのに表示されない」という報告がある、またはソーステーブルの名前が変更されています。
- 対処:
external-data-sources-refresh-schemasで新しいテーブル一覧を取得し、新しいスキーマの同期を設定します。
D. インクリメンタル同期の状態が正しくない(重複、行の欠落、データの破損など)
- スキーマのステータスが
Completedの場合もあります。これは必ずしも「失敗」ではなく、データに問題がある状態です。 - 対処:
external-data-schemas-resyncで同期済みデータを消去し、ソースから再インポートします。破壊的な操作ですが、データ品質に問題がある場合は多くの場合、適切な対処です。
E. Postgres の CDC パイプラインが機能していない
- エラーにレプリケーションスロット、パブリケーション、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. スキーマ設定は保持したまま、テーブルデータを修復したい
- 対処:
external-data-schemas-delete-dataでスキーマエントリを保持したまま同期済みテーブルを削除します。同期もオフになるため、external-data-schemas-partial-updateでshould_sync: trueを設定してから、再読み込みします。再読み込みでは、設定済みの sync_type/incremental_field を失うことなく、最初から再インポートします。
H. 課金上限
- 技術的な対処はありません。上限を説明し、プランのアップグレード、または優先度の低いスキーマの無効化によって、重要なスキーマが割り当て量内に収まるよう案内します。
I. Webhook を使用するスキーマでイベントを受信できない
- 症状:スキーマの
sync_type: "webhook"が設定され、初回の一括同期は完了しているものの、ソース側でアクティビティがあるにもかかわらず新しい行が届きません。一括同期(セーフティネットとしての定期実行)が成功しているため、ステータスはCompletedのままの場合があります。問題はプッシュ経路にあります。 - 対処:
external-data-sources-webhook-info-retrieve({source_id})を実行します。exists: falseの場合 → Webhook が登録されていないか、削除されています。create-webhook-createを呼び出して登録します。exists: trueでexternal_status.errorが設定されている場合 → 通常は「API キーに Webhook を読み取る権限がありません」などのエラーです。ソースのダッシュボードで Webhook が削除された可能性があります。再作成してください。external_status.statusが"enabled"でない場合 → ソース側で Webhook が無効化されています(通常、配信失敗が繰り返された後に発生します)。再度有効にするか、再登録してください。- ペイロードは届いているものの、署名検証に失敗する場合 → 署名シークレットがローテーションされています。ソースのダッシュボードで新しいシークレットを取得し、
update-webhook-inputs-create({source_id}, {inputs: {signing_secret: "..."}})を呼び出します。
- 修正後、ソース側の Webhook ログを確認し、PostHog が 2xx で応答していることを確かめます。
ステップ 5 — 破壊的な操作の前に承認を得る
次の 3 つの復旧操作はデータを破棄し、取り消すことができません。
external-data-schemas-resync— 同期済みの行を消去し、最初から再インポートしますexternal-data-schemas-delete-data— 同期済みテーブルを削除しますexternal-data-sources-destroy— ソースとそのすべてのスキーマを削除します
これらの操作を呼び出す前に、提案する対処を必ず提示し、明示的な承認を待ってください。「とりあえず再同期してみる」は、通常、適切な初期対応ではありません。
やり取りの例
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のまま止まっている同期には、resyncではなくcancelの後にreloadが必要です。- 再同期は破壊的な操作です。 同期済みデータが破棄されます。データ自体に問題がある場合(重複、行の欠落、破損)、または復旧にデータを完全に消去した状態がどうしても必要な場合(CDC で WAL の位置が失われた場合)にのみ推奨してください。一時的なエラーに対する最初の手段としては使用しないでください。
- データの削除では設定は保持されます。 ユーザーが「このテーブルを最初からやり直したいだけ」と言っている場合は、
resyncと新しいスキーマエントリの組み合わせよりも、delete-dataとreloadの組み合わせを優先してください。設定済みの sync_type / incremental_field / PK の設定が保持されます。delete-dataを実行すると同期がオフになるため、リロードの前にshould_sync: trueを設定してください。 - 障害の原因はソースではなく、宛先にある場合があります。 プロジェクトによっては、ソースを PostHog だけでなく、自社のデータベースにも同期しています。その場合、
latest_errorの先頭には宛先の名前が付きます。例:customer postgres: connection refused。これは顧客のデータベースが書き込みを拒否しているのであり、ソースからの抽出が失敗しているのではありません。ソースではなく、顧客のデータベースと認証情報を確認してください。すべての宛先でライフサイクルが共有されるため、到達できない宛先が1つあるだけで、PostHog を含む同期全体が滞ります。 - 請求制限は技術的な障害ではありません。 再試行や設定変更で解決しようとしないでください。請求担当に引き継いでください。
- Webhook の障害は、ステータスが緑色でも見えない場合があります。 Webhook タイプのスキーマで一括フォールバック同期が成功すると、プッシュチャネルが機能していなくても
Completedと表示されます。Webhook スキーマで「データが数時間遅れている」とユーザーが言っている場合は、スキーマのステータスを確認する前にwebhook-info-retrieveを呼び出してください。Webhook の問題はexternal-data-schemas-listには表示されません。