SQL Server прекращает загрузку сборки - PullRequest
42 голосов
/ 12 августа 2011

Мы разработали сборку для SQL Server 2008 R2.

Сборка работает уже неделю. Управляемый хранимый процесс внутри сборки работал в течение всей недели, а затем перестает работать. Мы видели эту проблему пару раз. Чтобы заставить его работать снова, перезапустите SQL Server.

Msg 10314, Level 16, State 11, Line 4
An error occurred in the Microsoft .NET Framework while trying to load assembly id 65536. The server may be running out of resources, or the assembly may not be trusted with PERMISSION_SET = EXTERNAL_ACCESS or UNSAFE. Run the query again, or check documentation to see how to solve the assembly trust issues. For more information about this error: 
  System.IO.FileLoadException: Could not load file or assembly 'myAssembly, Version=2.0.0.490, Culture=neutral, PublicKeyToken=5963130873dd3a75' or one of its dependencies. Exception from HRESULT: 0x80FC0E21 System.IO.FileLoadException:
  at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
  at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
  at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
  at System.Reflection.Assembly.Load(String assemblyString)

Я нашел разные статьи в Интернете.

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

В этом блоге сказано, что я мог бы столкнуться с этим, если бы я установил .NET 3.5 на SQL Server 2005, но у меня был SQL Server 2008 R2, и я ничего не установил, когда возникла эта проблема.

Суть в том, что он может продолжаться некоторое время. Он просто перестает работать в случайном порядке. Затем, если мы перезапустим SQL Server, он снова начнет работать. Я думал о том, что моему серверу действительно не хватает памяти, но теперь я просто вижу проблему снова. SQL Server использует только 300 МБ ОЗУ, а мой сервер имеет 16 ГБ ОЗУ. Это кажется невозможным, потому что мне не хватает памяти.

Теперь я хочу собрать больше информации по этой проблеме. Любой журнал, который я могу включить и посмотреть? Любые предложения, которые помогут решить эту проблему, приветствуются.

Я выполнил несколько SQL-запросов.

SELECT * from sys.dm_clr_properties
=============================================
directory   C:\Windows\Microsoft.NET\Framework64\v2.0.50727\
version v2.0.50727
state   CLR is initialized

.

SELECT * from sys.dm_clr_appdomains
======================================================
0x0000000087160240  3   mydatabase.dbo[runtime].2   2011-08-12 08:44:08.940 10  1   E_APPDOMAIN_SHARED  1   1

.

SELECT * from sys.dm_clr_tasks
======================================================
0x000000008185A080  0x00000000818562C8  0x0000000000000000  E_TASK_ATTACHED_TO_CLR  E_ABORT_NONE    E_TYPE_ADUNLOAD 0   0
0x00000000818CE080  0x00000000818CA2C8  0x0000000000000000  E_TASK_ATTACHED_TO_CLR  E_ABORT_NONE    E_TYPE_FINALIZER    0   0
0x0000000081AD4C30  0x000000000400D048  0x0000000000000000  E_TASK_ATTACHED_TO_CLR  E_ABORT_NONE    E_TYPE_USER 0   0

.

SELECT * from sys.dm_clr_loaded_assemblies
<returns nothing>

* ОБНОВЛЕНИЕ *

На моем SQL Server я создал четыре базы данных. К каждому из них прикреплена одинаковая сборка. Теперь SQL Server отказался загружать сборку и выдал мне вышеуказанную ошибку.

SELECT * from sys.dm_clr_appdomains показывает, что в этот момент был загружен только один домен приложений, а SELECT * from sys.dm_clr_loaded_assemblies показывает, что сборок вообще не загружено.

Затем я запустил один и тот же хранимый процесс в трех других базах данных. Он работал и успешно загрузил сборки и успешно запустил сохраненный процесс. После выполнения сохраненной процедуры. SELECT * from sys.dm_clr_appdomains теперь показывает, что загружено только четыре домена приложений, а SELECT * from sys.dm_clr_loaded_assemblies показывает, что сейчас загружены три сборки.

Это имеет смысл. Теперь, я надеюсь, что если я снова запущу сохраненный процесс в исходной базе данных, сборка будет загружена как есть. Угадай, что. Нет, это не так. Это все еще дает мне ту же ошибку. Похоже, эта база данных полностью застряла. Единственный способ исправить это - перезагрузить SQL Server. Я надеюсь, что где-то в системной таблице есть флаг / блокировка, удерживающая это. Я не могу найти это. Любая идея приветствуется.

Теперь мой SQL Server находится в состоянии, требующем перезагрузки, чтобы он снова заработал.

* ОБНОВЛЕНИЕ (31.08.2011) *

Похоже, это связано с владельцем базы данных базы данных. Это довольно сложно. У нас есть два сайта и два леса AD. Компьютер SQL Server присоединен к лесу A, но владелец базы данных находится в лесу B. Соединение между лесом A и лесом B не столь стабильно, поскольку они находятся в двух разных сайтах, физически соединенных с помощью WAN.

После того, как я изменил владельца базы данных на учетную запись SQL (учетная запись не из Windows), мой сохраненный процесс работает в течение нескольких недель без перерыва.

Я приму ответ, если кто-нибудь сможет его объяснить.

Ответы [ 10 ]

47 голосов
/ 07 сентября 2011

Сборки с EXTERNAL_ACCESS по некоторой извилистой траектории попадают под путь EXECUTE AS. Проблема возникает, когда «dbo» не может быть сопоставлен с действительным именем входа. логин dbo - это логин с SID значением owner_sid в sys.databases. Если в CREATE DATABASE не было использовано предложение AUTHORIZATION, owner_sid является идентификатором входа в систему субъекта, выполняющего инструкцию CREATE DATABASE. В большинстве случаев это SID Windows пользователя, который вошел в систему и выдал CREATE DATABASE. Обладая этими знаниями, можно легко представить себе проблемы, которые могут возникнуть:

  • копировать базу данных: CREATE DATABASE был выдан на машине A пользователем, локальным для A (т. Е. MachineA\user или DomainA\user), затем база данных была скопирована на машину B (посредством резервного копирования / восстановления или посредством копирования файла). Owner_sid сохраняется как при копировании файла, так и при резервном копировании / восстановлении, это на машине B, owner_sid является недействительным. Все, что требует EXECUTE As, не удается, включая загрузку сборок из базы данных.
  • могильный счет. CREATE DATABASE выдан пользователем, покинувшим компанию. Учетная запись AD удаляется, и все неожиданно происходит сбой EXECUTE AS, включая загрузку сборок.
  • отключен ноутбук. CREATE DATABASE были проблемы, когда ноутбук был подключен в рабочей сети. Дома вы можете войти в систему с использованием кэшированных учетных данных Windows, но EXECUTE AS хочет подключиться к недоступной AD и завершается неудачно. Загрузка сборок также не удалась. Проблемы загадочным образом решаются на следующий день на работе, когда вы снова в пределах досягаемости AD.
  • пятнистое подключение AD. EXECUTE AS не использует системные кэшированные учетные данные и подключается к AD каждый раз. Если при подключении AD возникают проблемы (тайм-аут, ошибки), эти проблемы проявляются как аналогичные тайм-ауты и ошибки в EXECUTE AS, включая загрузку сборок

Все эти проблемы можно диагностировать, просто запустив: EXECUTE AS USER = 'dbo'; в контексте проблемы db. Если происходит сбой с ошибкой, то причиной проблем с загрузкой сборки является контекст EXECUTE AS dbo.

Решение тривиально, просто введите owner_sid действительный логин. sa обычно лучший кандидат:

ALTER AUTHORIZATION ON DATABASE::[<dbanme>] TO sa;

Самое смешное, что база данных может показаться совершенно здоровой; таблицы доступны, и вы можете запускать операции выбора, обновления, удаления, создания и удаления таблиц и т. д. Только некоторые компоненты требуют EXECUTE AS:

  • для подписи кода требуется, чтобы в коде было предложение EXECUTE AS
  • проверка сборки
  • явное EXECUTE AS в коде T-SQL
  • Доставка сообщений компонента Service Broker (включая уведомления о запросах)

Последний является наиболее часто встречающимся виновником, поскольку приложения, полагающиеся на SqlDependency, внезапно перестают работать или имеют случайные проблемы. В этой статье объясняется, как SqlDependency в конечном итоге зависит от EXECUTE AS: Mysterious Notification

31 голосов
/ 05 ноября 2012

Я испытал это. Кажется, когда вы восстанавливаете базу данных TRUSTWORTHY, установленной в OFF. поэтому я решил включить его:

ALTER DATABASE [myDB] SET TRUSTWORTHY ON
GO

и после того, как я включил его, мои триггеры и хранимые процедуры начали работать как раньше.

20 голосов
/ 20 ноября 2013

На всякий случай, если кто-то сталкивался с этой проблемой, решение, которое работало для меня, было:

ALTER AUTHORIZATION ON DATABASE::[mydb] TO sa;

с последующим

ALTER DATABASE [mydb]  SET TRUSTWORTHY ON;

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

Замените [mydb] на [yourdatabasename]

6 голосов
/ 23 июля 2016

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

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

USE myDB
GO
ALTER DATABASE [myDB] SET TRUSTWORTHY ON
GO
EXEC sp_changedbowner [validDbUser]
5 голосов
/ 31 октября 2012

У меня такая же ошибка и заметил, что не так: Посмотрите на свой идентификатор сборки! Это 65536 - мой 65538

Кажется, идентификатор сборки закодирован в 16-битном целом числе. Таким образом, «серверу не хватает ресурсов» имеет логический смысл.

ошибка Microsoft, на мой взгляд. Если вы нашли лучший способ, чем перезагрузить или перезапустить службу, пожалуйста, дайте мне знать! :)

4 голосов
/ 24 января 2018

Мы увидели эту ошибку при попытке обновить пространственные столбцы на новом сервере, на котором работал SQL Server 2017.

Благодарим руководителя ИТ нашей компании-клиента, который узнал, что:

Sql 2017 ввел новые правила доверия для CLR (SQL 2012 не был проблемой) ... Даже «безопасный» CLR должен быть подписан (что не является dll), или вы должны заставить доверие какниже:

DECLARE @clrName nvarchar(4000) = 'sqlspatialtools, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil'

DECLARE @asmBin varbinary(max) = 'PUT THE BINARY STRING HERE (GET FROM SCRIPTING CREATE TO FOR THE EXISTING ASSEMBLY'

DECLARE @hash varbinary(64);

SELECT @hash = HASHBYTES('SHA2_512', @asmBin);

EXEC sys.sp_add_trusted_assembly @hash = @hash, @description = @clrName;

Это исправило проблему для нас.

1 голос
/ 01 ноября 2013

Проблема в моем случае заключалась в том, что восстановление БД было выполнено с проверкой подлинности Windows на SQL Server!Удаление БД, вход в систему с sa, восстановление БД и установка TRUSTWORTHY ON, решили мою проблему!

0 голосов
/ 29 января 2014

Это странно.У меня была та же проблема, но я подтвердил, что учетная запись dbo была действительной, выполнив быстрый запрос: ВЫБЕРИТЕ «ТЕСТ» В КАЧЕСТВЕ ТЕСТА ВЫПОЛНИТЬ КАК ПОЛЬЗОВАТЕЛЬ = «dbo» Я также подтвердил, что для параметра «Достоверный» установлено значение «Истина».исправил это для моей коробки: менялся «владелец сборки» с dbo на моего собственного пользователя, а затем обратно на dbo.

0 голосов
/ 03 сентября 2011

Я подозреваю, что вы не утилизируете экземпляры SqlConnection и SqlCommand внутри вашей сборки, поэтому у нее заканчиваются ресурсы. Либо это, либо утечка памяти, вы можете опубликовать код?

0 голосов
/ 12 августа 2011

На какие пространства имен вы ссылаетесь в сборке?SQL Server официально поддерживает только несколько ссылок, доступных в .net.

Я видел точно такую ​​же проблему при обращении к System.DirectoryServices (не поддерживается).У нас была табличная функция, которая отлично работала бы в течение недели или около того, а затем внезапно произвела бы ошибку.Повторное развертывание или перезапуск службы временно устранит проблему.

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

...