SQL Server 停止加载程序集
我们为 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 Server 恢复了数据库,但我发誓我没有这样做。
这个博客说如果我在 SQL Server 2005 上安装 .NET 3.5,我可能会遇到这个问题,但我的是SQL Server 2008 R2,出现此问题时我没有安装任何东西。
最主要的是它可以持续一段时间。它只是随机停止工作。然后,如果我们重新启动 SQL Server,它将再次开始工作。我曾以为我的服务器确实内存不足,但现在,我又看到了这个问题。 SQL Server 仅使用 300MB RAM,而我的服务器有 16GB RAM。这听起来不可能,因为我的内存不足。
现在,我想收集有关这个问题的更多信息。我可以打开并查看任何日志吗?欢迎任何有助于解决此问题的建议。
我已经运行了一些 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 处于需要我重新启动才能使其再次工作的状态。
* UPDATE (8/31/2011) *
听起来好像与数据库的数据库所有者有关。这有点复杂。我们有两个站点和两个 AD 森林。 SQL Server 计算机已加入林 A,但数据库所有者来自林 B。林 A 和林 B 之间的连接不太稳定,因为它们位于通过 WAN 物理连接的两个不同站点。
一旦我将数据库所有者更改为 SQL 登录(非 Windows 帐户),我的存储过程到目前为止将运行几周,没有中断。
如果有人能解释的话我会接受答案。
We have developed an assembly for SQL Server 2008 R2.
The assembly has been working for a week. The managed stored proc inside the assembly was working fine for the whole week and then it stops working. We have been seeing this problem couple times. The way to make it work again is to restart the 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)
I have found different articles on the web.
This KB suggested that I might have restored the database from another SQL Server, which I swear I didn't.
This blog said I might run into this if I installed .NET 3.5 on SQL Server 2005 but mine was SQL Server 2008 R2 and I did not install anything when this problem occurs.
The main point is that it can keep going for a period of time. It just stops working randomly. Then, if we restart the SQL Server, it will start working again. I have thought of my server was really running out of memory but now, I just see the problem again. SQL Server is using 300MB RAM only and my server has 16GB RAM. This sounds impossible that it's because I am running out of memory.
Now, I want to collect more information on this problem. Any log that I can turn on and look at? Any suggestion that help troubleshooting this problem is welcome.
I have run some SQL queries.
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>
* UPDATE *
On my SQL Server, I have created four databases. Each of them with the same assembly attached to it. Now, SQL Server refused to load the assembly and gave me the above error.
SELECT * from sys.dm_clr_appdomains
shows me at that point there was only one appdomain loaded and SELECT * from sys.dm_clr_loaded_assemblies
showed me there were no assemblies loaded at all.
Then, I ran the same stored proc on the other three databases. It worked and successfully loaded up the assemblies and successfully ran the stored proc. After executing the stored proc. SELECT * from sys.dm_clr_appdomains
now shows me there are only four appdomain loaded and SELECT * from sys.dm_clr_loaded_assemblies
showed me there are now three assemblies loaded.
This makes sense. Now, I hope if I run the stored proc again in the original database, it should get the assembly loaded as it were. Guess what. No, it doesn't. It still gives me the same error. It looks like this database is completely stuck. The only way to fix it is to reboot the SQL Server. I am hoping there is a flag/lock somewhere in the system table holding up this. I cannot find it. Any idea is welcome.
Now, my SQL Server is in the state that requiring me to reboot to make it work again.
* UPDATE (8/31/2011) *
It sounds like it's related to the database owner of the database. This is kind of complicated. We have two sites and two AD forests. The SQL Server machine is joined to forest A but the database owner is from forest B. The connection between forest A and forest B is not that stable since they are in two different sites physically connected by WAN.
Once I change the database owner to a SQL Login (Non-Windows account), my stored proc is up running for couple weeks so far with no interruption.
I will accept the answer if anybody can explain it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
具有 EXTERNAL_ACCESS 的程序集通过一些复杂的路径落入 EXECUTE AS 路径下。当“dbo”无法映射到有效登录名时,就会出现此问题。 dbo 的登录名是 SID 为 中的
owner_sid
值的登录名sys.databases
。除非在 CREATE DATABASE 中使用了 AUTHORIZATION 子句,否则owner_sid 是发出 CREATE DATABASE 语句的主体的登录 sid。大多数情况下,这是登录并发出 CREATE DATABASE 的用户的 Windows SID。有了这些知识,我们就可以很容易地预见到可能出现的问题:MachineA\user
或DomainA\ user
),然后数据库被复制到机器 B(通过备份/恢复或通过文件复制)。 owner_sid 通过文件复制以及备份/恢复来保留,这在机器 B 上owner_sid 无效。所有需要 EXECUTE As 的操作都会失败,包括从数据库加载程序集。所有这些问题都可以通过简单运行来诊断:
EXECUTE AS USER = 'dbo';
在问题数据库的上下文中。如果它因错误而失败,则程序集加载问题的原因是dbo
的 EXECUTE AS 上下文。解决方案很简单,只需强制
owner_sid
进行有效登录即可。sa
通常是最好的候选者:有趣的是,数据库可能看起来非常健康;表可用,您可以运行选择、更新、删除、创建和删除表等。只有某些组件需要 EXECUTE AS:
T-SQL 代码中的 EXECUTE AS
后者是最常见的罪魁祸首,因为应用程序依赖于
SqlDependency
全部突然似乎停止工作,或者出现随机问题。本文解释了SqlDependency
最终如何依赖于 EXECUTE AS:神秘的通知Assemblies with EXTERNAL_ACCESS are, through some convoluted path, falling under the EXECUTE AS path. The problem appears when the 'dbo' cannot be mapped to a valid login. dbo's login is the login with the SID the
owner_sid
value insys.databases
. Unless an AUTHORIZATION clause was used in CREATE DATABASE the owner_sid is the login sid of the principal issuing the CREATE DATABASE statement. Most times this is the Windows SID of the user logged in and issuing the CREATE DATABASE. With this knowledge in hand one can easily envision the problems that may arise:MachineA\user
orDomainA\user
) then the database was copied to machine B (via backup/restore or via file copy). The owner_sid is preserved by file copy as well as by backup/restore, this on machine B the owner_sid is invalid. Everything requiring EXECUTE As fails, including loading assemblies from the database.All these issues can be diagnosed by simply running:
EXECUTE AS USER = 'dbo';
in the context of the problem db. It it fails with an error then the cause of your assembly load problems is the EXECUTE AS context ofdbo
.The solution is trivial, simply force the
owner_sid
to a valid login.sa
is the usually the best candidate:The funny thing is that the database may seem to be perfectly healthy; tables are available and you can run selects, updates, deletes, create and drop tables etc. Only certain components require
EXECUTE AS
:EXECUTE AS
in T-SQL codeThe latter is the most often seen culprit, as applications relying on
SqlDependency
all of a sudden seem to stop working, or have random problems. This article explains howSqlDependency
ultimately depends on EXECUTE AS: The Mysterious Notification我经历过。似乎当您恢复数据库 TRUSTWORTHY 设置为 OFF 时。所以我的解决方案是打开它:
打开它后,我的触发器和存储过程开始像以前一样工作。
I experienced it. it seems when you restore a database TRUSTWORTHY set to OFF. so my solution was to turn it on :
and after i turned it on, my triggers and stored procedures started to work like before.
以防万一有人遇到这个问题,对我有用的解决方案是:
然后
我使用管理员帐户恢复我的数据库,除了这两个调用的组合之外,没有其他方法对我有用。
将 [mydb] 替换为 [yourdatabasename]
Just in case someone comes across this problem, the solution that worked for me was:
followed by
I am restoring my db with the Administrator account, and nothing else other than the combination of these two calls has worked for me.
Substitute [mydb] for [yourdatabasename]
在我的情况下,需要进行一些组合,其中我从不同的服务器复制了数据库,并且创建数据库的用户不在新服务器上。
myDB 是我尝试访问的数据库
validDbUser 是我希望将移植数据库的所有权更改为的新数据库服务器上的用户名。
A combination of things were required in my case where I had copied a database from a different server and the user who created the database was not present on the new server.
myDB is the database that I am trying to access
validDbUser is the user name on the new database server that I wish to change the owner ship of the transplanted database to.
我将数据库从服务器恢复到本地计算机并遇到此错误。尝试以下两个查询。对我来说,第一个查询有效:
--First Query
--Second Query
-- 如果设置为 false,则启用 CLR 集成
-- 如果设置为 true,则禁用 CLR 严格安全性
I restored the DB from server to my local machine and ran into this error. Try the below two queries. For me, the first query worked:
--First Query
--Second Query
-- Enabling CLR Integration if it is set to false
-- Disabling CLR strict security, if it is set to true
当我们尝试在运行 SQL Server 2017 的新服务器上更新空间列时,我们看到了此错误。
感谢我们客户公司的 IT 主管,他发现:
这为我们解决了问题。
We saw this error when trying to update spatial columns on a new server which was running SQL Server 2017.
Credit to the head of IT at our client company who found out that:
This fixed the issue for us.
我有同样的错误并注意到出了什么问题:
查看您的程序集 ID!
它是 65536 - 我的是 65538
看来程序集 ID 是用 16 位整数编码的。
因此,“服务器可能耗尽资源”具有逻辑意义。
在我看来,微软的错误。
如果您找到比重新启动或重新启动服务更好的方法,请告诉我! :)
I have the same error and noticed what is wrong :
Have a look at your assembly ID !
It is 65536 - mine is 65538
It seems the assembly ID is coded on a 16bits integer.
So, "server may be running out of resources" takes a logical sense.
Microsoft bug, in my opinion.
If you have find a better way than reboot or restart the service, please let me know! :)
就我而言(SQL 2019 CU10),由于自 SQL 2017 以来引入的 CLR 严格安全功能,发生了错误。您可以在此处阅读有关此内容的更多信息:CLR 严格安全
简而言之,解决方案是禁用该功能,以便可以加载未签名的程序集。
另外,禁用该功能后我必须重新启动 sql server 引擎。由于某种原因,更改并未立即生效。
我知道更好的解决方案是对程序集进行签名,但在我的情况下这是不可能的,这个解决方案让我有时间要求开发人员提供签名的程序集。
In my case (SQL 2019 CU10) the error was happening because of the CLR strict security feature introduced since SQL 2017. You can read more about this here: CLR strict security
In short the solution is to disable that feature so non-signed assemblies can be loaded.
Also, I had to restart the sql server engine after disabling the feature. For some reason the change did not take effect immediately.
I understand that a better solution is to sign the assembly but in my case that was not possible and this solution gave me time to ask the developers to provide signed assemblys.
此消息可能与新实例上 SQL 用户帐户的权限有关。
使用 ;
EXEC sp_configure 'clrenabled' ,1
GO
USE
GO
EXEC sp_changedbowner 'sa'
USE
GO
ALTER DATABASE SET TRUSTWORTHY ON;
你完成了...!
This message is likely related to permissions to the SQL user account on the new instance.
USE ;
EXEC sp_configure 'clr enabled' ,1
GO
USE
GO
EXEC sp_changedbowner 'sa'
USE
GO
ALTER DATABASE SET TRUSTWORTHY ON;
YOU ARE DONE...!
我的问题是数据库恢复是在 SQL Server 上使用 Windows 身份验证执行的!删除数据库,使用 sa 登录,再次恢复数据库并设置 TRUSTWORTHY ON,解决了我的问题!
Problem in my case was that DB restore was executed with Windows Authentication on SQL Server! Droping DB, loging in with sa, restoring DB again and setting TRUSTWORTHY ON, solved my problem!
您在程序集中引用了哪些命名空间? SQL Server 仅正式支持少数 .net 提供的参考资料。
我在引用 System.DirectoryServices (不受支持)时看到了完全相同的问题。我们有一个 clr 表值函数,可以在一周左右的时间内正常工作,然后突然出错。重新部署或回收服务可以暂时解决该问题。
确保所有命名空间引用都受支持。否则,您可能会关闭数据库。
What namespaces are you referencing in the assembly? SQL Server only officially supports a handful of the references that .net has available.
I've seen the exact same issue when referencing System.DirectoryServices (unsupported). We had a clr table valued function that would work great for a week or so and then, all of the sudden, would error. A redeploy or recycle of the service would temporarily fix the issue.
Make sure all of your namespace references are supported. Otherwise, you can potentially bring down the database.
这很奇怪。我遇到了同样的问题,但我通过运行快速查询确认 dbo 帐户有效:
选择“测试”作为测试
作为用户执行 = 'dbo'
我还验证了 Trustworthy 已设置为 True。
修复我的盒子的方法是将“程序集所有者”从 dbo 更改为我自己的用户,然后再更改回 dbo。
This is weird. I had the same issue but I confirmed that the dbo account was valid via running a quick query:
SELECT 'TEST' AS Test
EXECUTE AS USER = 'dbo'
I also verified that Trustworthy was set to True.
What fixed it for my box was changing the "assembly owner" from dbo to my own user and afterwards back to dbo.
我发现了同样的问题。就我而言,CLR 程序集是针对 x86 cpu 编译的。在我将 cpu 更改为任何 CPU 后,此问题得到解决,因为我的 SQL 服务器是 64 位。
我希望这有用。
I found the same issue. In my case the CLR assembly was compiled for x86 cpu. After I changed the cpu to ANY CPU this issue was resolved since my SQL server is 64 bits.
I hope this useful.
这对我有用。请注意,直到我将数据库所有者更改为“sa”后,它才起作用。
This worked for me. Note, it did not work until I changed the database owner to "sa".
我怀疑您没有在程序集中处理
SqlConnection
和SqlCommand
实例,这就是它耗尽资源的原因。要么就是内存泄漏,你能发布代码吗?I suspect you are not disposing your
SqlConnection
andSqlCommand
instances inside your assembly, which is why it's running out of resources. Either that or it has a memory leak, can you post the code?