SQL Server数据库还原或分离附加后程序集遇到的SQL CLR问题

 

工做中遇到一个案例:备份还原事后或者对数据库分离&附加后(移动数据库文件),发现一些权限为EXTERNAL_ACCESS和UNSAFE程序集对应的CLR函数,在调用的时候会出现一些错误。下面特地用YourSQLDba备份还原到一个测试环境,而后调用CLR函数,就会遇到以下错误:sql

 

USE YourSQLDba;
GO
SELECT  *
FROM    [yUtl].[clr_GetFolderList]('C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\',
                                   '*.mdf');

 

 

Msg 10314, Level 16, State 11, Line 19数据库

在尝试加载程序集 ID 65537 Microsoft .NET Framework 出错。服务器可能资源不足,或者不信任该程序集。请从新运行查询,或检查有关的文档了解如何解决程序集信任问题。有关此错误的详细信息: 服务器

System.IO.FileLoadException: Could not load file or assembly 'yoursqldba_clrfileop, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An error relating to security occurred. (Exception from HRESULT: 0x8013150A)app

System.IO.FileLoadException: ide

   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)函数

   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)测试

   at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection)spa

   at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)日志

   at System.Reflection.Assembly.Load(String assemblyString)code

 

 

检查发现assembly_id=65537的程序集为YourSqlDba_ClrFileOp

 

 

USE YourSQLDba;
GO
SELECT a.name 
      ,a.principal_id
      ,a.assembly_id 
      ,a.clr_name
      ,a.permission_set_desc 
      ,a.is_visible 
      ,a.create_date 
      ,a.modify_date
FROM  sys.assemblies AS a 

 

clip_image001

 

 

 

出现这种错误,通常是EXTERNAL_ACCESS 和UNSAFE的程序集,错误出现的具体缘由有两种:

 

 

1: 数据库Owner的SID变化了。不管你是备份还原仍是分离附加操做,都要确保数据库全部者SID在数据库属性中显示的内容与源数据库元数据中记录的内容之间匹配。若是使用备份/还原,则数据库全部者SID可能不匹配(取决于你操做时使用的帐号),这将阻止CLR代码运行。

 

 

2: 数据库的TRUSTWORTHY属性值变化了。 数据库属性TRUSTWORTHY用于指明SQL Server实例是否信任该数据库以及其中的内容。 默认状况下,此设置为 OFF,可是可使用ALTER DATABASE语句将其设置为ON.

 

 

此属性可用于减小附加数据库所带来的某些隐患,该数据库包含下列对象之一:

 

·         带有 EXTERNAL_ACCESS UNSAFE 权限设置的有害程序集。 有关详细信息,请参阅 CLR Integration Security

 

·         所定义的、做为高特权用户执行的有害模块。 有关详细信息,请参阅 EXECUTE AS 子句 (Transact-SQL)

 

 

这两种状况均要求具备特定程度的权限,而且在已附加到SQL Server实例的数据库的上下文中使用这两种状况时,应采起相应的机制保护这两种状况。 可是,若是数据库脱机,则对数据库文件具备访问权限的用户可能会将其附加到其选择的SQL Server实例,并将有害内容添加到数据库中。 SQL Server中分离和附加数据库时,将对限制访问数据库文件的数据和日志文件设置某些权限。

 

由于不能当即信任附加到SQL Server实例的数据库,因此不容许数据库访问超出数据库范围的资源,直到数据库已显式标记为可信。 所以,若是备份或分离TRUSTWORTHY选项设置为 ON 的数据库并将该数据库附加或还原到同一个或另外一个 SQL Server 实例后,则附加/还原完成后 TRUSTWORTHY 属性将设置为 OFF 此外,旨在访问数据库之外资源的模块和带有 EXTERNAL_ACCESS UNSAFE 权限设置的程序集还须要其余条件才能成功运行。

 

 

 

下面检查数据库的属性TRUSTWORTHYis_trustworth_on), 以下所示

 

 

SELECT  database_id ,
        name ,
        is_trustworthy_on
FROM    sys.databases
WHERE name='YourSQLDba';

 

clip_image002

 

 

可是你对比源数据库的属性TRUSTWORTHY,就会发现数据库还原后,TRUSTWORTHY属性会变化(is_trustworth_on从1变为了0).

 

 

 

clip_image003

 

设置YourSQLDba的属性TRUSTWORTHYON

 

 

USE master;
GO
ALTER DATABASE YourSQLDba SET TRUSTWORTHY ON;

 

 

还原数据库时,因为可能使用不一样帐号,那么就会出现数据库的owner出现变化的状况。固然,也有可能使用相同的帐号操做,不会出现db_owner变化的状况。下面这种状况,就是源数据库的db_owner为sa,可是我使用域帐号作了还原操做。数据库的db_owner变成了一个域帐号。

 

 

clip_image004

 

 

USE [YourSQLDba];
GO         
EXEC sp_changedbowner 'sa';
GO

 

将数据库的db_owner修改成sa,此时问题解决。固然也能够先修改db_owner,而后设置数据库的trustworth属性。分离附加数据库也会致使TRUSTWORTHY属性变化,还有可能致使数据库db_owner变化(这个取决于你操做时使用的帐号),另外。这种错误只对权限为EXTERNAL_ACCESS 和UNSAFE的程序集出现,对于SAFE_ACCESS的程序集,不会出现这个问题。

 

 

 

 

 

 

参考资料:

 

https://support.microsoft.com/zh-cn/help/918040/you-may-receive-an-error-message-when-you-try-to-run-an-existing-clr-o

https://docs.microsoft.com/en-us/sql/relational-databases/security/trustworthy-database-property?view=sql-server-ver15

相关文章
相关标签/搜索