diagnosing-failed-warehouse-syncs

Par posthog · skills

Diagnostiquer pourquoi une synchronisation vers un data warehouse échoue et recommander la bonne action de récupération. À utiliser quand l'utilisateur demande « pourquoi ma sync Stripe/Postgres/HubSpot ne fonctionne pas ? », « cette table est bloquée depuis des heures », « les données dans le warehouse semblent incorrectes », ou souhaite dépanner une source ou un schéma spécifique. Couvre les échecs au niveau source ou schéma, les états Running bloqués, les erreurs de credentials et de schema drift, les mauvaises configurations de champ incrémental, les échecs de prérequis CDC, ainsi que les actions de récupération cancel / reload / resync / delete-data.

npx skills add https://github.com/posthog/skills --skill diagnosing-failed-warehouse-syncs

Diagnostic des syncs de data warehouse défaillants

Procédez de haut en bas quand une source ou une table de data warehouse échoue, est bloquée ou produit de mauvaises données : source → schéma → action de récupération. N'allez pas directement à « resync from scratch » — cela supprime les données synchronisées et redémarre de zéro, ce qui est rarement la bonne première étape.

Quand utiliser cette compétence

  • L'utilisateur signale qu'un sync spécifique échoue (par ex. « ma source Stripe est rouge »)
  • Une table est en état Running beaucoup plus longtemps que prévu
  • Les données d'une table du warehouse sont obsolètes, il manque des lignes ou elles semblent corrompues
  • Les dernières lignes n'apparaissent pas malgré un schéma marqué Completed
  • L'utilisateur hésite entre cancel / reload / resync / delete-data
  • Une autre compétence — typiquement auditing-warehouse-data-health — a repéré une source ou un schéma défaillant et l'utilisateur veut creuser

Les deux points d'entrée (signalement utilisateur et remise d'audit) utilisent le même workflow ; l'audit signifie simplement que vous savez déjà quel élément diagnostiquer et pouvez sauter la recherche découverte de l'étape 1.

Outils disponibles

Outil Objectif
external-data-sources-list Lister toutes les sources avec statut de connexion et dernière erreur
external-data-sources-retrieve Détails complets d'une source avec tous ses schémas
external-data-schemas-list Tous les schémas de table sur toutes les sources, avec statut et latest_error
external-data-schemas-retrieve Détails complets d'un schéma avec sync_type_config
external-data-schemas-cancel Annuler un sync en état Running
external-data-schemas-reload Déclencher un sync via la méthode configurée (respecte incremental)
external-data-schemas-resync Resync complet — efface les données synchro et redémarre. Destructif
external-data-schemas-delete-data Supprimer la table synchro mais garder l'entrée schéma
external-data-schemas-partial-update Changer sync_type / incremental_field / cdc_table_mode
external-data-sources-partial-update Mettre à jour les credentials d'une source (job_inputs) après rotation
external-data-sources-reload Relancer les syncs pour tous les schémas activés d'une source
external-data-sources-refresh-schemas Re-récupérer la liste de tables de la source pour détecter les nouvelles
external-data-sources-check-cdc-prerequisites-create Vérifier la configuration CDC Postgres d'une source
external-data-schemas-incremental-fields-create Rafraîchir les champs incremental candidats si le schéma source a changé
external-data-sources-webhook-info-retrieve Vérifier l'état d'enregistrement du webhook et le statut du service externe
external-data-sources-create-webhook-create Réenregistrer un webhook perdu ou jamais enregistré
external-data-sources-update-webhook-inputs-create Mettre à jour le secret de signature après rotation côté source
external-data-sources-delete-webhook-create Supprimer un webhook cassé avant réenregistrement

Workflow

Étape 1 — Localiser l'élément défaillant

Si l'utilisateur a nommé une source, allez directement à external-data-sources-retrieve. Sinon, commencez par external-data-sources-list et external-data-schemas-list pour trouver ce qui est rouge.

Deux types de défaillance :

  • Au niveau source (ExternalDataSource.status = "Error"): la connexion elle-même est cassée — credentials expirées, hôte inaccessible, compte désactivé. Affecte chaque table.
  • Au niveau schéma — la source se connecte bien mais une ou plusieurs tables échouent. Dans la réponse API sérialisée de external-data-schemas-list, cherchez les valeurs status "Failed", "Billing limits", ou "Billing limits too low". (Les valeurs enum du modèle sous-jacent sont BillingLimitReached et BillingLimitTooLow, mais le sérialiseur les réécrit — faites correspondre les deux formes pour être sûr.)

Une source peut afficher Completed au niveau supérieur tandis que l'un de ses schémas est Failed — toujours vérifier les deux.

Étape 2 — Classifier le statut du schéma

De external-data-schemas-list, chaque schéma a un status :

Statut Signification Signifie généralement
Running Sync actuellement en exécution Normal, sauf s'il est bloqué pendant des heures
Completed Dernier sync terminé avec succès Sain
Failed Dernier sync en erreur — voir latest_error Nécessite diagnostic
Paused Utilisateur a désactivé le sync (should_sync = false) Intentionnel
Billing limits (sérialiseur) / BillingLimitReached (enum) Équipe a atteint son quota de lignes warehouse Problème de facturation, pas technique
Billing limits too low (sérialiseur) / BillingLimitTooLow (enum) L'équipe n'a pas assez de crédit Problème de facturation

Toujours vérifier last_synced_at avec le statut. Un schéma en Running avec last_synced_at d'il y a 12 heures est presque certainement bloqué, même si le statut n'est pas Failed.

Étape 3 — Interpréter latest_error

Mappez la chaîne latest_error à une cause racine. Motifs courants :

Substring d'erreur Cause racine Correction
authentication failed, 401, 403, invalid credentials Credentials expirées ou tournées Utilisateur tourne les creds, puis external-data-sources-partial-update avec nouveau job_inputs
Could not establish session to SSH gateway Tunnel SSH mal configuré ou hôte distant down Utilisateur vérifie hôte SSH/clé/bastion
Primary key required for incremental syncs Table n'a pas de PK et sync_type est incremental/cdc Ajouter PK dans source, ou passer schéma à full_refresh
primary keys for this table are not unique Les colonnes PK déclarées ne sont pas vraiment uniques Choisir différentes colonnes PK via partial-update
Integration matching query does not exist L'intégration sauvegardée de la source a été supprimée Recréer la source
column "X" does not exist, does not have a column named Dérive de schéma — colonne incremental ou tracée supprimée Utiliser incremental-fields-create pour re-détecter, puis partial-update
relation "..." does not exist Table source supprimée/renommée Supprimer schéma ou renommer côté source
SSL, connection refused, timeout, unreachable Réseau / pare-feu / accessibilité hôte Côté utilisateur — vérifier hôte/port/allowlist
replication slot, publication, wal_level Prérequis CDC cassés Exécuter check-cdc-prerequisites-create ; may need slot recreate
Schema exceeds row limit, billing Limite de facturation Mettre à niveau le plan ou désactiver le schéma

Si latest_error est null mais le schéma est Failed, récupérez le schéma directement — l'erreur peut seulement être remplie en vue détail.

Étape 4 — Choisir l'action de récupération

L'action de récupération dépend de la cause racine, pas juste du statut. Faites correspondre la situation de l'utilisateur à l'une de celles-ci :

A. Défaillance transitoire (accroc réseau, panne API temporaire)

  • Les données synchro jusqu'à présent restent valides.
  • Action : external-data-schemas-reload pour réessayer via la méthode configurée.
  • Les syncs incremental/append reprennent où ils se sont arrêtés.

B. Credentials expirées ou tournées

  • Chaque schéma sous la source échoue avec une erreur auth.
  • Action : utilisateur tourne les creds → external-data-sources-partial-update avec le nouveau job_inputs → le reload se fait automatiquement quand le statut source bascule à running, ou déclencher manuellement avec external-data-sources-reload.

C. Dérive de schéma — colonne renommée, supprimée ou type changé

  • L'erreur mentionne une colonne spécifique qui ne correspond plus à la source.
  • Action : external-data-schemas-incremental-fields-create pour obtenir les champs actuels, puis external-data-schemas-partial-update avec incremental_field / incremental_field_type / primary_key_columns corrigés. Généralement pas besoin d'effacer les données.

C2. Tables ajoutées / renommées dans la base de données source

  • L'utilisateur mentionne « J'ai ajouté une nouvelle table à Postgres mais elle n'apparaît pas », ou une table source a été renommée.
  • Action : external-data-sources-refresh-schemas pour détecter la nouvelle liste de tables, puis configurer le sync sur les nouveaux schémas.

D. L'état incremental est mauvais (doublons, lignes manquantes, données corrompues)

  • Le statut schéma peut être Completed — ce n'est pas une « défaillance » en soi, c'est de mauvaises données.
  • Action : external-data-schemas-resync pour effacer les données synchro et réimporter de la source. Destructif mais souvent le bon appel pour les problèmes de qualité data.

E. Pipeline CDC cassé sur Postgres

  • L'erreur mentionne replication slot, publication, WAL.
  • Action : external-data-sources-check-cdc-prerequisites-create pour énumérer ce qui est cassé, corriger côté Postgres, puis external-data-schemas-reload. Si la position WAL a été perdue, un resync est parfois inévitable.

F. Le sync est bloqué en Running pendant des heures

  • Vérifier last_synced_at. S'il y a des heures et toujours Running, le job est orphelin.
  • Action : external-data-schemas-cancel pour l'arrêter, puis external-data-schemas-reload.

G. Les données de table sont corrompues mais vous voulez garder la config schéma

  • Action : external-data-schemas-delete-data pour supprimer la table synchro mais préserver l'entrée schéma. Le prochain reload réimporte de zéro sans perdre le sync_type/incremental_field configuré.

H. Limite de facturation

  • L'action n'est pas technique. Expliquer la limite, recommander de mettre à niveau le plan ou de désactiver les schémas moins prioritaires pour que les importants rentrent dans le quota.

I. Schéma avec webhook ne reçoit pas d'événements

  • Symptômes : schéma a sync_type: "webhook", bulk sync initial terminé, mais aucune nouvelle ligne n'arrive malgré l'activité côté source. Le statut peut toujours afficher Completed car le bulk sync (la cadence safety-net) réussit — le problème est le chemin push.
  • Action :
    1. external-data-sources-webhook-info-retrieve({source_id}).
    2. Si exists: false → le webhook n'a jamais été enregistré, ou a été supprimé. Appeler create-webhook-create pour l'enregistrer.
    3. Si exists: true mais external_status.error est défini → typiquement « API key n'a pas la permission de lire les webhooks » ou similaire. Le webhook peut avoir été supprimé sur le dashboard de la source. Le recréer.
    4. Si external_status.status n'est pas "enabled" → la source a désactivé le webhook (généralement après des échecs de livraison répétés). Le réactiver ou réenregistrer.
    5. Si les payloads arrivent mais échouent la vérification de signature → le secret de signature a été tourné. Obtenir le nouveau du dashboard de la source et appeler update-webhook-inputs-create({source_id}, {inputs: {signing_secret: "..."}}).
  • Après tout fix, vérifier les logs webhook de la source (de leur côté) pour confirmer que PostHog répond maintenant 2xx.

Étape 5 — Confirmer avant les actions destructives

Trois actions de récupération effacent les données et ne peuvent être annulées :

  • external-data-schemas-resync — efface les lignes synchro, réimporte de zéro
  • external-data-schemas-delete-data — supprime la table synchro
  • external-data-sources-destroy — supprime la source et tous ses schémas

Toujours présenter le fix que vous proposez et attendre l'approbation explicite avant d'appeler l'un de ceux-ci. « Essayez juste resync » est rarement la bonne valeur par défaut.

Exemple d'interaction

Utilisateur : « Notre sync Stripe est cassé, tu peux vérifier ? »

Agent :
- external-data-sources-list → trouver source Stripe, status = Error
- external-data-sources-retrieve({id}) → latest_error: "authentication failed: 401 Unauthorized"
- Signaler : « La clé API de votre source Stripe ne s'authentifie plus.
   Les 8 tables sous elle échouent toutes avec des 401s. Cela signifie généralement que la clé a été tournée côté Stripe.

   Pour corriger :
   1. Obtenir une nouvelle clé API restreinte du dashboard Stripe.
   2. Je vais mettre à jour la source avec la nouvelle clé.
   3. Les syncs reprendront automatiquement — aucune perte de données.

   Collez la nouvelle clé quand vous êtes prêt. »

Utilisateur : « sk_live_... »

Agent :
- external-data-sources-partial-update({id}, {job_inputs: {stripe_secret_key: "sk_live_..."}})
- external-data-sources-reload({id}) pour déclencher la tentative
- Signaler : « Mis à jour et relancé. Revérifiez dans quelques minutes — latest_error devrait se clearer. »

Notes importantes

  • Le statut source surpasse le statut schéma pour le diagnostic. Si la source est Error, rien sous elle ne fonctionnera ; corriger la source corrige généralement tous ses schémas à la fois.
  • Running n'est pas toujours sain. Vérifier croisé last_synced_at. Un sync bloqué en Running a besoin de cancel puis reload, pas resync.
  • Resync est destructif. Il efface les données synchro. Ne recommandez le que quand les données elles-mêmes sont mauvaises (doublons, lignes manquantes, corrompues) ou quand la récupération nécessite genuinely une ardoise propre (position WAL perdue sur CDC). Ne l'utilisez jamais comme première tentative pour les erreurs transitoires.
  • Delete-data préserve la config. Quand un utilisateur dit « Je veux juste redémarrer cette table de zéro », préférer delete-data + reload à resync + nouvelle entrée schéma — cela garde le sync_type / incremental_field / setup PK configuré.
  • Les limites de facturation ne sont pas des défaillances techniques. N'essayez pas de réessayer ou reconfigurer votre chemin vers la sortie. Routez vers la facturation.
  • Les défaillances webhook peuvent se cacher derrière un statut vert. Un schéma type webhook dont le fallback bulk sync a réussi affiche Completed même quand le canal push est cassé. Quand les utilisateurs disent « mes données ont des heures de retard » sur un schéma webhook, appeler webhook-info-retrieve avant de regarder le statut schéma. Les problèmes webhook ne remontent pas sur external-data-schemas-list.

Skills similaires