PostgreSQL 對於 C 語言編寫的函數(包括其餘與 C 語言兼容的語言,如 C++、Rust 等),是動態裝載的,用 CREATE FUNCTION
建立完函數後,並不會當即裝載,而是有鏈接創建以後,客戶端第一次調用時纔會進行裝載,並且是裝入到會話進程的內存裏面去了。這時候,就算咱們把 .so 文件刪除,若是會話以前已調過一次函數的話,客戶端仍是能夠繼續調用函數的。sql
若是咱們改寫了函數代碼,從新生成了 .so 文件,把新的 .so 文件覆蓋老版本的 .so 文件,這時候在已有的會話裏調用函數的話,有時候會報函數版本錯誤「ERROR unrecognized function API version, sql status: XX000」;有時候更嚴重,會致使當前會話的進程 Segment Fault,致使整個 PostgreSQL 崩潰而重啓。這時候就算用 CREATE OR REPLACE FUNCTION
來從新裝載函數也不行,也會致使 PostgreSQL 重啓。函數
惟一可行的解決方案就是把 .so 文件版本化,每一個編譯出來的 .so 文件加上版本號,每一個版本的文件都不一樣,把新版本的文件拷到 PKGLIBDIR 下,再用 CREATE OR REPLACE FUNCTION
替換掉老版本的函數,這樣就算在已創建的會話裏調用時,也是調的新版本的函數了。老版本的 .so 文件也能夠刪除了。code