Azure Data Factory×PostgreSQLでNpgsqlTypes.NpgsqlIntervalエラー発生時の原因と解決策(SHIR 不整合の実践対処)

Azure Data Factory の PostgreSQL コネクタで発生する「Could not load type ‘NpgsqlTypes.NpgsqlInterval’」エラーの原因と解決策(自己ホスト統合ランタイム/SHIR 由来の不整合に注意)

本記事では、Azure Data Factory(ADF)の PostgreSQL コネクタでデータ抽出時に突如として発生しうる下記エラー:

Could not load type 'NpgsqlTypes.NpgsqlInterval' from assembly 'Npgsql, Version=4.0.9.2'

について、技術的背景、迅速な復旧手順、恒久対策までを一気通貫で解説します。とくに、数か月安定稼働していたのに「最近 ADF やパイプラインを触っていないのに突然落ち始めた」という状況に心当たりがある場合、自己ホスト統合ランタイム(Self-hosted Integration Runtime/SHIR)の自動更新を起点とした ドライバの不整合が濃厚です。運用を止めない応急回避(SQL キャスト)から、確実な復旧(SHIR の再起動/ロールバック/修正版への更新)まで、すぐに着手できる具体策をまとめました。


目次

現象の要点

  • ADF の新しい PostgreSQL コネクタで数か月運用後、特定のテーブルのみまたは全テーブルで上記エラーが突発。
  • 最近、ADF 側の変更は一切なし。それでも突然失敗する。
  • エラーの多くは interval / time / timestamp を含む列で顕在化。
  • どこを直すべきか(ADF 側か PostgreSQL 側か)判断しづらい。

結論:多くの環境で、SHIR の自動更新をきっかけに、コネクタが読み込む Npgsql ライブラリと ADF 側の型解決がズレ、NpgsqlTypes.NpgsqlInterval が見つからずに例外化する、という構図が見られます。


最短で復旧したい人向けの TL;DR

  1. SHIR を再起動(サービス再起動または OS 再起動)。これだけで解消する事例あり。
  2. 解消しない場合は、SHIR を修正版に更新(または安定稼働していた 既知の旧版 5.45.x へダウングレード)。更新後は再起動。
  3. 運用を止められない場合の暫定回避:問題の列を ::text へキャストして抽出(コネクタ側の型バインディングを迂回)。
  4. ソースが Azure 上の DB なら、コネクタを「Azure Database for PostgreSQL」コネクタへ切り替えると改善する事例あり。

技術的背景:なぜ「NpgsqlInterval を読み込めない」のか

ADF の Copy Activity / Data Flow は、SHIR 上で各種 DB ドライバ(ここでは Npgsql)を読み込み、型ごとのリーダー・ライターを組み合わせてデータを搬送します。ところが、SHIR の自動更新によって、

  • コネクタ側が期待する Npgsql の型とシグネチャ(NpgsqlTypes.NpgsqlInterval 等)
  • 実際にロードされた Npgsql アセンブリの中身(型の有無や名前空間、実装差)

に矛盾が発生すると、下記のような例外がスローされます。

System.TypeLoadException: Could not load type 'NpgsqlTypes.NpgsqlInterval' 
from assembly 'Npgsql, Version=4.0.9.2, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7'.

つまり、コードはその型を使おうとしているが、実体のアセンブリには登録がない、という状態です。とくに interval を含む行の読み出し・マッピング時に、この乖離が顕在化しやすいのが実運用でのパターンです。


まず試すべき対応(優先度順)

対応策詳細備考
SHIR を再起動自動更新後の一時的な読み込み不整合が解け、再起動だけで正常化するケースがある。最も手軽。まずはこれから。
SHIR を安定版へダウングレード問題が出たビルド(例:5.48.9106.2)から、過去に正常だった 5.45.x に戻して再起動。ダウングレード後は自動更新を一時停止推奨。
修正版 SHIR へアップデート同系統の 5.48 系でも、差し替え済みの修正版インストーラに更新し、再起動。更新後は IR Manager でビルド日付・ファイル更新日時も確認。
該当データ型を文字列キャストinterval / time / timestamp 列に限り、クエリ側で ::text キャストして抽出。恒久対応までの一時しのぎ。コピー先スキーマは string に合わせる。
コネクタ種類を切り替えるソースが Azure 上の PostgreSQL の場合、従来の「PostgreSQL」ではなく「Azure Database for PostgreSQL」コネクタを利用。オンプレミスには適用不可。ファイアウォール/接続方式の違いに留意。

診断チェックリスト(原因の切り分け)

1. 影響範囲の把握

  • 全テーブル/一部テーブルのどちらで失敗するか。
  • 一部なら「どの列型で失敗しているか」を確認。傾向として、interval、time、timestamp を含むテーブルで発生しやすい。

2. PostgreSQL 側で型を一覧する SQL(例)

-- interval / time / timestamp を含む列を洗い出す
SELECT 
  table_schema, table_name, column_name, data_type
FROM information_schema.columns
WHERE data_type IN ('interval', 'time without time zone', 'time with time zone',
                    'timestamp without time zone', 'timestamp with time zone')
ORDER BY table_schema, table_name, ordinal_position;

3. SHIR のビルド確認

  • 対象サーバの「Integration Runtime(IR)構成マネージャ」を開き、バージョンとビルド日時を確認。
  • 最近自動更新されていないか、Windows のイベントログ(アプリケーション)や IR ログを参照。
  • 高可用(HA)構成の場合、全ノードのバージョンが揃っているかも要確認。

4. 失敗ログの観察ポイント

TypeLoadException: Could not load type 'NpgsqlTypes.NpgsqlInterval'
at Microsoft.DataTransfer.PostgreSql.[...]  // 実際はより長いスタックトレース
...

この種の TypeLoadException が出ていれば、ドライバの型解決が主因と考えてよいシグナルになります。

5. コネクタの識別

  • Linked service / Dataset で、どのコネクタ(PostgreSQL / Azure Database for PostgreSQL)を使っているかを確認。
  • Copy Activity と Data Flow の両方で発生しうるため、両方の設定を点検。

解決策の実装詳細

対応 1:SHIR の再起動

最短で試せる打ち手です。IR Manager からの再起動、またはサービス再起動(高可用構成なら順番に)を行います。PowerShell・コマンドライン派は次のような操作も可能です。

:: サービス名の一例(環境により異なる場合あり)
sc stop "DIAHostService"
sc start "DIAHostService"
  • 処理中のパイプラインがある場合は、安全な停止タイミングを見計らうか、別ノードへフェイルオーバーしてから実施。
  • OS のメンテナンス再起動も有効。キャッシュや一時ファイルの残骸を含めクリーンに立ち上げ直します。

対応 2:既知の安定版(例:5.45.x)へいったんロールバック

更新で悪化した疑いが濃厚な場合、直近まで安定していたバージョンへ戻すのが確実です。一般的な流れは以下。

  1. 現行のビルド番号とビルド日時を控える(トラブルシュートの証跡)。
  2. 対象サーバから SHIR をアンインストール。
  3. 運用実績のある旧版インストーラ(例:5.45.x)で再インストール。
  4. IR を ADF に再登録・再接続(キーの貼り付け)。
  5. サービス起動後、簡単な疎通テスト(軽量の SELECT)で正常性を確認。
  6. 暫定的に 自動更新を停止し、以後はステージング環境で先行検証→段階展開(リング)を徹底。

ポイント:IR の自動更新を止めると、セキュリティ修正の取り込みが遅れるため、長期放置は非推奨。後述の「恒久対策(リング運用)」で安全に最新版へ戻す前提の一時措置としてください。

対応 3:修正版 SHIR へアップデート

同じ 5.48 系でも、差し替えられた修正版に更新すると解消するケースがあります。インストール後は次を必ず確認します。

  • IR Manager のバージョン表示とビルド日付。
  • インストール済みファイル(例:Program Files\Microsoft Integration Runtime\ 配下)の更新日時。
  • 更新後、OS 再起動またはサービス再起動も忘れずに。

対応 4:暫定回避(SQL 側で ::text キャスト)

型バインディングで落ちる箇所を避けるため、問題の列だけ文字列表現に変換して抽出します。Copy Activity の Source にクエリを指定可能です。

SELECT 
  id,
  some_interval_column::text AS some_interval_text,
  start_time::text          AS start_time_text,
  updated_at::text          AS updated_at_text
FROM public.sample;

シンク(出力側)のスキーマは string に合わせます。後工程で必要になれば、文字列から interval / time / timestamp へ再解釈する処理を別途用意してください。

PostgreSQL の元型暫定のキャスト備考
interval::text例:'1 day 02:03:04' のような表現に。
time [with/without tz]::textタイムゾーンは文字列で保持。後段でパース。
timestamp [with/without tz]to_char(col, 'YYYY-MM-DD HH24:MI:SS.US TZ')フォーマット固定にする場合。単純に ::text でも可。

対応 5:コネクタの切り替え(Azure Database for PostgreSQL)

ソースが Azure 上のマネージド PostgreSQL(Single Server, Flexible Server 等)の場合、「PostgreSQL」コネクタではなく「Azure Database for PostgreSQL」コネクタを使うと改善する事例があります。両者は内部実装(利用ドライバや接続経路)が異なり、型の扱いや パラメータ既定も差異があります。

項目PostgreSQL コネクタAzure Database for PostgreSQL コネクタ
想定ターゲットオンプレ/IaaS/任意の PostgreSQLAzure マネージド PostgreSQL
接続経路SHIR 経由(基本)SHIR / マネージド仮想ネットワーク等
型互換性interval 周辺で不整合の事例あり同事例が発生しないケースが多い
オンプレ DB 対応可不可

よくある質問(FAQ)

Q. パイプラインもクエリも触っていないのに、なぜ突然落ちた?

A. ADF 本体ではなく、SHIR が自動更新されたのがきっかけの可能性が高いです。ドライバ(Npgsql)の型や署名が想定とズレると、アセンブリ読み込み時に TypeLoadException が発生します。

Q. 一部テーブルのみでエラーになるのは?

A. interval / time / timestamp などの時間系の列を含むテーブルで顕在化しやすいからです。その列の読み取りや型マッピング時に型解決が働き、例外につながります。

Q. PostgreSQL のバージョンが古い/新しいことは関係ある?

A. 直接の主因は SHIR 側のドライバとコネクタの不整合です。とはいえ DB のメジャー差分(例:古い 9.x や新しい 15.x など)で型の既定挙動が違うこともあるため、アプリケーション側のマッピングは安定版に揃えるのが無難です。

Q. Data Flow と Copy Activity のどちらで発生?

A. どちらでも起こり得ます。ドライバの型解決は共通レイヤに近いため、両方の経路で再現することがあります。

Q. TimeSpan や string でマッピングすれば直る?

A. ドライバの読み込み・型解決で失敗している場合は、マッピング前にエラーが起きているため、まずは SHIR/ドライバ側の修正や再起動が必要です。緊急回避としては ::text キャストが有効です。


運用に組み込む恒久対策

1. SHIR の「リング」更新と段階展開

  • 最小構成のステージング IRを持ち、最新版を先に適用してスモークテスト。
  • クリティカルでないパイプラインから順に、本番 IR へ段階展開。
  • 想定外のエラーが検知されたら即座にロールバックできるよう、旧版インストーラ・登録情報を保全。

2. 自動更新の制御

  • 「常時 ON」ではなく、メンテナンスウィンドウで手動適用に切り替える運用を検討。
  • 適用後は必ずOS 再起動/サービス再起動でクリーンにロード。

3. ヘルスチェックとアラート

  • 代表的なテーブル(時間型を含む)を対象に、軽量 SELECT の定期実行を設定。
  • TypeLoadException や Npgsql のロード失敗を検知する ログ監視を導入。

4. スキーマ設計上のガードレール

  • 長期的には、interval の活用方針を見直し、必要に応じて正規化された数値表現(秒数やマイクロ秒)やISO 文字列への変換を検討。
  • ETL の入口では文字列として受け、DWH 側で目的の型に再キャストする「遅延型付け」戦略も有効。

実践ノウハウ(現場でのハマりどころ)

高可用(HA)構成とノード間のバージョン差

複数ノードの IR を HA 構成にしている場合、一部ノードだけ更新されて障害が出たり、ジョブのフェイルオーバーで症状が出たり消えたりすることがあります。全ノードのバージョンを一致させ、順序立てて更新・再起動を行ってください。

導線を確保する「二重 IR」戦略

ダウンタイム最小化のため、同一ネットワーク内に予備 IR(別ホスト)を用意しておくと安心です。予備 IR に事前に旧版を維持しておけば、障害発生時に Linked service の IR バインドを切り替えるだけで、即時に復旧できます。

クエリの安全な暫定変更

やむなく ::text を導入する際は、限定的なビューを作ってアプリケーションからはそのビューを参照する方法がおすすめです。これなら本体テーブルの参照を変えずに回避策を差し替え可能です。

CREATE OR REPLACE VIEW v_sample_for_adf AS
SELECT 
  id,
  some_interval_column::text AS some_interval_text,
  start_time::text          AS start_time_text,
  updated_at::text          AS updated_at_text
FROM public.sample;

復旧後はビュー定義を戻すだけで、パイプライン定義の修正なく運用に復帰できます。


トラブルシュートの深掘り:Npgsql と型マッピング

Npgsql は PostgreSQL の .NET ドライバで、バージョンごとに型マッピングの仕様や実装が変化してきました。interval のように .NET 側で表現が難しい型は、実装の微妙な差が積み重なる領域です。ADF 側のコネクタが 特定の型(NpgsqlTypes.NpgsqlInterval)の存在を前提にしている一方、実際にロードされた Npgsql には当該型が見当たらない──この齟齬が TypeLoadException を引き起こします。

このため、「アプリを触っていないのに壊れた」というときほど、実行基盤(SHIR)側の変更に目を向けるのが効果的です。アセンブリバインディングの差し替えや GAC ではなく、IR が保持する依存バイナリの差で破綻しているケースが支配的です。


ダウンタイム最小の復旧プレイブック

  1. 影響評価(10~15分):失敗対象(Copy / Data Flow、テーブル、列型)を洗い出す。
  2. 短期回避(15分):クエリを ::text で暫定化し、急ぎの処理を通す。
  3. 根本修正(30~60分):SHIR を再起動 → 治らなければ修正版へ更新 or 既知安定版にロールバック。
  4. 安定化(30分):軽量 SELECT のヘルスチェック、リング更新のラインを整える。

Tip:IR の更新やロールバックは、別ノードで同一 IR(HA)に参加させてからスイッチするのが安全です。これにより、作業中の停止を最小化できます。


チェックリスト(まとめ)

  • エラー文字列に NpgsqlTypes.NpgsqlInterval が含まれているか?
  • 該当テーブルに interval / time / timestamp があるか?
  • SHIR は最近自動更新されていないか?バージョン・ビルド日時は?
  • 再起動で直るか? 直らなければ修正版に更新 or 既知の安定版へロールバック。
  • 緊急時は ::text キャストで暫定回避。
  • Azure 上の DB ならコネクタ切り替えも検討。
  • 以後はステージングで先行検証 → 本番リング展開で更新管理。

サンプル:一時回避と戻しの手順(実践用)

一時回避(ビュー方式)

  1. 対象スキーマに _for_adf などの 暫定ビューを作成。
  2. 対象列のみ ::text でキャスト。
  3. ADF 側の Dataset / Source の参照先をビューに切り替え(またはクエリ差し替え)。

復旧後の戻し

  1. SHIR を修正版に更新 or ロールバック完了後、テスト用パイプラインで正常読取を確認。
  2. ビューを本来の生テーブルに戻す(または ::text を外したクエリに戻す)。

トラブル再発を防ぐためのテンプレ(運用品質の底上げ)

施策内容期待効果
リング更新Dev → Stg → Prod (A/B) の順で IR を更新。段階的に展開。本番への影響最小化。早期検知。
ヘルスチェック時間系列を含む代表テーブルで定時 SELECT を実行し、異常を監視。型不整合の早期発見。
予備 IR同一ネットワークに予備 IR を常設。旧版を保持し即時切替を可能に。ダウンタイム短縮。
スキーマ設計ガイドinterval 多用時の表現方針を定め、必要に応じて数値や ISO 文字列で保持。ドライバ差異の影響を軽減。

まとめ

ADF の PostgreSQL コネクタで発生する Could not load type 'NpgsqlTypes.NpgsqlInterval' は、現場報告を総合すると、SHIR の自動更新を契機とする Npgsql まわりの不整合が本質です。まずは SHIR 再起動 → ダメなら 修正版へ更新 or 過去安定版へロールバック。運用を止められないときは ::text キャストで迂回し、Azure 上の DB であれば Azure Database for PostgreSQL コネクタへの切り替えも有効です。

恒久的には、リング更新・予備 IR・ヘルスチェックの三点セットで「突然壊れた」を仕組みで防ぎましょう。この記事の手順をそのままプレイブックとして取り込み、次回以降は迷わず安全に復旧できる状態を目指してください。


付録:運用メモ(手短版)

  • 症状:NpgsqlTypes.NpgsqlInterval が見つからない(TypeLoadException)。
  • 第一手:SHIR 再起動。
  • 第二手:SHIR の修正版へ更新 or 旧版(5.45.x)へ戻す(自動更新は一時停止)。
  • 緊急回避:::text キャストで抽出を継続。
  • 代替策:コネクタを「Azure Database for PostgreSQL」に切替(Azure 上の DB 限定)。
  • 再発防止:リング更新、予備 IR、時間型を含む疎通テストの定期化。

このガイドが、現場の「今すぐ復旧したい」「二度と同じ事故に遭いたくない」の両方に役立つことを願っています。


この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次