2つの別個のSQLサーバーがあります。一方のサーバーにはデータウェアハウス(DWH)があり、もう一方のサーバーには販売情報データベースがあります。
これで、DWHサーバー上に、販売サーバーから情報を収集するETLジョブがあります。ジョブは毎日午前0時以降に実行されます。 DWHはリンクされたサーバーを介して販売データベースから情報を収集します。
現在、ETLジョブはほとんど問題なく実行されています。ただし、クエリのタイムアウトが原因で失敗する場合があります。特定のパターンがあることがわかりました。障害は11日ごとに発生します。したがって、11日目に、ETLジョブは情報を収集できません。
次のエラーが発生します。
リンクサーバー "マイリンクサーバー"のSQLNCLI11は、メッセージ "クエリタイムアウトの期限が切れました。"
注:ジョブは通常、開始後10分で失敗します。
すべてを検索しましたが、この問題の原因を特定できませんでした。また、データ量は毎回、ほぼ同じであることもわかっています。また、11日間すべてを実行するようなスケジュールされたジョブはありません。
リンクサーバーのリモートクエリタイムアウトは0に設定されています。
次のステップは、販売サーバーのウイルス対策プログラムをオフにして、これが問題の原因かどうかを確認することです。
問題を見つけるためにさらに検索できる手掛かりやアイデアはありますか?
これは、11日目にクエリが遅い理由に関する質問の答えにはなりませんが、うまくいけば、10分後に失敗する理由を明らかにするのに役立ちます。
あなたは言及します:
リンクサーバーのリモートタイムアウトは0に設定されています。
直感的には、これは制限がないように思えるかもしれません。
実際に行うことは、sp_configure
リモートクエリタイムアウト のデフォルトは600秒(10分)です。
クエリタイムアウトリンクサーバー上をより高い値、おそらく1200秒(20分)に設定すると、ジョブが完了する可能性があります。そして、うまくいけば、仕事の完了は、なぜこの特定の日にそれがそんなに長くかかるのかについてのいくらかの洞察を提供するでしょう。
このサイトの別の質問で説明されているように、設定は少し混乱していると思います: マルチサブネットフェールオーバークラスターへのリンクサーバー接続
古いSQL Server RAISERROR hack は私にとってはトリックです。
RAISERROR(N'', 0, 1) WITH NOWAIT
リモートコードでデフォルトの600秒(10分)よりも頻繁に呼び出すことができる場合は、それを使用できます。
バッファフラッシュを強制するだけで、これはリモートクエリタイムアウト制限を克服するのに十分です。
詳細。SQL Serverインスタンスにストアドプロシージャがあります。そのインスタンスはリンクされています。
このプロシージャは(特にループで)呼び出します
PRINT CONCAT('Buffer spamming to prevent "Query timeout expired"; at ', CONVERT(VARCHAR(12),GETDATE(),114))
RAISERROR(N'', 0, 1) WITH NOWAIT
次に、別のSQL Serverインスタンスのリンクサーバー機能を通じてこのプロシージャを呼び出します。
EXECUTE MyNamedLinkedServer.MyDb.MyScheme.MyRemoteStoredProcedure
警告!SQL Server 2019ではテストされていません。
基本的にこの状況では、2つの奇妙なオプションがあります。
最初に設定を覚えておくこと リモートクエリタイムアウト
EXECUTE sp_configure 'remote query timeout', <your_value_seconds>;
新しいDBインスタンスごとに。
その他は RAISERRORハック を使用することを忘れないでください。
データ量は変化しており、適切な人々が仕事を変える可能性があります。遅かれ早かれ、あなたは何らかの形でこの問題に遭遇するでしょう。
残念ながらですが、remote query timeout
接続レベルまたはセッションレベル。私見では
現在の状況では、堅牢性のために、SQL Serverにキューの類似機能を実装します。つまり、いくつかの作業を要求し、リンクサーバー機能を介してパラメーターを配置します。その後、定期的に結果を確認します。
もう一方の奇妙な手には、 RAISERROR hack をまったく使用しない手順があります。しかし、彼らは常に何時間も安定して働きます。
そこで何が起こっているのかを理解するために最善を尽くしました。
私は彼らがほとんど持っていないと言うことができますSET NOCOUNT ON
とそのループは長時間ハングアップせず、サブプロシージャの呼び出しは10分以内です。