PostgreSQL引入插件EXTENSION的常用方法
yuyutoo 2024-10-17 16:59 11 浏览 0 评论
作者:北研 火昊 (华宇研发)
前言
PostgreSQL 的一个重要功能就是支持以插件的形式引入新的功能。本文希望通过几个示例,说明如何创建并引入额外的插件。
因此,本文的主要内容包括:
?基础篇:是介绍如何将一个外部的插件引入 ArteryBase 数据库中
?进阶篇一:是介绍如何自定义实现一个插件,方便快速引入一套常用的 SQL 函数
?进阶篇二:是介绍如何将 C 语言实现的函数通过插件的形式引入数据库中
实验环境
名称版本操作系统CentOS 6.5
数据库ArteryBase-6.0.1(PostgreSQL-11.1)
插件引入
其实引入一个外部插件,仅需要如下几步:
1.一键安装的 ArteryBase 数据库
2.下载插件(源码)包
3.编译插件
4.引入数据库中
即:我们无需下载并重新编译 PostgreSQL 数据库源码,即可把外部插件编译引入到 ArteryBase 数据库中。
基础篇之引入外部插件
这里以插件 pg_hint_plan 为例,介绍如何引入该插件到 abase 中。
?pg_hint_plan :可用于指定执行计划中的扫描方式、表连接方式、表连接顺序等,对 DBA 进行 SQL 调优有一定的帮助。
?官网地址:https://pghintplan.osdn.jp/pg_hint_plan.html
?源码地址:https://github.com/ossc-db/pg_hint_plan
具体步骤如下:
1.安装 ArteryBase 数据库,以默认配置进行后续的插件安装过程
2.下载插件源码,并解压(任意位置即可,以 /home/thunisoft 为例,该路径要求数据库 owner 用户可操作)
# 由于目标库对应的PG版本为 11.1,这里选择对应版本的源码包
# 使用数据库owner用户进行如下操作,以 thunisoft 为例
$ wget https://github.com/ossc-db/pg_hint_plan/archive/REL11_1_3_4.tar.gz
$ tar -xf REL11_1_3_4.tar.gz
3.进入解压文件夹下,编译插件源码:
$ cd pg_hint_plan-REL11_1_3_4/
# 编译
$ USE_PGXS=1 make && make install
4.引入 abase 目标库中,该插件需要以 shared_preload_libraries 的形式加载,执行如下 SQL 后重启数据库生效:
-- 客户端工具为psql
-- create extension 方式引入该插件所需的管理表
abase=# create extension pg_hint_plan ;
CREATE EXTENSION
abase=# \dx+ pg_hint_plan
Objects in extension "pg_hint_plan"
Object description
-----------------------------
表 hint_plan.hints
序列 hint_plan.hints_id_seq
(2 rows)
-- shared_preload_libraries 方式装载在数据库应用上
-- 并非所有插件均需此项配置,请根据对应文档操作
abase=# alter system set shared_preload_libraries = 'pg_hint_plan';
ALTER SYSTEM
重启后即可使用该插件的功能,后续不再需要时,可快速卸载,方便易用。
其中,编译环节设定 USE_PGXS=1 的说明:
?插件 pg_hint_plan 源码编译时,依赖 abase 的 lib 库和 include 库,因此编译时必须引导插件找到 abase 的应用程序安装路径。对于多数插件编译而言,在不修改源码包 Makefile 文件的前提下,有两种途径可以让插件正常编译安装:
?1、编译时加参数 USE_PGXS=1 ,此时 Makefile 会通过 abase 自带命令 pg_config 来查找 lib 库和 include 库的位置,而命令 pg_config 已默认加载在数据库 owner 的 PATH 环境变量中,可直接使用。
?2、下载数据库源码,将源码包放置于数据库源码的 contrib 文件夹下,优先编译数据库后,再编译该插件源码(只需要执行 make && make install 即可)。
进阶版--创建插件EXTENSION(无C程序版)
这里我们演示如何自定义创建一个名为 "common_func" 的插件,插件用于引入自己写的常用 SQL 函数,方便管理,这样我们就可以在需要的地方随时安装、卸载。
?当然,我们也可以通过引入插件的形式向创建目标库创建一些表、视图等数据库对象。
?对于大量的数据库对象创建操作,通过插件引入,方便管理,且无数据库版本限制。
创建一个基础的插件,只需要如下三个文件即可:
common_func--1.0.sql common_func.control Makefile
具体步骤如下:
1.首先,我们需要一个安装好的 Abase 数据库,不限版本
2.切换到数据库 owner 用户下,以 thunisoft 为例,创建一个文件夹
$ mkdir common_func
$ cd common_func/
3.创建一个 common_func.control 文件(命名与插件名保持一致即可),该文件用于指导数据库识别当前 EXTENSION 版本号,创建所属 SCHEMA 等信息,是所有 EXTENSION 必不可少的部分:
# 文件内容大致如下
$ cat common_func.control
# common function extension
# provide by hh
comment = 'Provide some commonly used functions'
default_version = '1.0'
module_pathname = '$libdir/common_func'
relocatable = true
4.创建一个 Makefile 文件,用于后续将 EXTENSION 的文件快速部署。
#文件内容如下:
EXTENSION = common_func
DATA = common_func--1.0.sql
PGFILEDESC = "common_func -- Provide some commonly used functions"
REGRESS = common_func
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/common_func
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
5.由于本次示例中,我们仅打算创建一个包含函数的插件,所以,在文件夹根目录下,创建一个 common_func--1.0.sql 即可,该文件的文件名分为两部分:
?"common_func" :代表插件名
?"1.0" :代表版本号,这个用于后续插件升级。例如我们引入了2.0版本,则可以创建一个 common_func--2.0.sql (用于直接安装2.0版本的该插件),创建一个 common_func--1.0--2.0.sql (用于将1.0版本的插件升级为2.0版本,遵循 extension--oldversion--newversion.sql 命名原则)
SQL 文件内容如下:
\echo Use "CREATE EXTENSION char_count" to load this file. \quit
create function fn_int(int)
returns int as
$ begin return $1; end;$
language plpgsql stable;
6.之后,我们执行如下命令,即可将插件的相关文件拷贝至数据库应用文件夹下:
USE_PGXS=1 make install
7.此时,该插件相关文件已引入数据库应用中。如需使用,只需要在目标库中执行命令即可:
CREATE EXTENSION common_func;
进阶版--创建插件EXTENSION(引入C程序版)
这里就简单写一个 C 程序,程序引入一个函数 config_limits,用于输出数据库中的几项限制信息:
插件 c_extension 共需创建如下几个文件:
$ ls
c_extension--1.0.sql c_extension.c c_extension.control Makefile
其中,control 文件内容如下:
# c_extension extension
comment = 'show some limits of postgresql'
default_version = '1.0'
module_pathname = '$libdir/c_extension'
relocatable = true
sql 文件内容如下:
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION c_extension" to load this file. \quit
-- config_limits()
CREATE FUNCTION config_limits(
OUT pg_version text,
OUT block_size int4,
OUT name_maxlen int4, -- Maximum length for identifiers (e.g. table names, column names, function names)
OUT func_max_args int4, -- Maximum number of arguments to a function
OUT index_max_keys int4, -- Maximum number of columns in an index
OUT partition_max_key int4 -- Maximum number of columns in a partition key
)AS 'MODULE_PATHNAME', 'config_limits'
LANGUAGE C IMMUTABLE PARALLEL SAFE;
c 程序内容如下:
#include "postgres.h"
#include "fmgr.h"
#include "utils/builtins.h"
#include "utils/rel.h"
#include "funcapi.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(config_limits);
Datum
config_limits(PG_FUNCTION_ARGS)
{
Datum result;
TupleDesc tupleDesc;
int j;
char *values[6];
HeapTuple tuple;
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
j = 0;
values[j++] = psprintf("%s", PG_VERSION);
values[j++] = psprintf("%d", BLCKSZ);
values[j++] = psprintf("%d", NAMEDATALEN);
values[j++] = psprintf("%d", FUNC_MAX_ARGS);
values[j++] = psprintf("%d", INDEX_MAX_KEYS);
values[j++] = psprintf("%d", PARTITION_MAX_KEYS);
tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupleDesc),
values);
result = HeapTupleGetDatum(tuple);
PG_RETURN_DATUM(result);
}
Makefile 文件内容如下:
MODULES = c_extension
EXTENSION = c_extension
DATA = c_extension--1.0.sql
PGFILEDESC = "c_extension - show some limits of postgresql"
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/c_extension
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
插件引入数据库中之后,使用示例如下:
abase=# create extension c_extension ;
CREATE EXTENSION
abase=# select * from config_limits();
pg_version | block_size | name_maxlen | func_max_args | idex_max_keys | partition_max_key
------------+------------+-------------+---------------+---------------+-------------------
11.1 | 8192 | 64 | 100 | 32 | 32
(1 row)
?pg_version:数据库内核对应的 postgresql 版本
?block_size:BLOCK 块的大小,8K
?name_maxlen:数据库一些对象名支持的最大长度,例如表名、字段名、函数名等
?func_max_args:函数支持的最多参数项个数
?index_max_keys:组合索引支持设定最多字段个数
?partition_max_key:分区键支持设定最多字段个数
补充
介绍 control 文件各参数含义:
https://mmbiz.qpic.cn/mmbiz_png/bRS7HnFhibB8wK9rj8ZvdNR2UHzETxhZLoSEfkdTOXDthxscR5P8pSmBZfGNVqFZZGCibDG7AmTHYyQZ9cCmHDGg/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1
介绍 Makefile 文件各参数含义:
https://mmbiz.qpic.cn/mmbiz_png/bRS7HnFhibB8wK9rj8ZvdNR2UHzETxhZLJsPwDqweMRoD0L9HJDWIvaVxL2B0qvR5a0oCueic4k2iaib5JrPnNnGzw/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1
Makefile 文件最底部几行,作用在于帮助找到PG的PGHOME路径,通常只需要修改 subdir 一项,其他直接拷贝即可。这几行的含义是:
1.我们编译(make 或 make install)时,如果不加 USE_PGXS=1 ,则认为本文件夹放在了 subdir 路径下,这通常是我们把插件放在PG的源码 contrib 路径下编译,往上返回两层即为 PGHOME
2.否则,则通过环境变量中查找 pg_config 命令 (通常在 PGHOME/bin 路径下,如果是abase默认安装,本命令可直接使用),通过 pg_config 来查找 PGHOME
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/char_count
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
相关推荐
- MyBatis的SQL执行流程不清楚?看完这一篇就够了
-
推荐学习真香警告!Alibaba珍藏版mybatis手写文档,刷起来...
- SpringBoot开发必备!49个内置工具类,让你的代码效率翻倍!
-
作为一名Java开发者,你是否经常为字符串处理、文件操作、数据验证等重复性代码头疼?SpringBoot的武器库里藏着...
- C# 基于命名管道(Named Pipes) 的进程间通信(IPC)
-
基于命名管道(NamedPipes)的进程间通信(IPC),用于在同一台机器不同进程之间进行高效、可靠的数据传输,是一种基于消息或流的通信机制。管道有一个唯一的名称,客户端和服务器端通过名称连接到...
- 十年之重修MyBatis原理(mybatis方法重载)
-
弱小和无知并不是生存的障碍,傲慢才是。--------面试者...
- C#串口通信(c#串口通信界面)
-
串口通信(SerialCommunications)是指外设和计算机间通过数据信号线、地线等按位(bit)进行传输数据的一种通信方式,属于串行通信方式,能够实现远距离通信,长度可达1200米。尽管比...
- C#中使用命名管道进行进程通信的实例
-
1新建解决方案NamedPipeExample...
- 继GitHub之后 OpenAI为ChatGPT推出OneDrive和SharePoint连接器
-
上周,OpenAI宣布推出ChatGPT的GitHub连接器,允许用户对其源代码库进行深入研究。将GitHub与ChatGPT连接后,用户可以提出问题,深度研究代理将读取和搜索存储库的...
- Power BI:如何在SharePoint中嵌入Power BI报告?
-
问题描述:今天业务同事来询问如何才能将自己开发的PowerBI报告嵌入团队使用的SharePoint页面中,以更直观地和团队成员分享可视化报告。(SharePoint是微软推出的可以用来存储、整理、...
- O365(世纪互联)SharePoint 之调查列表简单介绍
-
前言SharePoint中为了提供了很多开箱即用的应用程序,比如调查列表就是其中之一,同样,在O365版本里(国际版和世纪互联版本均可),也有这样的调查列表可以供我们使用,而使用起来非常方便和快速,就...
- 制作Excel电子表格必备的:Excel 2021 mac中文版
-
MicrosoftExcel2021forMac是一款运行在Mac平台上的办公软件,OfficeExcel2021forMac中文版是办公必不可少的软件,主要用于制作电子表格等,这里带...
- 微软SharePoint新特性:能以邮件方式向目标发送新闻内容
-
IT之家8月30日消息,微软今天发布新闻稿,宣布为SharePoint服务引入新特性,允许企业将新闻动态转换为电子邮件,并以时事通讯、安全公告、警告等主题发送给感兴趣的用户。微软在新闻稿中...
- 在Access中创建Sharepoint列表的链接表
-
在Access中提供了一个DoCmd.TransferSharePointList方法,一行代码就可以搞定。使用TransferSharePointList方法从SharePointFoun...
- BBC推荐:12月最值得一看的5部电影 Five films to watch in December
-
年终岁末,还有哪些精彩电影在等着我们呢?迪士尼的《欢乐满人间2》绝对是合家欢电影的首选,超级英雄迷们将能看到索尼动画《蜘蛛侠:平行宇宙》,福尔摩斯的粉丝们千万别错过《福尔摩斯与华生》。还有朱莉亚·罗伯...
- 基于锂离子电池的电池荷电状态 (SOC) 和运行健康状态 (SOH) 估计技术
-
简介基于锂离子(Li-ion)电池单元的电池组广泛用于各种应用,例如:混合动力汽车(HEV)、电动汽车(EV)、可供日后使用的再生能源储存以及用于各种目的(电网稳定性、调峰和再生能源时移等)的...
- 深入解析电池充电状态 (SOC) 和运行状态 (SOH) 估计技术
-
基于锂离子(Li-ion)电池单元的电池组广泛用于各种应用,例如:混合动力汽车(HEV)、电动汽车(EV)、可供日后使用的再生能源储存以及用于各种目的(电网稳定性、调峰和再生能源时移等)的电网...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- MyBatis的SQL执行流程不清楚?看完这一篇就够了
- SpringBoot开发必备!49个内置工具类,让你的代码效率翻倍!
- C# 基于命名管道(Named Pipes) 的进程间通信(IPC)
- 十年之重修MyBatis原理(mybatis方法重载)
- C#串口通信(c#串口通信界面)
- C#中使用命名管道进行进程通信的实例
- 继GitHub之后 OpenAI为ChatGPT推出OneDrive和SharePoint连接器
- Power BI:如何在SharePoint中嵌入Power BI报告?
- O365(世纪互联)SharePoint 之调查列表简单介绍
- 制作Excel电子表格必备的:Excel 2021 mac中文版
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)