PgSQL · 內核開發 · 如何管理你的 PostgreSQL 插件
一.背景
我們都知道 PostgreSQL 提供了豐富數據庫內核編程的接口,允許開發者以插件的形式把功能融入數據庫內核。
PostgreSQL 提供了一個插件管理模塊,用於管理用戶創建的插件。
本文給大家介紹 PostgreSQL 插件管理模塊,幫助大家管理自己的插件。
二.PostgreSQL的插件內容
通常一個 PostgreSQL 內核插件包括下麵的部分
- 1. 包含功能的邏輯的動態庫,即 so 文件。
- 2. 描述插件信息的的控製文件,即 control 文件。
- 3. 一組文件用於創建、更新和刪除插件,這是一組按照版本命名的 SQL 文本文件。
如果缺少了上述部分,或版本號不正確,插件的管理功能會異常。
三.插件的管理
我們使用 create extension, drop extension alter extension 管理指定的插件。
1.插件的創建
例如 postgres_fdw 的創建
create extension postgres_fdw;
drop extension postgres_fdw;
我們可以選擇把插件創建到指定的模式中。
2.插件的管理視圖
這是最簡單的部分,創建插件後,我們可以通過插件管理視圖看到一些細節信息
select * from pg_extension ;
extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
--------------+----------+--------------+----------------+------------+-----------+--------------
postgres_fdw | 10 | 2200 | t | 1.0 | |
可以看到,postgres_fdw 的 owner, 存在的 schema 和插件的小版本。
3.插件的刪除
插件的內容可以是任何的數據庫對象,例如:函數、操作符等等。
這些對象可能被其他的對象引用,例如我們在 postgres_fdw 創建了基於 postgres_fdw 的外部表。
當我們要刪除 postgres_fdw 時,需要加上 cascade 子句,把相關對象一並刪除。
drop extension postgres_fdw cascade;
這麼做帶來的問題是,所有依賴這個插件的對象都會被刪除。再次使用需要重建。
4.插件的更新
有時候,我們需要做插件的 BUGFIX ,或定製一些功能。這就用到了插件更新功能。
- 首先,我們需要升級插件的小版本
修改控製文件 .control, 增加一個小版本,如果當前版本是 1.1,則文件中版本號修改成 1.2
- 添加新版本的的 DDL SQL 文件
添加新版本的 DDL SQL 文件 *–1.2.sql, 用於從零創建該插件。
該 SQL 文件應該包括該插件的所有對象的 DDL。
- 添加用戶老版本升級到新版本的 DDL SQL 文件
創建 *1.1–1.2.sql,用於從版本 1.1 升級到 1.2
該 SQL 文件隻包含 1.2 版本中新創建的對象。用戶的升級操作會調用該 SQL 文件,從而避免了完全重新創建。
-
修改源碼添加新的功能,編譯並安裝到指定目錄。
-
使用 SQL 升級小版本
alter extension postgres_fdw update;
如果成功更新,我們能從視圖中看到對應的小版本號被更新了。
postgres=# select * from pg_extension ;
extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
--------------+----------+--------------+----------------+------------+-----------+--------------
postgres_fdw | 10 | 2200 | t | 1.2 | |
(2 rows)
使用 PostgreSQL 的插件管理功能,用戶很容開發和維護需要的插件。
其他
有幾點需要特別提醒,這是在開發和管理插件時,經常碰到的問題,需要多加注意
- 插件是通過動態庫形式引入到內核中。和內核在同一個進程中運行,且沒有內存保護,影響內核的穩定性。開發中需要特別注意內存的使用。不要造成內存泄露或越界寫。建議使用 PostgreSQL 的內存管理機製,插件中也能使用。
- 內核中被標記成 PGDLLIMPORT 的全局變量都能在插件中直接使用,這些通常是一些 GUC 參數。
- 內核中非 static 的函數也能在插件中使用,隻需要先 extern 它們。
- 我們可以實現 _PG_init 用於實現一些初始化工作,該函數在連接建立後隻會被執行一次。
- 我們可以在 _PG_init 中使用函數 DefineCustom*Variable 定義對應插件相關的 GUC 參數,他們可以用於開啟和關閉該插件的一些功能。
- 插件的參數需要以插件名開頭且加上點,例如 oss_fdw.enable_parallel_read。
參考
最後更新:2017-10-21 09:04:28