Skip to main content
VillageSQL 扩展框架 (VEF) 以一种明确定义的方式,让扩展能够访问数据库的内部工作机制。PostgreSQL 拥有所有开源数据库中最成熟的扩展框架,因此本页以它作为参照点,让您了解 VEF 当前和计划中的功能。 您应该将本页视为一个快照,而不是最终状态。VEF 会随每个版本发生变化。精确匹配 PostgreSQL 的钩子功能并不是目标。MySQL 和 PostgreSQL 是不同的数据库,其用户的需求通常也不同。

VillageSQL 特有的功能

VEF 提供的某些内容在下面的表格中没有可比较的对象,这或者是因为 MySQL 的构建方式不同,或者是因为 VillageSQL 扩展作者需要一些 PostgreSQL 并未提供给其自身扩展的东西。
  • 密钥环访问——vsql::preview::keyring 允许扩展从服务器的密钥环中读取密钥。
  • 扩展私有文件存储——vsql::preview::storage 为扩展提供了一个受管理的磁盘位置。PostgreSQL 扩展自行管理其文件,没有相应的服务器端 API。
  • 备用协议处理程序——#299 将允许扩展通过 MySQL 线路协议之外的方式为客户端提供服务。
另有两项功能的存在源于 MySQL 的构建方式。二进制日志写入和刷新观察 (#297) 以及复制通道观察 (#341) 都会读取 MySQL 的二进制日志及其多源复制通道。PostgreSQL 通过 WAL 上的逻辑解码及其订阅机制覆盖了类似的领域,这是一种服务于相似目的的不同设计。

如何阅读这些表格

每一个未标记为可用的行都链接到跟踪和讨论该项工作的 GitHub Issue。 任何通过预览功能标记为可用的项都需要 vsql_allow_preview_extensions = ON——请参阅预览功能

C++ 和 Rust

您可以使用 C++ 或 Rust 编写 VillageSQL 扩展。VEF 是服务器端的能力,而每个 SDK 都是它之上的绑定;Rust 绑定较新,因此目前有少数功能仅能从 C++ 访问。

可插拔接口

最知名的 PostgreSQL 扩展是构建在这些接口之上的,而不是构建在下文的钩子之上。它们也是 VEF 覆盖得最完整的框架部分,因此请从这里开始。 _PG_init 不同,on_init()on_deinit() 在扩展内部运行,无法访问服务器。它们适合本地设置,例如选择特定于 CPU 的函数指针。需要与服务器通信的设置则属于某个功能的填充步骤。 vsql::preview::sql_query 有三项限制,会影响任何围绕 SPI 构建的扩展。语句不接受绑定参数,因此必须手动转义值 (#627)。扩展获得的是单个会话,而不是并发会话 (#626)。并且它不能从 VDF 内部调用 (#597)。

钩子变量

钩子是服务器在语句执行过程中将控制权交给扩展的一个点,让扩展能够读取或改变服务器即将执行的操作。PostgreSQL 将一组固定的钩子声明为全局函数指针;下面的表格涵盖了所有这些钩子,并按每个钩子触发所处的查询处理阶段进行分组。

解析和 DDL

规划器

执行器

需要按算子级别细节的 PostgreSQL 扩展,通过在节点级别包装 ExecutorRun_hook 来获得它。在 VEF 中,这是单独的工作,跟踪于 #340

EXPLAIN

身份验证和安全

PostgreSQL 扩展将 ClientAuthentication_hook 用于两种不同的工作,而 VEF 覆盖了其中一种。扩展可以通过 vsql::preview::auth 功能实现自己的身份验证方法,vsql-oauth2 就是基于此构建的。它还不能观察并非由自己处理的身份验证的结果,而 PostgreSQL 的 auth_delay 和失败登录跟踪器正是这样工作的。这部分是 #464 PostgreSQL 通过 pg_ident.conf 而不是钩子,将外部身份映射到数据库账户。VEF 通过同一个 vsql::preview::auth 功能覆盖了这一点:set_active_roles() 允许身份验证插件在解析出外部身份后为会话分配角色,而 auto_grant_roles() 注册一个回调,根据令牌的声明自动授予角色。两者都声明在 villagesql/sdk/include/villagesql/preview/auth.h 中。

日志记录

启动和共享内存

函数管理器

告诉我们您需要什么

我们根据扩展作者的需求来确定这项工作的优先级。如果上面的某一项阻碍了您想要构建的扩展,请为其 Issue 点赞 👍,并在评论中描述您的用例。