首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server CLR 整合 DBA 指南 (二):目錄物件、安全性、原始碼管理與監控

     編輯:關於SqlServer

承接第一篇,本文深入 CLR 整合後的系統目錄物件查詢、權限模型、原始碼與版本控制策略、效能監控計數器與 DMV 查詢、偵錯與疑難排解指南,協助 DBA 全面掌控 CLR 物件生命週期。

一、CLR 系統目錄物件查詢

SQL Server 2005 引入新目錄檢視追蹤組件 (Assembly) 及相關 CLR 物件:

組件相關檢視

-- 組件基本資訊:名稱、ID、權限集、可見性
SELECT * FROM sys.assemblies;

-- 組件檔案:每個組件包含的檔案 (含原始碼)
SELECT * FROM sys.assembly_files;

-- 組件模組:SQL 物件 ID 對應組件方法
SELECT * FROM sys.assembly_modules;

-- 組件參考:組件間相依關係
SELECT * FROM sys.assembly_references;

-- 模組組件使用:SQL 物件 ID 與組件 ID 連結 (部分重複 assembly_modules)
SELECT * FROM sys.module_assembly_usages;

sys.assemblies.is_visible 可隱藏組件 (如 XML Serializer 產生的輔助組件)。assembly_modules 中 assembly_method 為 NULL 表示使用者定義彙總 (UDA)。

系統預存程序

EXEC sys.sp_assemblies_rowset N'<AssemblyName>';
EXEC sys.sp_assembly_dependencies_rowset <AssemblyID>;

各類 CLR 物件查詢範本

物件類型關鍵查詢條件
CLR 預存程序sp.type_desc = 'CLR_STORED_PROCEDURE'
CLR 觸發器tr.type_desc = 'CLR_TRIGGER'
CLR 純量函數so.type_desc = 'CLR_SCALAR_FUNCTION'
CLR 資料表值函數so.type_desc = 'CLR_TABLE_VALUED_FUNCTION'
CLR 使用者定義彙總so.type_desc = 'AGGREGATE_FUNCTION'
CLR 使用者定義型別 (UDT)查詢 sys.types join sys.type_assembly_usages

完整查詢範本請參考原文,核心皆為:sys.objects → module_assembly_usages → sys.assemblies 三表聯結。

二、CLR 安全性模型:三大權限集

權限集允許操作風險與建議
SAFE (預設)純運算、資料存取、邏輯處理,同 T-SQL 權限。受信任呼叫者模型。最安全,優先使用。無法存取外部資源 (檔案、網路、註冊表)。
EXTERNAL_ACCESSSAFE 所有權限 + 檔案/網路 I/O、Web Service 呼叫。以 SQL Server 服務帳號身分執行。需嚴格審核。確認呼叫者權限、輸入驗證。建議僅受信任組件使用。
UNSAFEEXTERNAL_ACCESS 所有權限 + Unmanaged 程式碼呼叫、執行緒控制、記憶體直接操作、COM Interop。極高風險。可能導致 SQL Server 程序崩潰、記憶體洩漏、安全性破洞。嚴格限制使用,生產環境原則上禁止。

建立組件時指定:CREATE ASSEMBLY ... WITH PERMISSION_SET = SAFE | EXTERNAL_ACCESS | UNSAFE。

三、原始碼管理與版本控制策略

  1. 原始碼必須納入版控:CREATE ASSEMBLY 僅載入二進位 DLL,原始碼不進資料庫。DBA 需建立流程確保原始碼與部署版本一致。
  2. 建議工具鏈:
    • 開發:Visual Studio 2005+ (SQL Server Database Project)
    • 版控:Visual SourceSafe / TFS / Git
    • 建置:MSBuild / VS 自動部署 (僅開發/測試環境)
    • 生產部署:DBA 手動執行 CREATE/ALTER ASSEMBLY,並將原始碼、PDB、建置日誌存入受控儲存庫
  3. 將原始碼附加至組件 (SQL Server 2005 支援):
ALTER ASSEMBLY LeastSquaresSqlFunction
ADD FILE FROM 'D:\Production\Source\LeastSquares\LS1.cs';
  • ALTER ASSEMBLY 支援單一陳述式加入多檔案。
  • DBA 與開發皆應在簽入/部署時記錄變更說明。
  • 使用 WinDiff / Visual Studio Compare 驗證版本差異。
  • VS 建置輸出面板的編譯器命令列可複製為重建指令碼。

四、發行管理

  • 開發提交原始碼 + 編譯輸出 (DLL/PDB)
  • DBA 審核程式碼、執行靜態分析、單元測試
  • 建立受控部署套件:DLL + 原始碼 + 部署腳本 + 回滾腳本
  • 多實例環境:每個載入組件的資料庫建立關聯副本,確保可追溯

五、效能監控:效能計數器與 DMV

關鍵效能計數器

計數器物件關鍵指標異常判讀
.NET CLR ExceptionsExceptions/sec驟增預示應用程式錯誤,需檢視錯誤日誌
.NET CLR LoadingAppDomains、Loaded Assemblies過大表示 Procedure Cache 壓力
.NET CLR MemoryGen 0/1/2 Heap Size、% Time in GC記憶體異常增長需重構程式碼
.NET Data Provider for SqlServer連接數、連接池狀態資料庫層級活動監控

實用 DMV 查詢

-- 已載入組件 (各資料庫執行)
SELECT sa.name, ad.appdomain_name, clr.load_time
FROM sys.dm_clr_loaded_assemblies clr
JOIN sys.assemblies sa ON clr.assembly_id = sa.assembly_id
JOIN sys.dm_clr_appdomains ad ON clr.appdomain_address = ad.appdomain_address;

-- CLR 記憶體使用
SELECT mo.type, SUM(mo.pages_allocated_count * mo.page_size_in_bytes/1024) AS Current_KB,
       SUM(mo.max_pages_allocated_count * mo.page_size_in_bytes/1024) AS Max_KB
FROM sys.dm_os_memory_objects mo
WHERE mo.type LIKE '%clr%'
GROUP BY mo.type ORDER BY mo.type;

-- CLR 等待統計
SELECT * FROM sys.dm_os_wait_stats WHERE wait_type LIKE '%clr%';

-- 正在執行 CLR 程式碼的請求
SELECT session_id, request_id, start_time, status, command, database_id,
       wait_type, wait_time, cpu_time, total_elapsed_time, executing_managed_code
FROM sys.dm_exec_requests WHERE executing_managed_code = 1;

-- CLR 耗時最久的查詢
SELECT (SELECT text FROM sys.dm_exec_sql_text(qs.sql_handle)) AS query_text, qs.*
FROM sys.dm_exec_query_stats qs
WHERE qs.total_clr_time > 0
ORDER BY qs.total_clr_time DESC;

-- CLR 效能計數器值
SELECT object_name, counter_name, cntr_value, cntr_type
FROM sys.dm_os_performance_counters WHERE counter_name LIKE '%CLR%';

六、偵錯與疑難排解

偵錯工具分工

  • DBA:SQL Server Profiler 追蹤資料庫活動 (事件:CLR、SP:StmtStarting 等)
  • 開發:Visual Studio Debugger 逐步偵錯 CLR 程式碼 (需開發版 SQL Server),支援端到端 Client-Server 偵錯

注意:CLR 整合不支援並發偵錯,建議開發人員使用專屬開發實例。

常見效能反模式與對策

錯誤處理最佳實務

  • 使用 .NET 結構化例外處理 (try/catch/finally)
  • 外部呼叫 (DB、檔案、Web Service) 必須包裹例外處理
  • 使用 SQLContext.Pipe.ExecuteAndSend() 搭配 RAISERROR 回傳 SQL 錯誤
  • 優先拋出例外而非回傳錯誤碼 (開發者易忽略 @@ERROR)

UNSAFE 程式碼管控

  • 部署前全碼審:參數驗證、連線管理、交易邊界、Unmanaged 呼叫審查
  • 共用實例嚴禁 UNSAFE,需專用實例並啟用嚴格稽核
  • 啟用 clr strict security (SQL 2017+) 強制所有組件視為 UNSAFE 並需簽章/信任

UDT 使用限制

  • 大小上限 8 KB (單一資料頁)
  • 序列化/反序列化為整體讀寫,更新成本高
  • 結構變更需重新部署,影響範圍大
  • 慎用,優先考慮標準型別 + 檢查約束

七、展望:超越 SQL Server 2005

  • 未來版本可能要求重新編譯 (確保原始碼同步)、修改 API 相容性、支援多 CLR 版本並存
  • DBA 需持續管理原始碼、監控 API 使用、預留重寫緩衝

總結

CLR 整合賦予 SQL Server 強大擴充能力,但也帶來新的治理挑戰。DBA 必須掌握:目錄查詢 追蹤物件、權限集 管控風險、原始碼管理 確保可追溯、監控計數器/DMV 早期預警、偵錯分工 提升效率。嚴格遵循「SAFE 優先、EXTERNAL_ACCESS 審核、UNSAFE 禁用」原則,才能在享受生產力提升的同時守護資料庫穩定與安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
反模式徵兆對策
缺乏 Set-based 操作 (迴圈套迴圈)Profiler 顯示大量單行查詢改寫為 JOIN/集合運算;移至中介層處理
CLR 內大量 CPU 密集運算sys.dm_clr_appdomains 顯示高 CPU評估移至中介層;若留資料庫需嚴格負載測試
記憶體中建立大型物件 (DataSet、集合).NET CLR Memory 計數器異常分頁處理、確認資料提交、僅傳遞彙總結果