Окрім перезапуску SQL Server, чи є який-небудь спосіб змусити скинути SQLCLR AppDomain?


11

Я хочу змусити скинути AppDomain, який використовується SQLCLR. Як я можу це зробити, окрім перезавантаження екземпляра SQL Server?


Не впевнений, чи отримуєте ви повідомлення про оновлення відповідей, але я оновив свою відповідь ще простішим способом :).
Соломон Руцький

Відповіді:


6

Я знаю, що це трохи жорстоко, але як бути з відключенням CLR та його повторним включенням?

sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 0;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO

2
Важливою деталлю цього методу є те, що він працює, коли виконується на базі даних STANDBY (лише для читання); всіх інших методів, які я пробував, не роблю. Мені це було потрібно, тому що оновлення до складання CLR поширювалося як звичайне за допомогою доставки журналу до каталогу STANDBY, але AppDomain не перезавантажувався ---, тому він продовжував виконувати код зі старої версії .dll близько дня.
Грейнджер

@Granger дуже цікаво і добре знати :). Однак я вважаю, що помилка в SQL Server. Ви можете повідомити про це через веб-сайт Connect: connect.microsoft.com/SQLServer/Feedback
Соломон Руцький

1
@srutzky - Дякую за пропозицію; Я очікую, що вони просто закриють звіт як "Не виправлять". Налаштування загальносерверне, не за каталогом (як "вкладені тригери", "рівень доступу до файлового потоку" тощо). Це цілком баночки глистів, які я б намагався відкрити.
Грейнджер

@Granger (і Макс): Мені не було зрозуміло, про що я говорив, я вважав помилку. Я не казав, що скидання налаштування "Увімкнено CLR", що спричиняє завантаження, виявило помилку. Я говорив, що ALTER ASSEMBLYрозповсюджений через доставку журналів, який не перезавантажував (або принаймні вивантажував) Домен додатка, був помилкою. У будь-якому випадку я знайшов ще простіший метод, який я додав до своєї відповіді тут. Якщо ви мали можливість протестувати цей новий метод, це було б чудово, тому що мені дуже цікаво дізнатися, чи працює він у описаному вами сценарії доставки журналу.
Соломон Руцький

8

Існує більш елегантне рішення, яке не вплине на всі інші збірки: просто змініть PERMISSION_SET однієї з збірок у домені програми (домени додатків призначені для користувача).

ALTER ASSEMBLY [AssemblyName] WITH PERMISSION_SET = {1 of the 2 levels that 
                                                      this assembly is not current at}

Просто пам’ятайте, що вам потрібно буде повернути PERMISSION_SET до того, яким він був. Крім того, вам потрібно отримати доступ до методу в зборі, перш ніж змінити PERMISSION_SET, він вивантажить його; зміна збірки, яка наразі не завантажена у активний домен додатка, але з іншою збіркою, не впливає на домен додатка (Домени додатків - це DB, користувач, а не збірка).


ОНОВЛЕННЯ
Описаний вище метод є найбільш дрібним підходом, коли він буде вивантажити лише один Домен додатка. Але це вимагає, щоб збірка могла бути встановлена ​​на один з двох інших рівнів. Для збірок, позначених як, SAFEце стане можливим лише в тому випадку, коли вони є

  • базу даних встановлено на TRUSTWORTHY ON, або
  • збірка підписується і Логін, заснований на асиметричному ключі, який сам заснований на тому ж підписі, що і збірка, існує і надає EXTERNAL ACCESS ASSEMBLYабо UNSAFE ASSEMBLYдозвіл, або

У цьому випадку ви можете просто повернути TRUSTWORTHYналаштування, ONа потім негайно повернутись назад, OFFі це вивантажить усі Домени додатків у конкретній базі даних:

ALTER DATABASE CURRENT SET TRUSTWORTHY ON;
ALTER DATABASE CURRENT SET TRUSTWORTHY OFF;

Якщо у вас в базі даних є лише один домен додатка (і я підозрюю, що це 95% або більше часу), то обидва описані тут методи мають однаковий чистий ефект. І в цій ситуації ALTER DATABASEметод здається більш простим, оскільки він не вимагає вказувати конкретне ім'я об'єкта, а також не вимагає знати, яким PERMISSION_SETбув оригінал .

ТАКОЖ, якщо у вас є лише один Домен додатка, тоді ALTER DATABASEметод простіший навіть у тому випадку, коли база даних вже налаштована TRUSTWORTHY ONабо ви налаштували вхід на базі ключів з відповідним дозволом. Якщо ви використовуєте логін на основі ключів , то ви можете встановити , TRUSTWORTHYщоб ONпотім OFFзнову , як уже згадувалося вище. Але якщо ви вже TRUSTWORTHYналаштували його ON, просто переверніть його та встановіть його, OFFа потім негайно поверніться до ON:

ALTER DATABASE CURRENT SET TRUSTWORTHY OFF;
ALTER DATABASE CURRENT SET TRUSTWORTHY ON;

1
Оновлений підхід працює в каталозі баз даних STANDBY (READ_ONLY). Сервер Sql дозволив мені змінити налаштування "ДОСТУПНІСТЬ", а потім відновити його до того, що було раніше. Я переконався, що зміна насправді вивантажила домен, переглянувши результат від SELECT * FROM sys.dm_clr_appdomains;. Солодке.
Грейнджер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.