除了重新启动SQL Server,是否有任何方法可以强制重置SQLCLR AppDomain?


11

我想强制重置由SQLCLR使用的AppDomain。除了重新启动SQL Server实例外,我该怎么办?


不知道您是否收到有关更新答案的通知,但是我用一种更简单的方法来更新我的答案:)。
所罗门·鲁兹基

Answers:


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 2014年

@Granger非常有趣,很高兴知道:)。但是,我认为这是SQL Server中的错误。您可能想通过Connect网站进行报告:connect.microsoft.com/SQLServer/Feedback
Solomon Rutzky 2014年

1
@srutzky-感谢您的建议;我希望他们只是将报告关闭为“无法解决”。该设置在服务器范围内,而不是每个目录(就像“嵌套触发器”,“文件流访问级别”等一样)。那就是我要打开的蠕虫罐。
Granger 2014年

@Granger(和Max):我不清楚我说的是什么错误。我并不是说重置导致卸载的“ CLR Enabled”设置是一个错误。我是说ALTER ASSEMBLY没有重新加载(或至少卸载)App Domain的日志传送所传播的错误。无论哪种方式,我都找到了一个更简单的方法,该方法已添加到此处的答案中。如果您有能力测试这种新方法,那就太好了,我非常想知道它是否在您描述的日志传送方案中有效。
所罗门·鲁兹基

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以将其卸载;更改当前未加载到活动的应用程序域中但使用另一个程序集的程序集对应用程序域没有影响(应用程序域是按数据库,按用户,而非按程序集)。


更新
上述方法是最细粒度的方法,它将仅卸载该一个App Domain。但是,确实需要将组件设置为其他两个级别之一。对于标记为的装配件,SAFE只有在

  • 数据库设置为TRUSTWORTHY ON,或
  • 对该程序集进行签名,并且存在一个基于非对称密钥的登录名,该密钥本身基于与该程序集相同的签名,并且已被授予EXTERNAL ACCESS ASSEMBLYUNSAFE ASSEMBLY许可

在这种情况下,您可以简单地打开TRUSTWORTHY设置ON,然后立即OFF再次返回,这将卸载该特定数据库中的所有 App Domain:

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

如果数据库中仍然只有一个App Domain(我怀疑是95%或更多的情况是这种情况),那么这里描述的两种方法都具有相同的实际效果。在这种情况下,该ALTER DATABASE方法似乎更简单,因为它不需要指定特定的对象名称,也不需要知道原始对象PERMISSION_SET是什么。

另外,如果您只有一个App Domain,那么ALTER DATABASE即使数据库已经设置为TRUSTWORTHY ON或您已经使用适当的权限设置了基于密钥的登录名,该方法也更加简单。如果您使用的是基于密钥的登录名,则可以如上所述设置TRUSTWORTHYON,然后OFF再次设置。但是,如果您已经TRUSTWORTHY设置为ON,则只需将其反转并设置为OFF,然后立即返回ON

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

1
更新后的方法适用于STANDBY(READ_ONLY)数据库目录。Sql Server允许我更改“ TRUSTWORTHY”设置,然后将其还原为以前的设置。通过查看的结果,我验证了更改是否真正卸载了域SELECT * FROM sys.dm_clr_appdomains;。甜。
Granger
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.