PostgreSQL extension扩展模块解析

PostgreSQL extension扩展模块解析

extension是什么

extension是PostgreSQL的扩展模块,用于扩展PostgreSQL本身所欠缺的功能。

为什么创建extension
1. 受众人群较少
2. 快速实现所需功能
3. 代码质量未经严格审核测试

从哪里获得extension

PostgreSQL源码的contrib目录下
pgxn:https://pgxn.org/
github:很多项目获取

extension缺陷

  1. 代码质量与PostgreSQL相比稍有欠缺
  2. 版本更新不及时,存在版本适配问题
  3. 维护者较少
  4. 没有严格的测试

extension编写指南

extension编译模式

模式由Makefile的关键字进行配置

  • 单文件模式
    MODULES

  • 多文件模式
    MODULE_big,对象文件使用OBJS

  • 可执行模式
    PROGRAM

extension编译关键字

  • EXTENSION
    extension的名字

  • MODULEDIR
    extension模块的名字,默认安装到share/extension下

  • DATA
    安装到share/$MODULEDIR下的文件

  • DATA_built
    安装到share/$MODULEDIR下的文件,会先构建MODULEDIR目录

  • DATA_TSEARCH
    安装到share/tsearch_data下的文件

  • DOCS
    安装到doc/$MODULEDIR下的文件

  • HEADERS
    安装到include/server/$MODULEDIR/$MODULE_big下的头文件

  • HEADERS_built
    同HEADERS,需要先构建目录

  • HEADERS_$MODULE

  • HEADERS_built_$MODULE
    安装到include/server/$MODULEDIR/$MODULE下的头文件

  • SCRIPTS

  • SCRIPTS_built
    安装到bin下的脚本文件,非二进制需要编译的文件

  • REGRESS
    回归测试用例列表

  • REGRESS_OPTS
    传递给pg_regress的参数

  • ISOLATION
    传递给隔离测试的用例列表

  • ISOLATION_OPTS
    传递给pg_isolation_regress的参数

  • NO_INSTALLCHECK
    不用定义installcheck的目标

  • EXTRA_CLEAN
    make clean清理的文件

  • PG_CPPFLAGS
    传递给CPPFLAGS的参数

  • PG_CFLAGS
    传递给CFLAGS的参数

  • PG_CXXFLAGS
    传递给CXXFLAGS的参数

  • PG_LDFLAGS
    传递给LDFLAGS的参数

  • PG_LIBS
    PROGRAM 的库连接

  • SHLIB_LINK
    MODULE_big的库连接

  • PG_CONFIG
    pg_config的路径

extension 控制文件

  • directory
    SQL脚本文件目录,绝对路径或相对于SHAREDIR目录,默认为extension目录

  • default_version
    extension默认安装的版本

  • comment
    注释

  • encoding
    SQL脚本文件使用的字符集编码。默认数据库编码

  • module_pathname
    参数的值将替换脚本文件中的MODULE_PATHNAME

  • requires
    此扩展所依赖的扩展名列表requires = ‘foo, bar’。必须先安装这些扩展,然后才能安装此扩展。

  • superuser
    如果此参数是true(默认值),则只有超级用户可以创建扩展或将其更新为新版本

  • relocatable
    重定位到不同的模式中,默认false

  • schema
    所建对象的模式

extension配置表

通常,如果表是extension的一部分,则表的定义及其内容都不会被pg_dump出来。但是这种行为对于一些做配置的表是不合理的。

  • pg_dump 备份方法
    SELECT pg_catalog.pg_extension_config_dump(‘table or seq’, ‘where query‘)
    表的定义和数据都会被dump出来。此函数仅在create extension时的脚本文件中使用。

extension版本更新安装

版本更新安装采用最短路径的方式。如下文件存在时,安装2.0会直接使用cloud–2.0.sql

cloud–2.0.sql
cloud–1.0.sql
cloud–1.0–2.0.sql

  • 版本有向图
    版本中的数字没有任何意义,只是在建图的时候有用

版本组成:
1. extname–ver1.sql
2. extname–ver1–tover2.sql

建图:
ver1图(可安装),建立可达tover2的图
tover2图(不可安装)

建立路径:
从可安装图开始查找,依次找到目标版本

extension内部实现原理

钩子函数

钩子函数是PostgreSQL预留的接口,通过重新编写的钩子函数可以改变postgresql的默认功能,

钩子函数通常以hook最为结尾,PostgreSQL预留了非常丰富的接口。

示例:
ExecutorStart_hook
ExecutorRun_hook
ExecutorFinish_hook
ExecutorEnd_hook

自定义接口

通过PostgreSQL提供的扩展SQL实现

示例:
CREATE TYPE
CREATE FUNC
CREATE TEXT SEARCH PARSER

C函数

使用C语言可以获得PostgreSQL的头文件,结构体,变量等,可以获取数据库内部的信息,实现非常复杂的功能

示例:
CREATE FUNCTION zhprs_end(internal)
RETURNS void
AS ‘MODULE_PATHNAME’
LANGUAGE C STRICT;

extension组成

extension 通常由如下3个文件组成

  1. 控制文件
    参考:extension 控制文件

  2. 脚本文件(sql)
    参考: 自定义接口

  3. 动态库
    参考:C函数

动态库控制文件的加载有4种情况
1. 不使用任何PostgreSQL的hook
2. 服务器启动时需要加载hook的库,配置到shared_preload_libraries
3. 与服务器建立连接时加载hook的库,配置到session_preload_libraries,只允许超级用户修改
4. 与服务器建立连接时加载hook的库,配置到local_preload_libraries,只能加载libdir/plugins下的库,普通用户可以修改

extension语法

  • 创建
CREATE EXTENSION [ IF NOT EXISTS ] extension_name
    [ WITH ] [ SCHEMA schema_name ]
             [ VERSION version ]
             [ FROM old_version ]
             [ CASCADE ]

CASCADE:
    递归安装依赖的extension
VERSION:
        指定安装的版本,默认为control版本
FROM:
    从哪个版本开始安装
SCHEMA:
    安装到哪个模式下

创建extension时会在pg_extension建立pg_depend关系

  • 更新
ALTER EXTENSION name UPDATE [ TO new_version ]
ALTER EXTENSION name SET SCHEMA new_schema
ALTER EXTENSION name ADD member_object
ALTER EXTENSION name DROP member_object

member_object:TABLE/FUNCTION/TYPE等
  • 删除
DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
CASCADE:
    递归删除依赖  

删除extension时会根据pg_depend的关系递归删除extension建立的对象

demo

postgresql_extension_DEMO

总结

extension模块的实现并不复杂,但是非常强大实用,其中版本升级这个有向图做的非常好。

文章浏览总量 2,526 次

要发表评论,您必须先登录