Ошибки с SqlQueryNotificationStoredProcedure заполнены Sql Server log
Журналы My Sql Server быстро заполняются сообщениями об ошибках, например:
Активированный proc '[DBO]. [SqlQueryNotificationStoredProcedure-b65a194e-e29f-4ba0-8f5a-79f0875bd609] запуск в очереди 'MyDatabase.dbo.SqlQueryNotificationService-b65a194e-e29f-4ba0-8f5a-79f0875bd609' выводит следующее: 'Невозможно выполнить как основную базу данных, поскольку главного "dbo" не существует, это тип принципала не может быть олицетворен, или у вас нет разрешение.
Ни одна из хранимых процедур, на которые ссылаются эти сообщения, не существует.
Проблема аналогична описанной здесь. В статье упоминается, что проблема должна была быть исправлена в 2008 SP1, но я уже запускаю SP1.
Если я запустил следующую команду...
select * from sys.service_queues
... Я замечаю, что существует множество объектов в очереди, таких как SqlQueryNotificationService-f944d750-8530-4762-adcf-6948e8da991f.
Но если я попытаюсь убить их следующей командой...
drop queue [SqlQueryNotificationService-78f5b757-45f0-4a4d-83f5-91e1d7e46294]
... Появляется сообщение об ошибке: Очередь "SqlQueryNotificationService-78f5b757-45f0-4a4d-83f5-91e1d7e46294" не может быть удалена, поскольку она связана с одной или несколькими службами.
Ответы
Ответ 1
Невозможно выполнить как базу данных потому что основной "дбо" не существует, этот тип принципала не может быть выведено из строя, или вы не имеют разрешение.
Сначала вы должны решить эту проблему:
ALTER AUTHORIZATION ON DATABASE::<dbname> TO [sa];
Теперь, если вы хотите знать, что происходит, я рекомендую некоторые статьи в своем блоге: Таинственное уведомление и Когда идет дождь, он льет. В вашем случае проблема состоит из двух вариантов:
- административная ошибка, которая привела к созданию базы данных с сиротой dbo. Это обычно является результатом присоединения/восстановления базы данных, созданной SID Windows из несвязанной власти (то есть локальной учетной записи на другом компьютере).
- ошибка кодирования при использовании SqlDependency в том, что код не позволяет вызвать Stop(), когда это будет сделано, тем самым не сработает временная инфраструктура SqlDependency.
Обычно активированная процедура временной инфраструктуры SqlDependency удаляет временную очередь/службу/процедуры, но в вашем случае тот факт, что активация не может выполняться из-за того, что потерянное dbo разрушает все.
Как только вы исправите осиротевший dbo (запустив ALTER в начале моего сообщения), активированные процедуры будут работать, и они очистят все временные очереди, службы и процедуры.
Ответ 2
Я остановил журнал ошибок от заполнения, отбросив базовую услугу:
select * from sys.services
-- do this for every service:
drop service [SqlQueryNotificationService-7d871b6d-3868-452c-b75b-d5c5b13d0301]
Тогда я мог бы вернуться и удалить все очереди.
Теперь вопрос заключается в том, как предотвратить это в будущем.
Ответ 3
У меня была аналогичная проблема с SQL 2008 R2. Как только владелец базы данных был исправлен, я продолжал видеть подобные сообщения в журнале, но они в основном заявили, что SqlQueryNotificationService не смог найти себя.
Окончательным решением было бросить и воссоздать брокера, как указано здесь:
http://www.neolisk.com/techblog/MS-SQL-Server-2008-R2-Error-Log-Growing-Rapidly
ALTER DATABASE <DBNAME> SET DISABLE_BROKER
ALTER DATABASE <DBNAME> SET NEW_BROKER
ALTER DATABASE <DBNAME> SET ENABLE_BROKER
Ответ 4
Отбрасывать только SqlQueryNotificationStoredProcedure SPs:
use <your DB name>;
declare @procName varchar(500)
declare cur cursor
for select [name] from sys.objects WHERE type in (N'P', N'PC') and name like 'SqlQueryNotificationStoredProcedure%'
open cur
fetch next from cur into @procName
while @@fetch_status = 0
begin
exec ('drop procedure [' + @procName+']')
fetch next from cur into @procName
end
close cur
deallocate cur