MetricSign
NL|ENStart free →
error-reference9 min·

dbt-productiefouten: een referentie-index van mislukte uitvoeringen

Je dbt-run is om 04:12 voltooid. Drie modellen zijn mislukt. Het foutenlogboek meldt 'huidige transactie is afgebroken'. Power BI heeft de gegevens van gisteren al bijgewerkt.

Read this article in English →

dbt-productiefouten: een referentie-index van mislukte uitvoeringen

Drie modellen vielen om 04:12 uit. Niemand merkte het op tot de bestuursvergadering.

Het is 04:12. Je nachtelijke dbt-run in productie is zojuist mislukt. Drie modellen in de map marts gaven databasefouten en twee andere werden overgeslagen omdat ze afhankelijk zijn van de mislukte modellen. Niemand van het datateam is wakker.

Om 06:00 wordt de geplande Power BI verversing toch uitgevoerd. Deze haalt gegevens op uit de tabellen die dbt had moeten bijwerken. Twee van die tabellen bevatten nog steeds gegevens van gisteren. Eén tabel bevat gegevens van drie dagen geleden, omdat het model gisteravond en de nacht ervoor is mislukt.

Om 09:14 opent de VP Sales het pipeline-dashboard. De cijfers voor het tweede kwartaal zijn vannacht met 30% gedaald. De data engineer begint om 09:20 met debuggen, vindt de dbt-fout in de runlogs en besteedt 45 minuten aan het traceren van welke downstream datasets zijn getroffen.

Dit bericht is de referentie die je om 09:20 opent. Het behandelt de foutcategorieën die je kunt tegenkomen tijdens het uitvoeren van dbt in een productieomgeving, hoe je de schade kunt beperken met --fail-fast, waar dbt Core en dbt Cloud verschillen in foutafhandeling, en wat je moet doen als dbt Cloud zelf het probleem is.

De meeste productiefouten van dbt vallen in drie categorieën.

Weten in welke categorie je je bevindt, bepaalt je debugpad.

Compilatiefouten

dbt compileert je SQL-modellen tot uitvoerbare query's voordat ze naar de database worden verzonden. Compilatiefouten betekenen dat dbt de query nooit heeft uitgevoerd. Veelvoorkomende oorzaken:

Een Jinja-macro verwijst naar een variabele die niet bestaat in de productieomgeving. Je dev-profiel stelt target_schema in op dev_analytics; het prod-profiel gebruikt analytics. Als een macro de naam van het dev-schema hardcodeert, werkt deze lokaal, maar mislukt deze in de CI.

Een ref() verwijst naar een model dat is hernoemd of verwijderd. In een project met meer dan 200 modellen zorgt het hernoemen van stg_orders naar stg_raw_orders ervoor dat elk model dat naar de oude naam verwijst, niet meer werkt. dbt detecteert dit tijdens het compileren.

YAML-configuratiefouten: een verkeerde inspringing in schema.yml of een config()-blok met een ongeldige materialisatie. Deze fouten worden onderschept voordat er SQL-query's worden uitgevoerd.

Compilatiefouten zijn het gemakkelijkst op te lossen, omdat dbt je het exacte bestand, regelnummer en foutbericht geeft. De uitdaging in een productieomgeving is dat ze de hele uitvoering blokkeren, of alles wat daarop volgt als je --fail-fast gebruikt.

Databasefouten

De query is gecompileerd. dbt heeft deze naar het datawarehouse gestuurd. Het datawarehouse heeft deze afgewezen. Dit is waar sql state: 25p02 vandaan komt.

25p02 is de foutcode van PostgreSQL voor "de huidige transactie is afgebroken, opdrachten worden genegeerd tot het einde van het transactieblok." In de context van dbt gebeurt dit wanneer een eerdere instructie in dezelfde transactie al is mislukt (toegangsfout, ontbrekend schema, syntaxfout) en PostgreSQL elke volgende instructie weigert totdat de transactie is teruggedraaid.

De oplossing: zoek de oorspronkelijke fout die de transactie heeft afgebroken. Het bericht 25p02 is een symptoom. Controleer de log bestanden voor de eerste fout tijdens de uitvoering van dat model. Veelvoorkomende oorzaken zijn permissie fouten in productieschema's, ontbrekende tabellen die wel in de ontwikkelomgeving maar niet in de productieomgeving bestaan, en inconsistenties in kolomtypen na een wijziging van het bronschema.

Andere veelvoorkomende databasefouten:

  • Time-out: je model werkt in de ontwikkelomgeving met 100.000 rijen. De productieomgeving heeft 50 miljoen rijen. Snowflake geeft een TIMEOUT-foutmelding; Databricks Spark-taken kunnen een OutOfMemoryError (OOM) veroorzaken.
  • Toegang geweigerd: Het serviceaccount dat je productie-dbt-taak uitvoert, heeft niet dezelfde machtigingen als je persoonlijke ontwikkelaccount. Een GRANT SELECT op een nieuwe brontabel wordt gemakkelijk vergeten.
  • Gelijktijdigheidslimieten: Het parallel uitvoeren van 30 modellen kan de gelijktijdige querylimiet van je datawarehouse overschrijden, met name op kleinere Snowflake-datawarehouses of gedeelde Databricks-clusters.

Afhankelijkheids- en actualiteitsfouten:

dbt source freshness-controles valideren of brontabellen recente gegevens bevatten voordat modellen worden uitgevoerd. Een 'freshness error' betekent dat de brongegevens ouder zijn dan de geconfigureerde drempelwaarde:

```yaml sources:

- name: raw_sales loaded_at_field: _loaded_at freshness:

warn_after: {count: 12, period: hour}

error_after: {count: 24, period: hour} ```

Als raw_sales 26 uur geleden voor het laatst is geladen, geeft dbt een foutmelding voordat een model dat ervan afhankelijk is, wordt uitgevoerd. Dit is een van de nuttigste functies van dbt in productieomgevingen: het voorkomt dat je data marts bouwt op basis van verouderde gegevens. Maar het betekent ook dat je dbt-run kan mislukken vanwege een probleem in de bron dat niets met dbt zelf te maken heeft.

Het fail-fast-principe bestaat omdat een volledige run na de eerste fout rekenkracht verspilt.

De standaardinstelling van dbt run is om alle resterende modellen uit te voeren nadat er één is mislukt. In de ontwikkelomgeving is dit logisch. Je wilt alle fouten in één keer zien. In een productieomgeving verspilt dit echter rekenkracht en kan het leiden tot beschadigde tussentabellen.

dbt run --fail-fast stopt de uitvoering bij de eerste modelfout. Als stg_orders mislukt, probeert dbt int_orders, fct_orders of andere modellen die erna komen niet meer uit te voeren. Modellen die niet afhankelijk zijn van het mislukte model worden wel gewoon uitgevoerd.

Wanneer fail-fast te gebruiken:

  • Nachtelijke productieruns waarbij consistente verouderde data beter is dan een mix van actuele en verouderde tabellen. Als één model in een afhankelijkheidsketen mislukt, kunnen modellen die erna zijn uitgevoerd onvolledige upstream-data hebben verwerkt.
  • CI/CD-runs in de stagingomgeving. Met fail-fast in CI kun je de eerste fout opvangen zonder te wachten op de volledige build.

Wanneer fail-fast niet te gebruiken:

  • Onafhankelijke modelgroepen. Als je project verkoop-, marketing- en financiële modellen heeft zonder gedeelde afhankelijkheden, stopt fail-fast alle drie wanneer alleen het verkoopmodel een fout bevat. Voer elk domein afzonderlijk uit: dbt run --fail-fast --select tag:sales.

Configuratie in dbt_project.yml (dbt 1.6+):

```yaml flags:

fail_fast: true ```

Of per aanroep:

``bash dbt run --fail-fast --select tag:critical dbt run --fail-fast --exclude tag:experimental ``

Deze vlag is van toepassing op dbt run, dbt seed en dbt snapshot. Het is niet van toepassing op dbt test, dat altijd alle geselecteerde tests uitvoert, ongeacht individuele fouten.

Core en Cloud geven fouten op verschillende manieren weer, en dat heeft invloed op hoe snel je reageert.

dbt Core en dbt Cloud gebruiken dezelfde compilatie-engine. De fouten zelf zijn identiek. Het verschil zit in hoe je ze ziet, hoe snel je ze ziet en wat er automatisch gebeurt als ze optreden.

Logboekregistratie en foutmeldingen

dbt Core logt naar target/run_results.json en logs/dbt.log. Je kunt ze lezen door het bestand te openen, door de uitvoer door te sturen met jq of door de log aggregator te raadplegen die je team gebruikt (Datadog, CloudWatch, Grafana). Als je orchestrator (Airflow, Dagster, Prefect) stdout vastlegt, worden fouten daar ook weergegeven. Er is geen ingebouwde gebruikersinterface.

dbt Cloud toont fouten in een gebruikersinterface met een uitvoeringsgeschiedenis, inclusief syntax-gemarkeerde SQL, de gecompileerde query, de ruwe databasefout en de timing per model. Voor teams die meer dan 50 modellen draaien, is het sneller om door de gebruikersinterface te klikken dan een logbestand van 2000 regels te lezen.

Waarschuwingen en meldingen

dbt Core heeft geen ingebouwde waarschuwingsfunctie. Als je taak mislukt, stuurt je orchestrator een e-mail of Slack-bericht, maar alleen als je dit hebt geconfigureerd. Airflow gebruikt on_failure_callback; Dagster heeft @op(on_failure=...). Als je dbt Core via cron uitvoert, hebt je waarschijnlijk geen waarschuwingen, tenzij je deze zelf hebt ingesteld.

dbt Cloud stuurt standaard e-mailmeldingen bij een mislukte taak. Het ondersteunt webhooks die een Slack-bericht, een PagerDuty-incident of een aangepaste functie kunnen activeren. De payload van de webhook bevat de taak-ID, de uitvoerings-ID en de status.

Gedrag bij herhaling

dbt Core probeert mislukte modellen niet opnieuw. Als stg_orders mislukt, blijft dit zo tot de volgende geplande uitvoering. Je kunt logica voor herhaling toevoegen in je orchestrator (de parameter retries van Airflow), maar dbt zelf wordt slechts één keer uitgevoerd en stopt dan.

De taakdefinities van dbt Cloud bevatten een configureerbare herhaalpoging met vertraging. Dit helpt bij tijdelijke fouten: korte onbeschikbaarheid van het datawarehouse, tijdelijke netwerkproblemen, machtigingsproblemen tijdens een implementatieperiode. Bij aanhoudende fouten (schema-inconsistenties, syntaxfouten, ontbrekende tabellen) is een herhaalpoging echter tijdverspilling.

Soms ligt het probleem bij dbt Cloud zelf, en niet bij je project.

Als je dbt Cloud-taak mislukt en de fout niet in je SQL of configuratie zit, controleer dan of er een probleem is met het platform zelf.

status.getdbt.com toont de huidige servicestatus voor de API, IDE, scheduler en metadata-API afzonderlijk. Een storing in de scheduler betekent dat je taken niet worden uitgevoerd, zelfs als de rest van het platform operationeel is.

Voor programmatische controles biedt de dbt Cloud Administrative API een endpoint /api/v2/accounts/{account_id}/runs/. Als je aanroepen consistent een HTTP 503-fout of een time-out retourneren, is er een probleem met het platform.

Externe monitoring instellen voor dbt Cloud-storingen:

  1. Abonneer je op status.getdbt.com via e-mail of RSS. De pagina draait op Statuspage.io en verzendt automatisch incident meldingen.
  1. Voeg een health check toe aan je eigen monitoring. Roep de dbt Cloud API elke 5 minuten aan. Geef een waarschuwing als er drie opeenvolgende controles een andere waarde dan 200 worden geretourneerd.
  1. Configureer een fallback voor de orchestrator. Als je Airflow naast dbt Cloud gebruikt, configureer deze dan om een dbt Core-run te starten wanneer dbt Cloud-taken hun verwachte voltooiingstijdstip overschrijden.

Controleer de statuspagina-geschiedenis om inzicht te krijgen in de frequentie en duur van eerdere incidenten in je regio. Voor teams waar een vertraging van 30 minuten acceptabel is, kan de ingebouwde herhaalfunctie van dbt Cloud de meeste storingen afhandelen. Voor teams met strikte SLA-vensters (je Power BI verversing vindt plaats om 06:00 uur en het dashboard wordt om 07:00 uur geopend) is een externe monitoringlaag de moeite waard.

De debug workflow die in productie werkt.

Wanneer een dbt-run in een productieomgeving mislukt, volgt het debugpad een consistente volgorde.

1. Lees het foutbericht, beginnend bij de eerste fout. Bij een run met meerdere modellen is de eerste fout de hoofdoorzaak. Alles wat daarna komt, kan een kettingreactie zijn, inclusief 25p02-fouten. Sorteer in dbt Cloud de resultaten op uitvoeringsvolgorde. Controleer in dbt Core het bestand target/run_results.json en zoek naar de eerste vermelding met status: "error".

2. Vergelijk de gecompileerde SQL met de broncode. dbt genereert gecompileerde SQL in target/compiled/. Open het gecompileerde bestand van het model dat mislukt en voer de query rechtstreeks uit in je datawarehouse-client (Snowflake-werkblad, Databricks SQL-editor, psql). Als de query daar ook mislukt, ligt het probleem in de SQL of de databasestatus. Als het lukt, ligt het probleem in de manier waarop dbt het uitvoert: transactieverwerking, machtigingen of verbindingsinstellingen.

3. Controleer omgevingsverschillen. De meest voorkomende reden waarom een model in de ontwikkelomgeving werkt en in de productieomgeving niet:

  • Verschillende schema's of databases (target-configuratie in profiles.yml)
  • Verschillende machtigingen (je persoonlijke account versus het serviceaccount)
  • Verschillende datavolumes (een query die 10 seconden duurt op 1 miljoen rijen, loopt vast op 100 miljoen rijen)
  • Verschillende datawarehouse-groottes (Snowflake XS versus L-warehouse, Databricks cluster auto-scaling configuratie)

4. Controleer de actualiteit van de brongegevens. Als het model is uitgevoerd, maar de uitvoer er onjuist uitziet, zijn de invoergegevens mogelijk verouderd. Voer dbt source freshness uit op de bronnen waarvan je model afhankelijk is.

5. Controleer de querygeschiedenis van het datawarehouse. De QUERY_HISTORY-weergave van Snowflake en de Spark UI van Databricks tonen de uitvoeringstijd, het aantal gescande rijen en de gegevens die naar de schijf zijn weggeschreven. Een query die vorige week 10 miljoen rijen verwerkte en vandaag 500 miljoen rijen (omdat iemand stroomopwaarts een WHERE-clausule heeft verwijderd) zal er normaal uitzien in de logboeken van dbt, maar duidelijk zichtbaar zijn in de queryprofiler van het datawarehouse.

Het monitoren van dbt-processen op je gehele stack.

De ingebouwde monitoring van dbt laat je weten dat een model is mislukt. Het vertelt je echter niet welke Power BI datasets van dat model afhankelijk zijn, of de downstream-verversing al is uitgevoerd, of wie moet weten dat het verkoopdashboard verouderde gegevens weergeeft.

MetricSign maakt verbinding met dbt Cloud (via een webhook) en dbt Core (via polling van run_results.json) naast je datawarehouse en BI-laag. Wanneer een dbt-model in productie mislukt, leest MetricSign de foutmelding, identificeert welke downstream-datasets zijn getroffen via de lineage-grafiek en stuurt een waarschuwing naar het juiste kanaal voordat de volgende Power BI verversing wordt uitgevoerd.

Een typisch scenario: je nachtelijke dbt run mislukt om 04:12 uur bij fct_revenue. MetricSign detecteert de fout, controleert de lineage en ontdekt dat fct_revenue de Power BI dataset "Omzet per regio" voedt. Die dataset wordt om 06:00 uur vernieuwd. MetricSign stuurt om 04:15 een Telegram-waarschuwing naar de dienstdoende data engineer, 105 minuten voordat de refresh verouderde data in het dashboard zou laden.

MetricSign vervangt de foutafhandeling van dbt niet. Het breidt deze uit door dbt-fouten te koppelen aan hun impact in de BI-laag. Als je dbt-modellen alleen een datawarehouse voeden en je gebruikers deze rechtstreeks bevragen, is de native waarschuwingsfunctie van dbt Cloud mogelijk voldoende. MetricSign biedt toegevoegde waarde wanneer een BI-tool zoals Power BI op een eigen schema vernieuwt, onafhankelijk van dbt, omdat geen van beide tools de status van de ander kent.

De tekortkoming in de monitoring van dbt in productieomgevingen zit hem niet in de detectie van fouten. dbt doet dat al. De tekortkoming zit hem in de periode tussen detectie en impact: de tijd waarin een fout in een logbestand blijft staan terwijl de BI-refresh volgens schema wordt uitgevoerd, zonder dat de tool weet dat de brondata onjuist is.

Veelgestelde vragen

Waarom werkt mijn dbt-taak niet in de productieomgeving, maar wel in de ontwikkelomgeving?+
De meest voorkomende oorzaken zijn omgevingsverschillen: verschillende schema's of databases in profiles.yml, verschillende machtigingen tussen je persoonlijke account en het serviceaccount voor productie, en verschillende datavolumes die ervoor zorgen dat query's in productie een time-out krijgen. Voer de gecompileerde SQL-code uit target/compiled/ rechtstreeks uit in je productieomgeving om het probleem te isoleren.
Hoe gebruik ik --fail-fast om de explosieradius te beperken?+
Voeg --fail-fast toe aan je dbt run-opdracht of stel fail_fast: true in in het flags-gedeelte van dbt_project.yml (dbt 1.6+). Dit stopt de uitvoering bij de eerste modelfout en slaat alle volgende modellen over. Dit geldt voor dbt run, seed en snapshot, maar niet voor dbt test.
Wat betekent sql state 25p02 in dbt?+
PostgreSQL-fout 25p02 betekent 'de huidige transactie is afgebroken, opdrachten worden genegeerd tot het einde van het transactieblok'. Een eerdere instructie in dezelfde transactie is al mislukt en PostgreSQL weigert alles wat daarop volgt. Zoek de eerste fout in het run log van het model. Dat is de hoofdoorzaak. De 25p02 is een gevolg van een kettingreactie.
Hoe kan ik controleren of dbt Cloud niet beschikbaar is?+
Bezoek status.getdbt.com voor de realtime servicestatus. De pagina toont afzonderlijke componenten: API, IDE, scheduler en metadata-API. Abonneer je via e-mail of RSS voor automatische meldingen. Voor programmatische controles kunt je de dbt Cloud API monitoren en een melding instellen bij herhaalde 503-reacties.
Wat zijn de verschillen tussen dbt Core en dbt Cloud wat betreft foutafhandeling?+
De fouten zelf zijn identiek. De verschillen zitten in de manier waarop ze worden weergegeven en hoe erop wordt gereageerd: Core logt naar bestanden en vertrouwt op je orchestrator voor waarschuwingen. Cloud biedt een gebruikersinterface met een uitvoeringsgeschiedenis, verstuurt standaard e-mailmeldingen, ondersteunt webhooks voor integratie met Slack of PagerDuty en biedt configureerbare herhaalpogingen bij een fout.

Gerelateerde integraties

Gerelateerde artikelen