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

术语

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

VDF 函数查找

VDF 支持带限定名和无限定名函数调用:
无命名空间函数调用的解析顺序:
  1. 系统函数(内置 MySQL)
  2. VDF(扩展函数)- 仅当存在具有该名称的唯一函数时
  3. 存储函数(使用 CREATE FUNCTION 创建)
**性能:**对于热代码路径,使用有命名空间的调用(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 调试:
检查依赖关系:
常见错误:
  • **未定义的符号:**检查 extern "C" 链接
  • **无法打开共享对象:**检查库依赖关系
  • **VDF 调用时崩溃:**检查 NULL 指针处理

模式验证

在服务器启动时,SchemaManager 会验证系统表模式:
失败场景:
  • 缺少表 → 从 villagesql_schema.sql 创建
  • 错误的模式 → 报错并拒绝启动
  • 版本不匹配 → 运行升级脚本
服务器版本:
源代码构建包含 git 提交哈希值:

后续步骤

创建扩展

构建您的第一个扩展

系统参考

系统表和视图

示例

研究 vsql_complex 实现

管理扩展

监控和故障排除