百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

PostgreSQL引入插件EXTENSION的常用方法

yuyutoo 2024-10-17 16:59 4 浏览 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

相关推荐

史上最全的浏览器兼容性问题和解决方案

微信ID:WEB_wysj(点击关注)◎◎◎◎◎◎◎◎◎一┳═┻︻▄(页底留言开放,欢迎来吐槽)●●●...

平面设计基础知识_平面设计基础知识实验收获与总结
平面设计基础知识_平面设计基础知识实验收获与总结

CSS构造颜色,背景与图像1.使用span更好的控制文本中局部区域的文本:文本;2.使用display属性提供区块转变:display:inline(是内联的...

2025-02-21 16:01 yuyutoo

写作排版简单三步就行-工具篇_作文排版模板

和我们工作中日常word排版内部交流不同,这篇教程介绍的写作排版主要是用于“微信公众号、头条号”网络展示。写作展现的是我的思考,排版是让写作在网格上更好地展现。在写作上花费时间是有累积复利优势的,在排...

写一个2048的游戏_2048小游戏功能实现

1.创建HTML文件1.打开一个文本编辑器,例如Notepad++、SublimeText、VisualStudioCode等。2.将以下HTML代码复制并粘贴到文本编辑器中:html...

今天你穿“短袖”了吗?青岛最高23℃!接下来几天气温更刺激……

  最近的天气暖和得让很多小伙伴们喊“热”!!!  昨天的气温到底升得有多高呢?你家有没有榜上有名?...

CSS不规则卡片,纯CSS制作优惠券样式,CSS实现锯齿样式

之前也有写过CSS优惠券样式《CSS3径向渐变实现优惠券波浪造型》,这次再来温习一遍,并且将更为详细的讲解,从布局到具体样式说明,最后定义CSS变量,自定义主题颜色。布局...

柠檬科技肖勃飞:大数据风控助力信用社会建设

...

你的自我界限够强大吗?_你的自我界限够强大吗英文

我的结果:A、该设立新的界限...

行内元素与块级元素,以及区别_行内元素和块级元素有什么区别?

行内元素与块级元素首先,CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,分别为块级(block)、行内(inline)。块级元素:(以下列举比较常...

让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华
让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华

去年的两会期间,习近平总书记在参加人大会议四川代表团审议时,对治蜀兴川提出了明确要求,指明了前行方向,并带来了“祝四川人民的生活越来越安逸”的美好祝福。又是一年...

2025-02-21 16:00 yuyutoo

今年国家综合性消防救援队伍计划招录消防员15000名

记者24日从应急管理部获悉,国家综合性消防救援队伍2023年消防员招录工作已正式启动。今年共计划招录消防员15000名,其中高校应届毕业生5000名、退役士兵5000名、社会青年5000名。本次招录的...

一起盘点最新 Chrome v133 的5大主流特性 ?

1.CSS的高级attr()方法CSSattr()函数是CSSLevel5中用于检索DOM元素的属性值并将其用于CSS属性值,类似于var()函数替换自定义属性值的方式。...

竞走团体世锦赛5月太仓举行 世界冠军杨家玉担任形象大使

style="text-align:center;"data-mce-style="text-align:...

学物理能做什么?_学物理能做什么 卢昌海

作者:曹则贤中国科学院物理研究所原标题:《物理学:ASourceofPowerforMan》在2006年中央电视台《对话》栏目的某期节目中,主持人问过我一个的问题:“学物理的人,如果日后不...

你不知道的关于这只眯眼兔的6个小秘密
你不知道的关于这只眯眼兔的6个小秘密

在你们忙着给熊本君做表情包的时候,要知道,最先在网络上引起轰动的可是这只脸上只有两条缝的兔子——兔斯基。今年,它更是迎来了自己的10岁生日。①关于德艺双馨“老艺...

2025-02-21 16:00 yuyutoo

取消回复欢迎 发表评论: