Я хочу иметь отдельный экземпляр Sql Server, предназначенный для роли «отчетности». Я решил заполнить этот сервер через доставку журналов (поскольку зеркалирование не работает, а группы доступности безумно дороги). Я выяснил, что мне просто нужно сделать резервную копию журналов транзакций через определенный промежуток времени, скопировать их в место, доступное для отчетного экземпляра, а затем выполнить восстановление в целевом экземпляре.
Проблема, для которой я не нашел общепринятого решения, заключается в том, что невозможно восстановить журнал без монопольного доступа к целевому каталогу. Я хочу часто обновлять данные, но пусть процесс обновления дождется любого активный отчеты / запросы, выполняемые конечными пользователями; вы не можете просто отслеживать открытые соединения из-за объединения в пул. Итак, ключ к моему решению - уметь определять, "занят" ли каталог базы данных. Я придумал этот запрос, в котором перечислены «активные» запросы - те, которых мой процесс должен ждать. Кто-нибудь знает, почему это не стал бы работает, или может кто подтвердит, что будет? (например, имеет ли значение информация о блокировке сверх того, что я уже проверяю?)
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.
);
По сути, если этот запрос возвращает ноль строк, каталог простаивает, и я выполняю восстановление. Если этого не произойдет, то в этот раз восстановления не произойдет.
Запрос отлично работает. Я успешно использую его при восстановлении. Ни один процесс никогда не был удален из базы данных, когда они находятся в середине запроса.
Я сам не пробовал, но думаю, что нужная вам функциональность встроена, если вы снимите флажок «Отключать пользователей в базе данных при восстановлении резервных копий» при настройке вторичной доставки журналов.