「レポート」ロール専用のSQLServerの別のインスタンスが必要です。ログ配布を介してそのサーバーにデータを入力することにしました(ミラーリングが機能せず、可用性グループが非常に高価であるため)。トランザクションログを一定の間隔でバックアップし、レポートインスタンスがアクセスできる場所にコピーしてから、ターゲットインスタンスで復元を実行するだけでよいことがわかりました。
広く受け入れられている解決策が見つからないという問題は、ターゲットカタログへの排他的アクセスなしではログを復元できないことです。データを頻繁に更新したいのですが、更新プロセスでエンドユーザーが実行するレポート/クエリを待機しますアクティブ。接続プーリングのため、開いている接続を追跡することはできません。したがって、私のソリューションの鍵は、データベースカタログが「ビジー」であるかどうかを判断できるようにすることです。 「アクティブな」クエリを一覧表示するこのクエリを思いついた---プロセスが待機する必要があるクエリ。なぜこれが機能しない機能するのか誰かが知っていますか、または誰かがそれが機能することを確認できますか? (たとえば、ブロック情報は、私がすでにチェックしているものを超えて重要ですか?)
SELECT USER_NAME(user_id) AS LoginName
, DB_NAME(database_id) AS DbCat
, blocking_session_id AS BlockedBy
, open_transaction_count AS OpenTrans
, status AS ExecStatus
, cpu_time AS CpuTime
, logical_reads AS LogicalReads
, *
FROM sys.dm_exec_requests
WHERE session_id != @@SPID
AND database_id = DB_ID()
AND status != 'background' --always non-client activity; not something that should block log-shipping.
AND (open_transaction_count > 0 --open transactions always need to be waited on
OR status != 'sleeping' --sleeping=idle, except when there's an open transaction.
);
基本的に、このクエリがゼロ行を返す場合、カタログはアイドル状態であり、復元を実行します。そうでない場合は、その時点で復元は行われません。
クエリはうまく機能します。復元ジョブで正常に使用しています。クエリの最中にプロセスがデータベースから追い出されたことはありません。
自分で試したことはありませんが、ログ配布セカンダリを構成するときに[バックアップを復元するときにデータベース内のユーザーを切断する]チェックボックスをオフにすると、必要な機能が組み込まれていると思います。