Azure Data Factory / Synapse Pipelines の Oracle 連携で、Linked Service を v1 から v2 へ切り替えた途端に「Test connection failed」「ORA‑50000: Connection request timed out」が発生する――この現象は、記述方式の変更や暗号化ネゴシエーションの既定値、IR 側の到達性など複数要因が重なって起きます。本記事では“最小構成で必ず通す”を軸に、設計背景の理解から実運用のチェックリストまで、再現性のある解決手順を体系化して解説します。
問題の本質とスコープ
v1 では接続文字列(EZCONNECT など)を 1 行で渡していました。一方 v2 は server / username / password / authenticationType といった個別プロパティへ分解して指定します。さらに UI(または JSON)上に「Encryption client」「Crypto checksum client」等の追加プロパティが現れ、これらが“自動で既定値へ挿入”されることがあります。この 既定値がサーバ設定と噛み合わない 場合、接続確立の前段でネゴシエーションが止まり、最終的に ADF/Synapse 側では ORA‑50000 相当のタイムアウトとして観測されます。
まず押さえるべき動作仕様(v1 vs v2)
| 観点 | v1(従来) | v2(新方式) | 移行時の要点 |
|---|---|---|---|
| 接続情報の渡し方 | 接続文字列を 1 行で指定 | server 等の個別プロパティ | 接続文字列は存在しない。server に EZCONNECT 形式(例:host:1521/service_name)を入れる |
| 認証方式 | UI 依存(暗黙) | authenticationType を明示 | Basic(B は大文字)。小文字 basic だと失敗する場合あり |
| 暗号化/チェックサム | 明示不可/影響限定 | 「Encryption client」「Crypto checksum client」などを指定可能 | 既定が accepted になる場合あり。サーバ側と不一致なら 削除または rejected へ |
| ネットワーク前提 | IR 到達性(1521/tcp) | 同様 | 自己ホスト IR なら OS から疎通検証を実施(後述のコマンドを使用) |
最小構成でまず“通す” — 推奨 JSON 例
UI から作成しても最終的には Linked Service JSON に落ちます。余計なパラメータを一切入れず、最小構成で接続が成功するかを先に検証してください。
{
"name": "ls-oracle-v2-min",
"type": "LinkedService",
"properties": {
"type": "Oracle",
"typeProperties": {
"server": "db.example.local:1521/ORCLPDB1",
"username": "APPUSER",
"password": {
"type": "SecureString",
"value": "********"
},
"authenticationType": "Basic"
/* ここでは Encryption/CryptoChecksum 等は追加しない */
},
"connectVia": {
"referenceName": "SelfHostedIR-01",
"type": "IntegrationRuntimeReference"
}
}
}
ポイント:この時点では「Encryption client」「Crypto checksum client」「Wallet」などの追加プロパティを入れないでください。成功するなら“接続経路と資格情報は正しい”と切り分けできます。ここから必要な機能だけを 1 つずつ足していくのが確実です。
server の正しい書き方(EZCONNECT と SID/サービス名)
- 基本:
host:port/service_name(推奨、PDB でも一貫)。例:db01:1521/ORCLPDB1 - SID 指定:一部環境では
host:port:SIDの表記が必要。例:db01:1521:ORCL - 複数ホスト/SCAN:ロードバランス/フェイルオーバのためにカンマ区切りを受ける実装もありますが、挙動はドライバ/バージョン依存です。v2 ではまず単一ホストで通した後、必要なら接続先の可用性要件に合わせて検討します。
- サービス名の大文字小文字:Oracle は大文字小文字非依存に扱うケースが多いものの、ネットワーク機器の L7 制御や記述揺れが絡むと誤認識する可能性があります。サーバ側で定義している正規表記に合わせるのが安全です。
なお、OS からの疎通確認には tnsping を用います。環境によっては Easy Connect を tnsping が解釈できないことがあるため、次のいずれかで試行してください。
tnsping //db01:1521/ORCLPDB1
tnsping db01:1521/ORCLPDB1 <!-- 環境によってはこの形式でも可 -->
「AuthenticationType は Basic(B は大文字)」問題
authenticationType に basic と小文字で指定すると、UI では検証エラーにならないのにバックエンドで無言失敗する事例が見られます。必ず Basic と指定してください。
暗号化とチェックサムの既定値が引き起こす交渉失敗
v2 UI/JSON では、Oracle Net Services における暗号化/チェックサム関連のクライアント値を明示できます。Oracle の語彙では概ね次の意味です。
| 指定値 | 意味(クライアント) | サーバ側(例) | 不一致時の挙動 |
|---|---|---|---|
accepted | 使えれば使う。必須ではない | required 以外 | 基本は成立。だが一部中継機器/TLS 絡みで遅延・タイムアウト化する例あり |
rejected | 使わない | required | 確実に失敗(ネゴシエーション不成立) |
requested | 要求はするが、相手が応えなければ非暗号で続行 | accepted など | ほぼ成立 |
required | 必須。使えなければ切断 | accepted/rejected | 不一致なら失敗 |
実運用では「サーバ側で暗号化/チェックサムを要求していない」環境に対して、クライアント側(v2)の既定が accepted で入ると、ネットワーク機器やライブラリの差異によりハンドシェイクのやり直しが発生し、結果的に ADF 側でタイムアウト扱いとなる事例が多く報告されています。まずは両プロパティを未指定(=削除)で検証し、必要に応じて rejected を明示してください。サーバで required が設定されている場合は、クライアントも同じ強度へ合わせる必要があります。
サーバ側(sqlnet.ora)で確認すべき代表設定
SQLNET.ENCRYPTION_SERVER:required | requested | accepted | rejectedSQLNET.CRYPTO_CHECKSUM_SERVER:required | requested | accepted | rejectedSQLNET.INBOUND_CONNECT_TIMEOUT:ハンドシェイク全体の上限。過小だと正当な接続も切断されるSQLNET.ALLOWED_LOGON_VERSION_SERVER:古い認証方式を拒否していないか
ハンドシェイク中のエラーが サーバ側リスナー・アラートログに出ることがあるため、DBA と連携して同時刻のメッセージを必ず確認しましょう。
Integration Runtime(IR)側の基本チェック
自己ホスト IR
- OS から DB ホストへ 1521/tcp が到達するか
- DNS 解決(
db.example.local→ IP)に遅延や誤りがないか - プロキシ/SSL インスペクション装置を経由していないか(握手が壊される)
代表的な疎通コマンド:
# Windows(推奨)
Test-NetConnection -ComputerName db01 -Port 1521
# もしくは
tnsping //db01:1521/ORCLPDB1
# Linux
nc -vz db01 1521
Azure IR / マネージド VNet
- プライベート接続の場合、プライベートエンドポイント/オンプレ接続(VPN/ExpressRoute)のルートと NSG を精査
- アウトバウンドの制限(Firewall、Azure Firewall、NVA)で 1521/tcp が許可されているか
- FQDN ベース制御の場合は 逆引き・CNAME 連鎖で取りこぼしがないか
トラブルシューティングの黄金手順(再現性高)
- 最小 JSON で接続を作り直す(server / username / password / authenticationType=Basic のみ)。テスト接続。
- IR からポート疎通確認(上記コマンド)。DNS 遅延があれば hosts 等で一時回避できるか検証。
- 暗号化/チェックサムを未指定→必要なら rejected。それでも不可ならサーバ側の
requiredの有無を確認。 - サーバログと ADF の詳細ログを突合。Handshake/TLS/Checksum 関連のキーワードを重点確認。
- 接続名の表記(サービス名 vs SID) を入れ替えて再試験。
- ファイアウォール・ロードバランサ(L7) を経由している場合は一時バイパスで切り分け。
- リスナー接続方式(DEDICATED/SHARED)を DBA に確認。変更できるなら DEDICATED で試験。
原因別の対処早見表
| 症状 | よくある原因 | 即効の対処 | 恒久対策 |
|---|---|---|---|
| テスト接続が即時に失敗 | 認証タイプの表記ゆれ(basic) | Basic(大文字 B)へ修正 | テンプレート化しレビュー必須化 |
| 長時間待って ORA‑50000 | 暗号化/チェックサムのネゴシエーション不一致 | 両プロパティを未指定または rejected に | サーバの SQLNET.*_SERVER と合わせて方針を統一 |
| IR からの tnsping が失敗 | DNS/ルート/1521 閉塞 | DNS 修正、NSG/Firewall 開放、ルート見直し | 監視に疎通チェックを組み込み可視化 |
| たまに通る/たまに失敗 | L7 負荷分散での TLS インスペクション揺らぎ | 検証の間はバイパス | 装置側の例外設定 or 経路設計の見直し |
| v1 は通るのに v2 は失敗 | v2 固有の既定値(accepted)が追加 | 追加プロパティを削除して最小構成から | 構成管理(設定ドリフト検知) |
ケーススタディ(実務で遭遇しやすい 3 パターン)
ケース A:オンプレ DB、暗号化なし
サーバ側は SQLNET.ENCRYPTION_SERVER=accepted、CRYPTO_CHECKSUM_SERVER=rejected。v2 の既定(accepted)が交渉を長引かせ、L7 装置がアイドルタイムアウト。対処:クライアント側を未指定(または両方 rejected)にし、IR→DB の経路でインスペクション対象外を設定。
ケース B:セキュリティ方針で暗号化必須
サーバは required。クライアントが未指定/拒否なら失敗。対処:両方 required に明示し、使用アルゴリズム(SQLNET.SSL_VERSION や SQLNET.CIPHER_SUITES 相当)の互換性を DBA とすり合わせ。IR の中間機器で TLS 終端が入らないよう経路保証。
ケース C:PDB への接続でサービス名が不一致
ORCLPDB1 のつもりが orclpdb1 など曖昧な表記で、別のリスナールールにマッチ。結果、稀に別インスタンスへ流れてタイムアウト。対処:サーバ側定義の正規サービス名 を確認し、server を正しく記述。必要に応じて SID 表記も試す。
移行の作法:v1 → v2 の段階的チェックリスト
- v1 の接続文字列から ホスト/ポート/サービス名 を抽出し、v2 の
serverに EZCONNECT で反映 username/passwordを同一に設定。authenticationTypeは Basic- 追加プロパティは最初は入れない。通ったら要件に応じて 1 つずつ追加(ウォレット/TNS 名参照も同様)
- 自己ホスト IR の OS から
tnspingとTest-NetConnectionで疎通確認 - サーバの
sqlnet.oraで暗号化/チェックサム/タイムアウト値を確認 - ADF モニタリングのエラーメッセージと DB リスナーのログを時刻で突合
- 必要に応じて SID とサービス名の両方 で試験し、どちらが正規かを確定
- 本番移行前に 自動再試行/リトライ を含むパイプライン実行で負荷試験(夜間バッチ相当時間に実施)
暗号化・チェックサムの指定例(必要な場合のみ)
要件で暗号化が必須なら、クライアント側にも明示します。必ず DBA の了承のもとで設定してください。
{
"typeProperties": {
"server": "db01:1521/ORCLPDB1",
"username": "APPUSER",
"password": { "type": "SecureString", "value": "********" },
"authenticationType": "Basic",
"encryptionClient": "required",
"cryptoChecksumClient": "required"
}
}
注意:命名(encryptionClient / cryptoChecksumClient)は UI の表記に合わせます。JSON のキーは環境で大文字小文字が固定されている場合があるため、エクスポートと差分比較を推奨します。
ネットワーク設計の勘所
- ステートフル機器のタイムアウト:ハンドシェイクや再交渉でアイドル検知されると切断→ADF 側はタイムアウト扱い。装置側のアイドルタイムアウト と Oracle の INBOUND_CONNECT_TIMEOUT の両方を確認。
- L7/SSL インスペクション:暗号化を中継器で終端すると Oracle 側とネゴできず失敗。該当経路は例外設定に。
- 名前解決:SCAN 名(複数 A レコード)の順序/TTL による偏りで、稀に通らないホストへ当たる場合がある。名前解決結果を監視に取り込むと効果的。
運用に効く監視とログ
- IR 側:稼働ノードの CPU/メモリ、ネットワーク待ち時間、DNS ルックアップ時間
- ADF 実行ログ:接続テスト失敗の詳細メッセージ(Handshake/TLS/Checksum の単語を検索)
- DB 側:リスナーログ、アラートログ、
listener.logの接続拒否/タイムアウト記録
よくある質問(FAQ)
Q. v1 で使っていた tnsnames.ora を v2 にそのまま渡せますか?
A. v2 の基本は EZCONNECT での server 指定です。tnsnames を使う必要があるなら、Oracle Wallet/TNS 管理を含む高度な設定になります。まずは EZCONNECT で通してから追加しましょう。
Q. 「Encryption client」「Crypto checksum client」を空欄のまま公開しても安全ですか?
A. サーバ側で required になっていない限り、未指定=クラシックな v1 の挙動に近い ため、まずは未指定で接続確認するのが安全です。要件で必要な場合のみ明示しましょう。
Q. ORA‑50000 は Oracle の標準コードですか?
A. 表示上そう見える場合がありますが、実体としては ADF/ドライバ層のタイムアウトやネゴシエーション失敗がマッピングされているケースが多いです。根因はネットワーク/暗号化/資格情報にあります。
Q. サーバ側の SQLNET.INBOUND_CONNECT_TIMEOUT はどのくらいが適切ですか?
A. ネットワーク遅延や装置の挙動に依存します。まずは既定から始め、接続試験の実測(ハンドシェイク完了までの実時間)に 2〜3 倍の余裕を持たせるのが実務的です。
実装テンプレート(完成形の一例)
{
"name": "ls-oracle-v2-prod",
"type": "LinkedService",
"properties": {
"type": "Oracle",
"typeProperties": {
"server": "scan.db.prod.local:1521/APPDB_PDB1",
"username": "APP_ETL",
"password": { "type": "SecureString", "value": "********" },
"authenticationType": "Basic"
/* 必要に応じて以下を DBA と合意の上で使用
,"encryptionClient": "required"
,"cryptoChecksumClient": "required"
*/
},
"connectVia": { "referenceName": "SelfHostedIR-Prod", "type": "IntegrationRuntimeReference" },
"annotations": [ "owner:bi-team", "purpose:etl" ]
}
}
移行後の回帰テスト観点
- 並列コピー(並列度)を上げても失敗率が上がらないか(コネクション枯渇/リスナー制限に注意)
- 長時間セッションの安定性(L3/L7 タイムアウトに引っかからないか)
- 例外時のリトライ間隔・回数が設計意図どおりか
- 失敗時の監視アラートとオンコール手順が整備されているか
まとめ
Oracle Linked Service を v1 から v2 に切り替えた際の ORA‑50000(接続タイムアウト)は、(1)最小構成で通す、(2)暗号化/チェックサムの既定を削る、(3)IR 到達性と DNS を確認するの 3 点で大半が解消します。加えて authenticationType の Basic(大文字)、server の正確な EZCONNECT 記述、サーバ側の sqlnet.ora 整合性を押さえれば、v2 でも安定したデータ連携基盤を再現できます。本記事の手順をそのまま上から実施すれば、原因の切り分けと恒久対策までを短時間で到達できるはずです。
付録:コマンドとログのチートシート
| 目的 | コマンド/場所 | 期待結果 |
|---|---|---|
| ポート疎通(Windows) | Test-NetConnection db01 -Port 1521 | TCPTestSucceeded が True |
| 名前解決+応答 | tnsping //db01:1521/ORCLPDB1 | OK(往復時間が極端に長い場合は DNS/経路を精査) |
| ポート疎通(Linux) | nc -vz db01 1521 | suceeded と表示 |
| ADF 側の詳細 | モニタリング → 失敗した接続テスト/アクティビティ → 詳細 | Handshake/TLS/Checksum の語を検索 |
| DB 側ログ | $ORACLE_BASE/diag/tnslsnr/<host>/listener/trace | 拒否/切断/タイムアウトの原因が記録 |
付録:プロパティ早見表(v2)
| キー | 必須 | 例 | 備考 |
|---|---|---|---|
server | 必須 | db01:1521/ORCLPDB1 | SERVICE 名推奨。環境により SID 形式も可 |
username | 必須 | APPUSER | 権限・プロファイルのロックに注意 |
password | 必須 | SecureString | 期限切れ/変更ローテーションとの整合 |
authenticationType | 必須 | Basic | 大文字小文字に注意 |
encryptionClient | 任意 | rejected / accepted / requested / required | 最初は未指定を推奨 |
cryptoChecksumClient | 任意 | 同上 | 最初は未指定を推奨 |
付録:切り戻し戦略
- v2 の Linked Service は別名で作成し、データセット/パイプライン側の参照を段階的に切替(スロット式切替)
- フェイルしたらパイプライン変数(参照先 Linked Service 名)を即時に v1 へ戻せるよう設計
- 併走期間にメトリクス(エラー率・平均接続時間)を収集し、差分が解消したら v1 を廃止
以上を実施すれば、「v1 は通るのに v2 へ切替えると ORA‑50000 でタイムアウトする」という最も厄介な移行トラブルでも、手戻りなく安全に収束させられます。

コメント