PostgreSQL create extenstion 创建扩展逻辑分析

PostgreSQL 支持 create extenstion 语法创建扩展,扩展能够很方便地将第三方开发的插件集成到 PostgreSQL 数据库中,比如时序数据库 timescaledb 就是作为 PG 的一个扩展集成到数据库系统中,让 PG 能够支持更加强大的时序数据的存储与查询能力。

使用 psql 连接到 pg server,执行创建扩展的语句,如下:

CREATE EXTENSION timescaledb;

上述创建扩展的语句,在 PG 源码中的函数调用关系如下:

PostgresMain()
  ->exec_simple_query()
    ->PortalRun()
      ->PortalRunMulti()
        ->PortalRunUtility()
          ->ProcessUtility()
            ->loader_process_utility_hook() 位于 timescaledb
              ->standard_ProcessUtility()
                ->ProcessUtilitySlow()
                  ->CreateExtension()
                    ->CreateExtensionInternal()

在 ProcessUtility() 函数中,调用 loader_process_utility_hook() 函数,该函数位于 /home/pg/git/timescaledb/src/loader/loader.c:475,属于 timescaledb 实现,这个 hook 函数是在 PG 启动时调用 _PG_init()函数进行 hook 的,源码位于 timescaledb 的 loader/loader.c

loader_process_utility_hook() 函数对执行 drop database 语句时做一些检查,然后回到 PG 标准的函数 standard_ProcessUtility()中。

timescaledb 的函数能够被调用,主要是 PG 提供了一些全局钩子函数,在某些动作完成之后,调用这些全局钩子函数,扩展在实现时只需要将全局钩子函数替换成自己的函数实现即可,比如下面的全局钩子函数 ProcessUtility_hook ,PG 中类似这们的全局钩子 hook 还有很多。

/* Hook for plugins to get control in ProcessUtility() */
ProcessUtility_hook_type ProcessUtility_hook = NULL;

CreateExtension() 函数会做一些检查,比如扩展是否已安装。调用 get_extension_oid() 根据扩展名称查已安装扩展表,检查扩展是否已安装。

CreateExtensionInternal()函数是创建扩展的最终逻辑实现的地方,它的主要逻辑如下:

  1. 读取扩展控制文件 timescaledb.control,位于 /opt/app/postgresql13/share/extension 目录中。
  2. 获取扩展脚本文件名,通常是一个 sql 文件,调用函数 get_extension_script_filename() 获取,比如:/opt/app/postgresql13/share/extension/timescaledb--2.4.0-dev.sql。
  3. 调用 InsertExtensionTuple() 插入元数据表 pg_extension,依赖关系表 pg_depend。
  4. 调用 CreateComments() 插入描述信息表 pg_description。
  5. 调用 execute_extension_script() 执行安装扩展的脚本文件。文件名:/opt/app/postgresql13/share/extension/timescaledb--2.4.0-dev.sql
  6. 调用 ApplyExtensionUpdates() 执行额外的扩展更新脚本文件,也可能没有该额外的扩展更新文件。

经过以上这些步骤之后,扩展被正式创建完成。

注:PostgreSQL 源码版本:14

文章评论

0条评论