DBA眼中的CLR
Posted 詩和遠方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DBA眼中的CLR相关的知识,希望对你有一定的参考价值。
SQL Server 2005引入CLR之後,開發者們熱情地接受了它。
CLR作爲一個強有力的工具,開發者可在數據庫中利用它調用其他面嚮對象語言編寫而成的功能。
從DBA的視角來看,CLR的引入淡化了編譯型代碼與數據庫代碼的區別。它引發了在部署、管理CLR代碼以及安全性上,開發者和DBA的角色問題。在某種程度上,它也淡化了在多層架構的系統中,業務邏輯層和數據訪問層的區間。
對許多組織而言,實現CLR需要決策有關開發過程和它們涉及到的角色。如果你準備執行CLR,你需要足夠多的非技術細節信息來印證這些決定。
最後,我將指出如何實現CLR,討論CLR代碼的利弊,以及CLR技術給SQL Server管理和安全方面帶來的影響。我也將描述哪些情況適合用CLR,而哪些情況可能不適合。
創建與部署CLR
CLR是一個程序模型,它允許開發者用面嚮對象語言來寫編寫代碼,然後像T-SQL存儲過程、函數或觸發器一樣去使用它。一般創建過程如下:
1、創建VS工程,代碼可以用C#/VB.Net編寫;
2、代碼被編譯後,直接從VS部署到目標數據庫。編譯後會產生一個DLL文件,DLL是一個包含編譯後代碼的可運行的文件。部署後,將會在sys.assemblies視圖和其他相關視圖中插入對應程序集信息,
3、通過對程序集運用EXTERNAL NAME選項,一個或多個T-SQL對象將在數據爲中被創建。這些對象對稱爲原型,一個原型能被定義爲存儲過程,函數,用戶自定義聚集函數或用戶自定義類型。原型中不包含代碼,它只是一個簡單的可被其它數據庫代碼調用的入口,被調用時,DLL中編譯後的代碼將會運行。
通常,當你從VS編譯和部署時,上述所有步驟都會被執行,但你也可以手動分開執行每一步。
現代的面嚮對象語言有一些對T-SQL來說是非常困難甚至無法實現的功能。CLR則提供了一種在數據庫中運用這些語言豐富特性的方式。對於計算或迭代性的操作,CLR通常提供比T-SQL更優的性能。CLR代碼和SQL Server在同一個內存上下文中運行,所以它運行得非常有效率。
CLR代碼是被託管的代碼,這意味着它在『CLR運行時』中運行時,可以確保不會出現代碼運行時使服務器不穩定的情況。盡管這是好事,但任何形式的虛擬化都會有一定程序的開銷,CLR如果運用不當還是會影響性能的。盡管編譯後的代碼在SQL內存空間中會運行得很有效率,但T-SQL仍然是繁重工作的最好選擇,如果要訪問和返回大批量的數據,CLR並不是一個好的選擇。
總之一句話,T-SQL處理集合類操作更加有效率,而CLR對迭代、過程、計算類操作更加在行。當然也會有例外的時候。
管理CLR
有時DBA與CLR打的第一個交道就是有人提議在服務器上啟用CLR。雖然啟用CLR只是在服務的選項中啟用CLR配置項這麼簡單,但在啟動它之前你需要考慮很多問題。
將腳本部署到數據庫是DBA的傳統職責,DBA同時也要保證腳本正常工作而且不影響性能或引發服務器上的其它問題。然而,CLR代碼一般是從VS開發環境中直接部署到數據庫中的,而DBA一般不使用VS,這似乎意味著開發人員比DBA更適合去部署CLR代碼。
開發人員可以編寫編譯過後的代碼在SQL Server中像SQL代碼一樣運行,DBA或許會對此感覺不爽,但DBA仍然可以控制誰可以加載CLR程序集,在什麼安全級別下運行CLR功能。
CLR安全性
默認的,只有sysadmin、db_ower、ddl_admin角色的用戶有權限去運行程序集相關的DDL語句。這個權限可以賦給其他角色和用戶。另外,如下三種權限集可以讓你設置程序集本身的三種安全級別:
SAFE。此安全級別只允許訪問本地數據和內部計算。對系統資源,比如文件、網絡、環境變量或者註冊表的訪問是禁止的。任何有創建程序集權限的用戶都可以創建一個SAFE級別的程序集。如果CREATE ASSEMBLY語句沒有顯示指定安全級別,SAFE將是默認的級別。
EXTERNAL ACCESS。此安全級別允許程序集訪問外部資源。擁有EXTERNAL ACCESS權限的用戶才可以創建此安全級別的信息集。
UNSAFE。在將程序集設為UNSAFE時請三思,此級別的程序集在SQL Server內外都擁有不受約束的訪問權限。在UNSAFE程序集裏的代碼也可能是不受管理的代碼,意味著它有讓服務器不穩定的可能。僅sysadmins用戶組的用戶可以登陸UNSAFE的程序集。
默認的,CLR代碼都是在SQL SERVER服務帳號的安全上下文運行,如果你要訪問SQL Server之外的資源,這就會有問題,最好的做法是不超過服務帳號的權限。但是CLR代碼可以通過模擬其他Windows帳號來運行。UNSAFE和EXTERNAL ACCESS安全級別的程序集有這種能力。可以創建這種程序集的人必須是深受公司信任的。
理解CLR元數據
在一個啟用了CLR選項的環境中,DBA應該對如下5個包含了元數據信息的系統視圖非常熟悉:
sys.assembiles. 此視圖每行記錄對應一個程序集。它包含了程序集的一些屬性,比如名稱、安全級別和創建日期。
sys.assembly_files. 對數據庫中每一個程序集,這個視圖都包含了一行信息說明其源文件、DLL文件。
sys.assembly_modules. 一個程序集可能包含多個類,比如存儲過程和函數。程序集裏的類可能包含多個實現不同功能的代碼模塊。這個視圖將各自獨立的代碼模塊ID與引用它們的數據庫對象ID關聯在一起了。如下查詢可以查出每個CLR數據庫對象引用的程序集的類和方法:
SELECT OBJECT_NAME(m.object_id) AS db_object
,a.name AS assembly
,m.assembly_class
,m.assembly_method
FROM sys.assembly_modules m
INNER JOIN sys.assemblies a ON a.assembly_id = m.assembly_id
sys.assembly_references.程序集之間的相互引用依賴關係。
sys.module_assembly_usages將程序集的ID與引用它們的數據庫對象ID,關係起來了。
SELECT OBJECT_NAME(object_id) AS db_object
,a.name AS assembly
FROM sys.module_assembly_usages u
INNER JOIN sys.assemblies a ON a.assembly_id = u.assembly_id
移除CLR程序集
VS可以很方便創建和部署CLR程序集到SQL Server中,但並沒有同樣方便的工具去卸載它們。你必須有順序地手動將它們移動。
在移除某程序集之前可以通過查看依賴項先移動那些引用此程序集的T-Sql對象,可以Sp_Depends或在對象資源管理器中右鍵查看。
更好的改變
純T-SQL的數據庫編程時代正在發生變化,CLR正是這一跡象的例子。盡管有人會有點排斥,但正是變化讓DBA生涯變得有趣。CLR真正突破了T-SQL在某些方面的限制。兩種模式的混合編程能力是一個強大的工具,DBA和開發者都應該掌握它們。
附常用查詢
-- Assembly Query
SELECT * FROM sys.assembly_modules;
SELECT * FROM sys.assemblies;
SELECT * FROM sys.assembly_files;
-- CLR Object In Database
SELECT * FROM sys.objects WHERE type_desc LIKE ‘CLR%‘;
-- 哪些系统对象引用了CLR程序集
SELECT OBJECT_NAME(object_id) AS [Object_Name],b.Name AS Assembly_Name
FROM sys.module_assembly_usages a
INNER JOIN sys.assemblies b ON a.assembly_id = b.assembly_id;
以上是关于DBA眼中的CLR的主要内容,如果未能解决你的问题,请参考以下文章