Skip to main content
了解 VillageSQL 的扩展架构有助于调试问题并在构建扩展时优化性能。 扩展作者的流程很简单:您使用相应的 SDK 编写 C++ 或 Rust 函数,将它们编译成共享库,并将该库与清单打包成 .veb 文件。当您运行 INSTALL EXTENSION 时,VillageSQL 会加载您的库,调用您的注册代码,并立即将您的函数作为 SQL 函数提供——可以从任何查询中调用,就像它们是内置在服务器中的一样。无需重新启动服务器。本页的其余部分解释了该过程的每个步骤是如何工作的。

术语

  • VEB(VillageSQL 扩展包)- .veb 文件格式,一个包含清单、库和元数据的 tar 归档文件
  • VEF(VillageSQL 扩展框架)- 用于编写扩展的 C++ 和 Rust SDK
  • VDF(VillageSQL 定义函数)- 通过 VEF 注册的函数——在 C++ 中通过 VEF_GENERATE_ENTRY_POINTS(),或在 Rust 中通过 extension!

VDF 函数查找

VDF 支持限定和非限定函数调用:
解析顺序:
  1. 系统函数(内置 MySQL)
  2. UDF(传统 MySQL 用户定义函数,通过 CREATE FUNCTION ... SONAME
  3. VDF(扩展函数)- 仅当存在具有该名称的唯一函数时
  4. 存储函数(使用 CREATE FUNCTION 创建)
如果有多个扩展注册了同名函数,则无限定名调用会产生歧义,必须使用完全限定名(extension_name.function_name())。 **性能:**对于热代码路径,使用限定调用(extension_name.function_name())以跳过解析链并直接调用扩展函数。

VEB 文件格式

VillageSQL 扩展以 .veb(VillageSQL 扩展包)文件的形式分发——包含以下内容的 tar 归档文件:

manifest.json 架构

  • **name:**必须与 SQL 中使用的扩展名称匹配(小写字母加下划线)
  • **version:**语义版本(MAJOR.MINOR.PATCH)
  • **description、author、license:**可选元数据

扩展生命周期

安装流程

**回滚:**如果任何步骤失败,所有更改都会撤销,.so 文件将被卸载。 **符号隔离:**扩展使用 RTLD_LOCAL 标志加载,确保一个扩展中的符号不会与另一个扩展中的符号冲突。这可以防止多个扩展使用通用库名称或函数名称时发生命名冲突。
系统变量 veb_dir 指向存储 .veb 扩展文件的目录。

卸载流程

**依赖阻止:**如果表列使用扩展的自定义类型,则无法卸载。

扩展目录结构

VillageSQL 将 .veb 文件解包到 MySQL 数据目录中,以支持多个版本:
为什么使用 SHA256 目录?
  • 测试新版本,而不会覆盖旧版本
  • 启用回滚
  • 防止“相同版本,不同代码”
**清理:**在服务器重新启动时,孤立的 SHA256 目录将被删除。

Victionary 缓存层

VictionaryClient 维护系统元数据的内存缓存,以实现 O(log n) 查找。

缓存操作

**缓存失效:**在 DDL 操作期间自动进行(INSTALL/UNINSTALL EXTENSION)。 **内存开销:**每个条目约为 100 字节。

自定义类型系统

类型解析

实现类型

自定义类型映射到 MySQL 存储类型:

并发性和事务行为

线程安全模型

扩展函数以每行执行模型调用:
  • **隔离的每行执行:**每个函数调用都有自己的结果缓冲区(设计上是线程安全的)
  • **预运行/后运行钩子:**语句级设置/清理,每个 SQL 语句调用一次
  • **不保证隔离:**多个连接可以并发调用您的函数
  • **最佳实践:**避免全局状态;使用函数参数和返回值
VillageSQL 不保证扩展函数的线程隔离。如果您使用全局变量或共享状态,请使用互斥锁或锁来保护它们。

事务行为

扩展函数应遵循以下最佳实践:
  • 尽可能设计函数为无状态的
  • 避免在函数中使用持久性副作用(文件写入、外部 API 调用)
  • 如果使用预运行/后运行状态,请适当处理清理

性能注意事项

**优化:**使用预运行钩子来缓存昂贵的每语句设置,而不是对每一行重复执行。

自定义类型性能


安全性和调试

安全模型

**信任模型:**扩展以完整的服务器权限运行。
  • 没有沙盒或权限系统
  • 扩展可以读取任何文件、访问网络、执行代码
  • **信任影响:**仅从受信任的来源安装扩展
**安装安全性:**作为 villagesql_extension_installer 用户运行(上下文切换)。
启用详细日志:
GDB 调试:
检查依赖关系:
常见错误:
  • **未定义的符号:**使用 ldd(Linux)或 otool -L(macOS)检查库依赖关系
  • **无法打开共享对象:**检查库依赖关系是否存在且正确链接
  • **VDF 调用时崩溃:**检查 NULL 指针处理

后续步骤

创建扩展

构建您的第一个扩展

系统参考

系统表和视图

示例

研究 vsql_complex 实现

管理扩展

监控和故障排除