您正在看的SQLserver教程是:SQL Server“Yukon”Beta1CLR的基本架構。
Yukon CLR基本架構
概述
隨著SQL Server “Yukon” Beta1(也許也有人說:SQL Server2005)的推出,人們發現微軟在Yukon中集成了非常多的新功能,其中最引人矚目的是在數據庫引擎中集成了對Windows .Net Framework Common Language Runtime (CLR 公用語言運行環境)的支持。在2000年7月的專業開發者大會(PDC)上,微軟第一次向世界展示了這個新特征。
作為SQL Server 2000的開發人員,編寫數據庫的應用程序往往只局限於T-SQL,而宿主了CLR的Yukon,引入了許多強大的新特征,我們可以用Visual Basic.Net, C# 等面向對象的語言完成以前T-SQL難於完成的任務。比如,以前我們如果要調用一些系統函數(WIN32API或COM組件),我們必須寫擴展存儲過程,通過ODS(Open Data Services)開放式數據服務層和數據庫引擎交互,而現在我們通過CLR提供的托管對象可以非常方便的調用Windows .NET Framework Class Library (FCL).Net框架類庫。這些托管對象包括:
· 托管存儲過程
· 托管函數
· 托管觸發器
· 自定義復雜數據庫類型
· 自定義復雜類型索引
· 自定義集合函數
首先,我們要了解數據庫引擎集成CLR的優勢和CLR可以提供的一些關鍵特征。
CLR是一個托管的運行環境,所謂“托管”的意思是許多任務過去需要程序員負責的(比如內存管理)現在可以委托CLR來處理。作為托管代碼的一部分,CLR控制代碼執行過程中的每一個部分,同時CLR是基於類型安全(CLR扮演了代碼驗證的角色)和安全許可的環境――徹底地編譯為本地代碼(Native Code)。CLR可以“辨識”出運行的代碼是否企圖直接處理內存或調用非.Net的代碼。
.Net的可執行代碼在CLR中被裝載為程序集(assemblIEs)的形式。程序集中包括中間語言代碼(IL指令),描述代碼的元數據(Metadata)和其它資源(比如:引用其它文件列表),源代碼並不是直接保存在程序集中,而是編譯為一種CLR可以讀懂的中間語言(IL),在程序執行之前CLR通過即時編譯(JIT)將代碼轉換為本地代碼(通常是X86代碼)。如果代碼在本地運行,這個本地代碼會被加載到一段擁有生命周期的緩存,這就是說.Net的代碼是非解釋型的――它在運行時最終會被編譯成本地代碼。
CLR擁有自己管理內存的方式:如果一個對象或一組對象沒有被其它運行的代碼引用,從理論上說要回收所有不在使用的內存,但是對於CLR,內存只是在運行資源不足時才會被回收,CLR在需要額外的內存資源時才調用垃圾收集器,這種內存管理機制使程序員不用擔心內存洩漏。
所有的代碼都運行在自己的應用程序域(Application Domain)。在CLR環境中,應用程序域的作用是在單個進程中宿主不同的應用程序域,用來隔離不同的
寄宿
宿主了CLR的Yukon數據庫引擎有一些特殊需求。數據庫引擎對於資源管理是非常謹慎的――比如:通過直觀推斷數據庫使用的資源變化,在不同的緩存之間移動內存。因此,應該在數據庫引擎和CLR的資源管理方式保持某種默契關系。
在CLR的1.0和1.1的版本中, CLR提供一個API來加強進程的控制――比如判斷CLR線程池的大小。當然,這個API並非強大到可以替代CLR在Yukon中的作用, 比如:考慮以下幾種情況:
內存管理
Yukon 數據庫引擎完全控制已經被分配的內存空間,在不同的緩存之間切換,比如:存儲過程緩存和數據緩存。在這種情況下,Yukon 數據庫引擎需要有更加靈活的方法來運行CLR的垃圾收集器,同時對CLR垃圾收集器發生的條件,分配或釋放多少內存產生影響。
線程管理
CLR通過線程技術完成異步任務和多元化的並發操作。CLR擁有自己的托管線程池,用來計劃執行線程池中的任務。然而, SQL Server使用更精致的纖程機制(mechanism of fibres)來應對可能的巨量並發請求,因此,SQL Server需要接管CLR的線程管理。
並且,由於存在CLR的運行機制和SQL Server的需要之間的微妙關系,我們意識到這需要對CLR的寄宿接口進行擴展。因此隨著Whidbey(是微軟Visual Studio .NET 的下一代版本)的發布.NET會提供更多和更強大的寄宿API(Yukon發布的.NET版本和Yukon支持的.Net版本將保持一致)
在Whidbey中,有7處寄宿API的關鍵部分得到了擴展:
1. 內存管理
現在CLR允許宿主機(Yukon)取代Windows和C運行庫分配常規內存,因此現在宿主機可以控制和判斷內存的分配或釋放多少。同時,宿主機可以用自己的內存通知機制取代標准的內存通知機制,從而可以觸發垃圾收集器。宿主機也可以不進行內存分配,這時CLR會警告宿主機內存分配失敗的結果,這樣宿主機可以采取相應的策略。
Yukon通過這種策略施加對內存分配的影響,這樣來控制緩存的大小和預防潛在地可能造成內存分頁的操作。
2. 線程
現在,CLR從線程中抽象出一個新的概念叫任務(Task)。宿主機可以控制任務的分配和存儲,包括任務的開始,結束和同步等等。同時CLR和宿主機相互告知顯著的事件(比如當任務從可執行到不可執行的狀態改變,反之亦然,宿主機也要通知CLR)。宿主機可以提供配置CLR線程池工具。這樣的集成級別允許Yukon延續自己的軌跡同時允許CLR運行2個異步任務。
3. I/O實現
寄宿API現在可以為了CLR的利益配置宿主機I/O同步,在I/O操作完成後通知CLR。這樣Yukon可以完全了解進程內所有I/O的操作。
您正在看的SQLserver教程是:SQL Server“Yukon”Beta1CLR的基本架構。4. 同步
如果CLR放棄對任務的控制,就必須運許宿主機提供同步不同任務的手段。因此,宿主機必須提供一個方法來建立:臨界區(critical section),互斥體(mutexes),事件(events),讀寫鎖(reader/writer locks)和監控器(monitors)。 宿主機通過這些控制方式,就完全可以檢測死鎖操作。這樣Yukon就可以正確的處理CLR請求的計劃任務從而提高整體運行的可靠性,解決同步過程中的死鎖。
5. 托管和非托管
宿主機托管代碼完成P/Invoke調用,轉換為本地機器碼時可能會有問題,因為目前還沒有在代碼運行時檢測何種鎖被丟棄的方法。新的宿主API中允許任務在脫離CLR控制時通知宿主機。比如:當代碼運行在CLR外部時,Yukon會調整任務到non-fibre scheduled 任務。同樣這些非托管的代碼塊對數據庫引擎是透明的-例如:數據訪問的API,這些和其它的非托管代碼是區別對待的。