hene

hene.dev

BigQuery から dbt のインクリメンタルモデルが突然消えた原因と解決方法

BigQuery から dbt のインクリメンタルモデルが突然消えた原因と解決方法

はじめに

BigQuery から dbt のインクリメンタルモデルが突然消えて、原因を突き止めるのに時間がかかったので、原因と解決方法をまとめました。

実行環境

  • BigQuery
  • dbt-core: 1.8.2

エラー

BigQuery で設定していた 課金される最大バイト数 の上限に達して、ジョブが失敗した。 通常だと、インクリメンタルモデル は増分更新のため、上限に引っかかることはない。 結果をよく見ると、インクリメンタルモデル を新規作成しようとしていることがわかり、 元の インクリメンタルモデル が消えていることに気づいた。

HH:MM:SS    Database Error in model rpt_sample_model (models/reporting/ga4/rpt_sample_model.sql)
  Query exceeded limit for bytes billed: 3221225416800. 9999999999999 or higher required.
  compiled Code at target/run/dbt_project_name/models/reporting/ga4/rpt_sample_model.sql

原因

モデルを作成してから 168 時間後に消えるように テーブルの有効期限 を設定していた。 インクリメンタルモデル は、増分更新で テーブルの作成日時 は更新されないため、168 時間後に削除された。 毎日エラーが発生するわけではないので、原因を特定するのに時間がかかった。

dbt_project.yml

dbt_project.ymlhours_to_expiration を設定していた。

略

models:
  dbt_project_name:
    +hours_to_expiration: 168

略

解決方法

  1. 消えたテーブルの復元
  2. 今日の定期実行分の処理を実行
  3. テーブルの有効期限常にオフ に設定

消えたテーブルの復元

BigQueryで削除してしまったテーブル・データセットは復元できる! | クラウドテクノロジーブログ | ソフトバンク を参考にテーブルを復元した。

削除直前の時間を下記クエリで取得。

select unix_millis(timestamp_sub(current_timestamp(), interval 3 hour))

取得した時間(1726531456789)を指定して、テーブルを復元。

$ bq cp project_name_prod_reporting.rpt_sample_model@1726531456789 project_name_prod_reporting.rpt_sample_model

今日の定期実行分の処理を実行

復元後、定期実行の処理を再度実行。

$ dbt run -s +rpt_sample_model

テーブルの有効期限常にオフ に設定

既存のテーブルについては、bq コマンドで直接変更

テーブルを管理する | BigQuery | Google Cloud

テーブルのデフォルトの存続期間(秒)です。最小値は 3,600 秒(1 時間)です。 現在時刻にこの整数値を足した値が有効期限になります。 0 を指定すると、テーブルの有効期限が削除され、テーブルは無期限に有効になります。 有効期限のないテーブルは手動で削除する必要があります。

下記を実行して、テーブルの有効期限常にオフ に変更。

$ bq update --expiration 0 project_id:dataset_name.rpt_sample_model

テーブルの有効期限

今後発生しないように dbt のモデルの設定も変更

models/reporting/ga4/rpt_sample_model.sql で、 dbt_project.yml で設定していた hours_to_expiration の値を上書き。

  {{
    config(
      materialized='incremental'
      , incremental_strategy='insert_overwrite'
+     , hours_to_expiration=none
    )
  }}

hours_to_expiration'none', 0, '0' を設定するとエラーが発生しました

hours_to_expiration の設定方法に詰まったときに試した設定方法
hours_to_expiration=none を設定するのが正しい

BigQuery configurations | dbt Developer Hub

Parameter | Type | Required | Default | Change Monitoring Support -- | -- | -- | -- | -- hours_to_expiration | <integer> | no | none | alter

dbt のドキュメントに設定方法がしっかり記載されていた。

$ dbt run -s rpt_sample_model
HH:MM:SS  Running with dbt=1.8.3
HH:MM:SS  Registered adapter: bigquery=1.8.2
HH:MM:SS  Found 999 models, 99 seeds, 9999 data tests, 999 sources, 99 exposures, 999 macros
HH:MM:SS
HH:MM:SS  Concurrency: 4 threads (target='dev')
HH:MM:SS
HH:MM:SS  1 of 1 START sql incremental model project_name_dev_reporting.rpt_sample_model  [RUN]
HH:MM:SS  1 of 1 OK created sql incremental model project_name_dev_reporting.rpt_sample_model  [CREATE TABLE (33.6k rows, 192.2 MiB processed) in 7.96s]
HH:MM:SS
HH:MM:SS  Finished running 1 incremental model in 0 hours 0 minutes and 11.90 seconds (11.90s).
HH:MM:SS
HH:MM:SS  Completed successfully
HH:MM:SS
HH:MM:SS  Done. PASS=1 WARN=0 ERROR=0 SKIP=0 TOTAL=1
hours_to_expiration='none' は、エラーが発生
$ dbt run -s rpt_sample_model
HH:MM:SS  Running with dbt=1.8.3
HH:MM:SS  Registered adapter: bigquery=1.8.2
HH:MM:SS  Found 999 models, 99 seeds, 9999 data tests, 999 sources, 99 exposures, 999 macros
HH:MM:SS
HH:MM:SS  Concurrency: 4 threads (target='dev')
HH:MM:SS
HH:MM:SS  1 of 1 START sql incremental model project_name_dev_reporting.rpt_sample_model  [RUN]
HH:MM:SS  BigQuery adapter: https://console.cloud.google.com/bigquery?project=project-name-dev&j=bq:asia-northeast1:0x0x0x0x-0x0x-0x0x-0x0x-0x0x0x0x0x0x&page=queryresults
HH:MM:SS  1 of 1 ERROR creating sql incremental model project_name_dev_reporting.rpt_sample_model  [ERROR in 1.54s]
HH:MM:SS
HH:MM:SS  Finished running 1 incremental model in 0 hours 0 minutes and 4.50 seconds (4.50s).
HH:MM:SS
HH:MM:SS  Completed with 1 error and 0 warnings:
HH:MM:SS
HH:MM:SS    Database Error in model rpt_sample_model (models/reporting/ga4/rpt_sample_model.sql)
  Unrecognized name: none; failed to set 'expiration_timestamp' in OPTIONS() at [12:72]
  compiled Code at target/run/dbt_project_name/models/reporting/ga4/rpt_sample_model.sql
HH:MM:SS
HH:MM:SS  Done. PASS=0 WARN=0 ERROR=1 SKIP=0 TOTAL=1
hours_to_expiration=0 もエラーが発生

テーブルを管理する | BigQuery | Google Cloud

テーブルのデフォルトの存続期間(秒)です。最小値は 3,600 秒(1 時間)です。現在時刻にこの整数値を足した値が有効期限になります。0 を指定すると、テーブルの有効期限が削除され、テーブルは無期限に有効になります。有効期限のないテーブルは手動で削除する必要があります。

これを読んで、0 を設定すればよいと思ってしまった・・・

hours_to_expiration='0'hours_to_expiration=0 と同じエラーが発生する。

$ dbt run -s rpt_sample_model
HH:MM:SS  Running with dbt=1.8.3
HH:MM:SS  Registered adapter: bigquery=1.8.2
HH:MM:SS  Found 999 models, 99 seeds, 9999 data tests, 999 sources, 99 exposures, 999 macros
HH:MM:SS
HH:MM:SS  Concurrency: 4 threads (target='dev')
HH:MM:SS
HH:MM:SS  1 of 1 START sql incremental model project_name_dev_reporting.rpt_sample_model  [RUN]
HH:MM:SS  Unhandled error while executing target/run/dbt_project_name/models/reporting/ga4/rpt_sample_model.sql
404 GET https://bigquery.googleapis.com/bigquery/v2/projects/project-name-dev/datasets/project_name_dev_reporting/tables/rpt_sample_model?prettyPrint=false: Not found: Table project-name-dev:project_name_dev_reporting.rpt_sample_model
HH:MM:SS  1 of 1 ERROR creating sql incremental model project_name_dev_reporting.rpt_sample_model  [ERROR in 6.13s]
HH:MM:SS
HH:MM:SS  Finished running 1 incremental model in 0 hours 0 minutes and 8.62 seconds (8.62s).
HH:MM:SS
HH:MM:SS  Completed with 1 error and 0 warnings:
HH:MM:SS
HH:MM:SS    404 GET https://bigquery.googleapis.com/bigquery/v2/projects/project-name-dev/datasets/project_name_dev_reporting/tables/rpt_sample_model?prettyPrint=false: Not found: Table project-name-dev:project_name_dev_reporting.rpt_sample_model
HH:MM:SS
HH:MM:SS  Done. PASS=0 WARN=0 ERROR=1 SKIP=0 TOTAL=1

https://bigquery.googleapis.com/bigquery/v2/projects/project-name-dev/datasets/project_name_dev_reporting/tables/rpt_sample_model?prettyPrint=false にアクセスすると、下記エラーが表示される。 このエラーを修正しようといろいろ試して、無駄に時間を使ってしまった。

{
  "error": {
    "code": 401,
    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "errors": [
      {
        "message": "Login Required.",
        "domain": "global",
        "reason": "required",
        "location": "Authorization",
        "locationType": "header"
      }
    ],
    "status": "UNAUTHENTICATED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "CREDENTIALS_MISSING",
        "domain": "googleapis.com",
        "metadata": {
          "method": "google.cloud.bigquery.v2.TableService.GetTable",
          "service": "bigquery.googleapis.com"
        }
      }
    ]
  }
}

まとめ

テーブルの有効期限 を過ぎると、BigQuery からテーブルが消えてしまいます。 インクリメンタルモデル は、増分更新のため テーブルの作成日時 は更新されません。

インクリメンタルモデル には、hours_to_expiration=none を設定して、 テーブルの有効期限常にオフ にすることで、削除されないようにしておきましょう。

参考

関連記事