Поделиться через


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

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

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

Симптомы

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

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

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

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

    Примечание.

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

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

    Доставка уведомлений по запросу SPID на дату не могла отправлять сообщение в диалоговом окне "{ Идентификатор диалогового окна }.". Сбой доставки для уведомления ??<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-4fef-4f2bc7c599b4; eb99973e-3cc9-4c7e-b4b9-47d8cf590c43</qn:Message></qn:QueryNotification>' из-за следующей ошибки в брокере служб: "Дескриптор беседы "<Обработчик> беседы" не найден.

    Примечание.

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

Причина

Причина симптома 1. При указании параметра NEW_BROKER во время операции восстановления SQL Server пытается усечь все связанные таблицы Service Broker. Усечение требует SCH_M блокировку усеченного объекта. Таким образом, основная транзакция содержит блокировку 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).