Восстановление или восстановление может завершиться сбоем или занять много времени, если в базе данных используется уведомление о запросе

Эта статья поможет устранить проблему, из-за которой восстановление или восстановление может завершиться сбоем или занять много времени, если в базе данных используется уведомление о запросе.

Оригинальная версия продукта: SQL Server
Исходный номер базы знаний: 2483090

Симптомы

Вы можете заметить один или несколько из следующих симптомов в базе данных, настроенной для подписок на уведомления о запросах:

  • Симптом 1. Восстановление базы данных из резервной копии может завершиться ошибкой 1205, если во время операции восстановления указан параметр NEW_BROKER . Кроме того, файлы дампа создаются в папке Errorlog SQL Server.

  • Симптом 2. Восстановление базы данных из резервной копии завершается сбоем, и база данных переходит в автономный режим. Кроме того, в журнале ошибок SQL Server регистрируются следующие сообщения:

    <Datetime> spid61 Error: 9768, Серьезность: 16, State: 1.
    <Datetime> spid61. Пользователь базы данных, связанный с безопасной беседой, был удален перед обменом учетными данными с дальней конечной точкой. Избегайте использования DROP USER во время создания бесед.
    <Datetime> spid61 Не удалось проверка для ожидающих уведомлений о запросах в базе данных "5" из-за следующей ошибки при открытии базы данных: "Пользователь базы данных, связанный с безопасной беседой, был удален до обмена учетными данными с дальней конечной точкой. Избегайте использования DROP USER во время создания бесед. Сбой операции очистки подписок уведомлений о запросах. Дополнительные сведения см. в предыдущих ошибках.'.
    <Datetime> spid61 Error: 9001, Серьезность: 16, State: 5.
    <Datetime> spid61 Журнал для базы данных "Тест" недоступен. Проверьте журнал событий на наличие связанных сообщений об ошибках. Устраните все ошибки и перезапустите базу данных.
    <Datetime> spid61 Error: 3314, Серьезность: 21, State: 4.
    <Datetime> spid61 Во время отмены операции в журнале в базе данных Test произошла ошибка с идентификатором записи журнала (1835:7401:137). Как правило, конкретный сбой регистрируется ранее как ошибка в службе журнала событий Windows. Восстановите базу данных или файл из резервной копии или восстановите базу данных.

    Примечание.

    Проблема может возникнуть на этапе восстановления базы данных. Восстановление также выполняется в базе данных, когда база данных подключена, сервер перезапущен и т. д.

  • Симптом 3. Восстановление базы данных из резервной копии может занять много времени, и в журнал SQL Server ошибок регистрируются сообщения, аналогичные следующим:

    Не удалось отправить сообщение в диалоговом окне "{ Dialog ID }". Сбой доставки для уведомления "?<qn:QueryNotification xmlns:qn="https://schemas.microsoft.com/SQL/Notifications/QueryNotification" id="2881" type="change" source="database" info="restart" database_id="7" sid="0x010500000000000515000000FA48F22A6990BA52422C73DFF9030000"><qn:Message>4a4c696b-645c-40fd-bfef-4f2bc7c599b4; eb999973e-3cc9-4c7e-b4b9-47d8cf590c43</qn:Message></qn:QueryNotification> из-за следующей ошибки в компоненте service broker: "Не найден дескриптор беседы "<Обработчик> беседы".

    Примечание.

    Проблема может возникнуть на этапе восстановления базы данных. Восстановление также выполняется в базе данных, когда база данных подключена, сервер перезапущен и т. д.

Причина

Причина симптома 1. При указании параметра NEW_BROKER во время операции восстановления SQL Server пытается усечь все связанные таблицы компонента Service Broker. Усечение требует SCH_M блокировки усеченного объекта. Таким образом, транзакция main удерживает SCH_M блокировку в sysdesend. При восстановлении или восстановлении базы данных по умолчанию SQL Server пытается запустить все уведомления о невыполненных запросах, что требует вставки строк в таблицу sysdesend. Для выполнения этой операции требуется SCH_S блокировка таблицы. Однако эта операция выполняется в другой транзакции, и попытка получения SCH_S блокировки блокируется SCH_M блокировкой первой транзакции. В результате поток, выполняющий восстановление, теперь блокируется в ресурсе, который ему принадлежит, что называется самоблокировкой. Взаимоблокировка обнаруживается монитором взаимоблокировки, и поток завершается, что завершает операцию восстановления.

Дополнительные сведения о блокировках см. в разделе Режимы блокировки. Другие симптомы, описанные в разделе Симптомы, вызваны известными проблемами, которые описаны в статьях по исправлению, упомянутых в разделе "Решение" ниже.

Разрешение

Обходной путь для симптома 1. Вы можете обойти проблему, включив флаг трассировки на уровне сеанса 9109 перед попыткой восстановления. Ниже показан пример скрипта:

dbcc traceon (9109)
go
RESTORE DATABASE [Test] 
FROM DISK = N'C:\TestBackup.bak' WITH FILE = 1, 
MOVE N'test_Data' TO N'C:\test.mdf', 
MOVE N'test_Log' TO N'C:\test_1.ldf', 
NOUNLOAD, 
STATS = 1, 
NEW_BROKER
go
dbcc traceoff (9109)
go

Примечание.

После полного восстановления или восстановления базы данных настоятельно рекомендуется проверка, чтобы обеспечить срабатывание уведомлений о запросах. Самый простой способ добиться этого — изменить состояние базы данных на "Только для чтения" и вернуть ее обратно в режим чтения и записи. Некоторые другие способы проверка для этого включают отключение и повторное подключение базы данных, перезапуск SQL Server и т. д.

Вы также можете избежать проблемы, не указывая параметр NEW_BROKER в операции восстановления, а вместо этого использовать ALTER DATABASE с параметром NEW_BROKER после восстановления базы данных.

Дополнительные сведения см. в разделе DBCC TRACEON — флаги трассировки (Transact-SQL).