儲存過程最佳實踐:有圍欄還是無圍欄?
我相信我了解受保護和不受保護的儲存過程背後的原因。
Fenced 在數據庫“外部”執行(在我們的例子中是 DB2),以防止出現指針等問題時數據庫引擎可能發生的損壞。
Unfenced 在數據庫“內部”執行,這意味著性能更好。
根據我的研究,SQL PL 基本上總是不受保護的,因為它是 SQL,因此不能像程式語言那樣訪問記憶體。
C/C++ 和 Java 過程可以執行受保護或不受保護。但是由於它們可能訪問記憶體,因此應該考慮將它們隔離執行,除非可以確定程式碼的質量不會崩潰並且需要性能。
首先,我對上述內容的理解是否正確?
接下來,從所有儲存過程(甚至定義為 SQL PL 的儲存過程)開始作為防護通常是一個最佳實踐嗎?
儲存過程的任何其他最佳實踐,尤其是與防護和/或安全相關的?
**編輯:**進一步的研究表明 SQL PL 程序不能執行。由於它們不包含任何可能損害數據庫引擎的程式碼,例如指針或文件 I/O,DB2 知道它們是安全的,並在引擎內部執行它們(即不受保護)。話雖如此,我仍在尋找有關所有其他儲存過程的最佳實踐。
更準確地說,
NOT FENCED
常式與數據庫管理器本身在相同的程序空間中執行。該引擎是用 C 語言編寫的,因此呼叫未受保護的常式就像從main()
. 這就是所有記憶體損壞和性能方面的來源:一個不受保護的常式可以訪問所有相同的資源——記憶體、文件等——就像數據庫管理器程序本身一樣。對於
FENCED
常式,數據庫管理器啟動一個單獨的程序 (db2fmp
),該程序依次執行常式程式碼。因此,作業系統保護可防止受防護的常式訪問屬於數據庫管理器的任何記憶體區域或資源。嚴格來說, SQL 常式不能被隔離,因為它們不“執行”,但它們甚至比不被隔離更好——它們是 DB2 執行時引擎本身執行的字節碼,因此沒有單獨的執行緒或程序。
C 和 C++ 常式可以被隔離,在這種情況下它們在單獨的程序中執行,或者不被隔離,在這種情況下它們被載入到數據庫管理器程序空間並作為函式呼叫。
Java 常式只能通過它們需要一個單獨的程序(Java 虛擬機)來執行這一事實來隔離。如果您將它們聲明為 NOT FENCED,則該選項會被忽略。
說了這麼多,您在受保護和不受保護之間的唯一選擇是使用 C/C++ 常式。通常,為了安全起見,您會執行受保護的模式,僅當您非常確定它們不會損害數據庫管理器並且它們需要更高的性能1時才更改為非受保護模式。
1 - 受保護常式和未受保護常式之間的性能差異來自與分配受保護程序相關的成本,以及與數據庫管理器和未受保護常式之間的程序間通信相關的成本。即使這樣,也不會在每次呼叫受保護常式時都創建受保護程序;將創建一個池並將其重用於此類呼叫。所有這一切意味著,只有在非常頻繁地呼叫該常式(例如每秒數十次或更多次)時,您才可能看到將常式聲明為受保護的好處。