海山数据库(He3DB)源码解读:CREATE EXTENSION原理浅析

一、插件的基本组成

   在 He3DB 中,插件(或称扩展)是一种可扩展的机制,允许用户增加数据库的功能。每个插件的基本组成部分如下:
   (1)控制文件(.control 文件):
   位置:通常位于 $PGSHARE/extension/ 目录中。
   内容:控制文件定义了插件的元数据,包括名称、默认版本、兼容版本、SQL 脚本路径等。它的结构是键值对格式,常见字段包括:
   name:插件名称。
   default_version:默认版本号。
   comment:描述信息。
   relocatable:是否可以重新定位,即插件是否可以安装到不同的 schema 中。
   requires:插件依赖的其他插件列表。
   module_pathname:共享库文件的路径。
   schema:安装插件时默认的 schema。
   (2)SQL 脚本文件:
   位置:通常位于 $PGSHARE/extension/ 目录中,文件名通常为 extension–version.sql 。
   内容:SQL 脚本文件定义了插件在数据库中的对象,例如函数、视图、数据类型、操作符等。这些 SQL 脚本在安装插件时会被执行。
   (3)源码文件(.c).c 文件包含扩展的实现代码,通常用 C 或 C++ 编写。它定义了扩展中的函数、操作符等。
   (4)Makefile 文件Makefile 文件用于定义如何编译和链接扩展。它通常包括编译选项、目标文件和链接规则。

二、CREATE EXTENSION 命令的执行流程

CREATE EXTENSION 命令用于安装和初始化插件。以下是该命令的详细执行流程:

  1. 语法解析与检查:He3DB 解析 CREATE EXTENSION 命令,检查插件名称、版本和选项是否合法。如果指定了 SCHEMA选项,系统会验证该 schema 是否存在。

  2. 检查插件是否已存在:系统查询 pg_extension 表,检查插件是否已安装。如果插件已存在,系统将返回一个错误(除非使用 IF NOT EXISTS 选项)。

  3. 读取控制文件:在 pg_available_extensions 目录中搜索与插件名称匹配的 .control
    文件,并读取其中定义的元数据。系统检查 default_version字段以确定要安装的插件版本。如果用户未指定版本,系统使用默认版本。

  4. 检查依赖关系:根据控制文件中的 requires 字段,系统检查所有依赖插件是否已经安装。如果依赖的插件未安装,系统将返回一个错误。系统还会检查插件是否可以重新定位(relocatable),如果插件不可重新定位但指定了 SCHEMA 选项,则会返回错误。

  5. 加载共享库:如果插件需要共享库(即 .so 文件), 会通过 module_pathname 加载该库。 加载时,系统会调用共享库中的_PG_init() 函数(如果存在)进行初始化。

  6. 执行 SQL 脚本: 执行与插件版本对应的 SQL 脚本文件,以创建和初始化插件的数据库对象。 这些脚本文件可以包含任何有效的 SQL语句,如创建函数、数据类型、视图等。

  7. 记录插件信息:系统在 pg_extension 表中记录插件的安装信息,包括名称、版本、安装 schema、依赖关系等。如果插件的schema 被更改,系统会更新 pg_extension 表中的相关信息。

  8. 插件初始化:某些插件在安装过程中可能需要执行自定义的初始化步骤,这通常通过共享库中的数或 SQL 脚本来完成。

  9. 返回结果:安装成功后,CREATE EXTENSION 命令会返回一个成功消息,表明插件已正确安装并可以使用

三、插件的使用和管理

1.使用插件:
在 He3DB 中,插件(扩展)安装后可以直接使用。例如,假设我们安装了前述的 my_extension 扩展:
– 安装扩展

CREATE EXTENSION my_extension;

– 使用扩展中的函数

SELECT my_function(10);

2.管理插件:
查看已安装扩展

SELECT * FROM pg_available_extensions;

卸载扩展

DROP EXTENSION my_extension;

更新扩展
更新扩展通常涉及到重新编译扩展并更新版本号。例如,修改 my_extension.control 和 .sql 文件后,执行:

ALTER EXTENSION my_extension UPDATE TO '1.1';

四、使用示例(C++ 函数使用案例)

  1. 编写 C++ 函数
    示例:my_cpp_extension.cpp
#include "postgres.h"
#include "fmgr.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

extern "C" {
    PG_FUNCTION_INFO_V1(my_cpp_function);

    Datum
    my_cpp_function(PG_FUNCTION_ARGS)
    {
        int32 arg = PG_GETARG_INT32(0);
        PG_RETURN_INT32(arg * 2);
    }
}

2.编写对应的 SQL 文件

CREATE FUNCTION my_cpp_function(INTEGER) RETURNS INTEGER AS 'MODULE_PATHNAME', 'my_cpp_function'
LANGUAGE C;
  1. 编写 Makefile
MODULES = my_cpp_extension
EXTENSION = my_cpp_extension
DATA = my_cpp_extension--1.0.sql

PG_CONFIG = pg_config
PG_CXX = g++

CXXFLAGS += -I$(shell $(PG_CONFIG) --includedir-server)

LDFLAGS = -L$(shell $(PG_CONFIG) --libdir)
LIBS = -lpq

OBJS = my_cpp_extension.o

my_cpp_extension.o: my_cpp_extension.cpp
	$(PG_CXX) $(CXXFLAGS) -fPIC -c -o $@ $<

my_cpp_extension.so: $(OBJS)
	$(PG_CXX) $(LDFLAGS) -shared -o $@ $^ $(LIBS)

PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
  1. 编写.control文件
# my_extension.control
comment = 'An example PostgreSQL extension'
default_version = '1.0'
module_pathname = '$libdir/my_extension'
relocatable = true

将 .control 文件放在扩展的目录中,与其他文件(如 .sql、.c、Makefile)同级。

编译和安装扩展:在 PostgreSQL 数据目录中运行 make 和 make install,编译扩展并将其安装到 PostgreSQL 的扩展目录中。

make
make install

在 He3DB 中使用

CREATE EXTENSION my_cpp_extension;
SELECT my_cpp_function(5);

作者介绍

张杰,移动云数据库工程师,负责云原生数据库He3DB的研发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值