查看已安装的扩展
使用 INFORMATION_SCHEMA 视图查询已安装的扩展:- 可以在交互式会话和脚本中使用
- 标准 SQL 接口,与 MySQL 工具兼容
检查扩展函数
验证扩展函数在安装后是否正常工作:扩展目录
检查 VillageSQL 查找.veb 文件的位置:
配置 veb_dir
要更改扩展目录的位置,请在 MySQL 配置文件中设置veb_dir:
my.cnf / my.ini:
- 路径必须是绝对路径(而不是相对路径)
- 目录必须在服务器启动之前存在
- MySQL 用户必须对该目录具有读取权限
- 仅支持一个
veb_dir(不能有多个路径) - 更改后需要重新启动服务器才能生效
故障排除
快速参考
找不到扩展
错误:Extension 'my_extension' not found
调试步骤:
安装后函数不可用
错误:FUNCTION my_func does not exist
调试步骤:
更新后扩展显示旧行为
症状: 在替换.veb 文件并重新安装后,扩展仍然
运行旧代码。
原因: VillageSQL 会在第一次加载时将 .veb 文件解包到 {datadir}/.veb_expansion_cache/。如果您
在不先运行 UNINSTALL EXTENSION 的情况下复制新的 .veb,服务器将继续
使用先前解包的 .so,该 .so 已经加载到内存中。
解决方案: 始终遵循完整的 UNINSTALL → 替换 → INSTALL 流程:
veb_dir 中的 .veb 文件并重新安装:
无法卸载扩展
错误:Cannot uninstall extension: types in use
解决方案:
库加载错误
错误:Cannot load library: undefined symbol
原因:
- 缺少库依赖项
- ABI 兼容性不匹配
- MySQL 版本不正确
扩展名称验证错误
错误:Failed to load VEF extension 'extension_name' with log message Extension name mismatch
原因: manifest.json 中的扩展名称与 VEB 文件名不匹配。
调试步骤:
-
检查 VEB 文件名是否与清单文件匹配:
-
验证 manifest.json 中的 name 字段:
- VEB 文件名:
my_extension.veb - manifest.json:
"name": "my_extension"
- 在清单文件中使用连字符:
"name": "my-extension"❌ - VEB 文件名不匹配:
my-extension.veb与"name": "my_extension"❌
自定义类型比较错误
错误:Cannot compare types X and Y in =
原因: 比较的两侧都是自定义类型,但来自不同的类型或扩展。
错误:
Unable to implicitly cast a non-custom type during compare with a custom type in =
原因: 比较的一侧是自定义类型列,另一侧是无法自动转换为该类型的字面量或列。
监控扩展使用情况
查询性能
使用 performance_schema 跟踪 VDF 执行时间:自定义类型使用情况
跟踪哪些表使用自定义类型:更新扩展
要将已安装的扩展更改为其他版本,请使用ALTER EXTENSION。
它会根据现有数据验证新版本,并在下次服务器重启时应用该更改。
手动卸载并重新安装仍然是一种可选的替代方式。
更改扩展版本
ALTER EXTENSION 将已安装的扩展更改为其他版本,
并在下次服务器重启时应用:
<name>-<version>.veb 的形式存在于扩展目录中
(此处为 update_test-1.2.0.veb);缺少该文件会被拒绝:
INFORMATION_SCHEMA.EXTENSIONS 会报告当前版本以及它将
更改到的目标版本:
INFORMATION_SCHEMA.EXTENSIONS 会在四个列中报告已计划的更改:
一次仅跟踪一个已计划的更改:
- 取消已计划的更改,方法是再次请求当前版本:
- 在没有计划任何更改时请求当前版本不会执行任何操作:
- 在已计划更改时,不同的目标会被拒绝——请先取消
现有的更改:
AT RESTART 子句会在下次服务器启动期间应用该更改。
成功重启之后
在下次重启时,待处理的更改会被应用:EXTENSION_VERSION 变为
目标版本,PENDING_VERSION 被清除。对于上面计划的更改
(update_test 1.0.0 → 待处理 1.2.0):
custom_columns 和
存储过程参数行都会被重写,因此依赖的表和例程无需手动迁移
即可继续正常工作。
更改会在重启期间应用,而不是在活动连接上应用——上面的值
是重启后的状态。
从启动时的待处理版本更改中恢复
已计划的版本更改会在下次服务器启动期间应用。如果 某个待处理的操作无法应用,服务器可能会启动失败,而其待处理更新决策仍保留在磁盘上。当排队的ALTER EXTENSION ... AT RESTART 阻止了启动,而你需要在清除它之前
先让服务器启动时,请使用 --villagesql-skip-extension-updates。
--villagesql-skip-extension-updates 是一个 mysqld 启动标志。设置后,
服务器会绕过对待处理 ALTER EXTENSION ... AT RESTART 操作的处理:
每个扩展都以其当前已安装的版本加载,其待处理操作
在磁盘上保持完整。该标志本身不会改变任何内容——它只是跳过在该次启动中
应用待处理操作。
设置该标志且至少有一个扩展存在待处理操作时,服务器
会在启动时记录一条警告,指出绕过了多少个操作:
1
使用该标志启动服务器
在生产环境中,将其作为普通的 在开发工具链中,通过 成功信号: 服务器启动,且错误日志包含上面所示的
mysqld 命令行选项传递,或在
my.cnf 的 [mysqld] 下添加:-- 传递:bypassing N pending extension update(s) 警告。2
识别待处理的操作
PENDING_VERSION 就是你需要清除的目标;
PENDING_LAST_ERROR 会显示它未能应用的原因。3
清除每个待处理的操作
对于上面返回的每个扩展,请求其当前版本以取消
排队的更改(在
更改扩展版本下描述的取消机制):成功信号: 返回一条
Cleared pending update for extension '<name>' (target matches current version '<current>') 提示,且
重新运行上一个查询显示 PENDING_VERSION 为 NULL。4
不带该标志重启
正常重启服务器,省略
--villagesql-skip-extension-updates。成功信号: 服务器启动,且日志中不再出现
bypassing N pending extension update(s) 警告。手动更新过程
-
卸载当前版本:
-
替换
.veb文件: -
安装新版本:
-
验证更新:
清理
移除孤立的解包缓存目录
VillageSQL 将.veb 文件解包到 {datadir}/.veb_expansion_cache/{name}/{sha256}/。旧版本会随着时间的推移而累积。
服务器重启会自动清理孤立的解包缓存目录。
复制
自定义类型需要 ROW 格式的 binlog。对于具有自定义类型列的表,不支持 STATEMENT 和 MIXED 模式。对自定义类型列执行的 INSERT、UPDATE、DELETE 和 ALTER TABLE 操作在 ROW 格式中都能正确复制。INSTALL EXTENSION 不会复制——每个服务器管理自己的扩展。在复制开始之前,在每个副本上安装扩展,并使用与源相同的版本。服务器强制执行精确的版本匹配;版本不匹配会停止复制。
如果副本遇到它不识别的自定义类型,则复制将在 DDL 语句处停止——在 CREATE TABLE 或 ALTER TABLE 处,在任何依赖的 DML 应用之前。安装正确的扩展版本,然后恢复:
mysqldump 在输出中保留完全限定的自定义类型名称。只要在导入转储之前在目标服务器上安装了扩展,逻辑恢复就可以工作。
在 Docker 中使用扩展
在 Docker 中运行 VillageSQL 时,将本地目录挂载为veb_dir,以便您可以从主机添加 .veb 文件,而无需重新构建容器。
Docker Compose 示例:
.veb 文件复制到主机上的 ./extensions/ 中,然后从 SQL 安装:
获取帮助
如果您遇到此处未涵盖的问题:- 检查错误日志: 大多数扩展错误都带有详细信息记录在日志中。
- 查看扩展文档: 扩展特定的故障排除方法可能存在。
- 在 Discord 上提问: 加入 VillageSQL Discord。
- 提交问题: 在 GitHub Issues 上报告错误。
后续步骤
系统参考
查询系统表和视图
卸载扩展
安全地删除扩展
扩展架构
了解内部结构

