应先查文档确认函数是否为当前mysql版本内置函数,再检查插件是否启用、自定义函数是否存在及权限是否正确,避免混淆udf与内置函数。

确认函数是否为 MySQL 内置函数
遇到 Function 'xxx' is not defined 错误时,第一反应不该是“重装”或“改配置”,而是先查文档确认该函数是否真的属于当前 MySQL 版本的内置函数。比如 ngram 在 MySQL 5.7+ 中是内置全文解析器,但仅在启用了 ngram 插件的前提下才可用;而它在 MariaDB 中压根不存在。
常见误判场景:
- 把 MySQL 官方手册里 8.0+ 的函数(如
JSON_OVERLAPS())直接用在 5.7 实例上 - 复制了带
WITH PARSER ngram的ALTER TABLE ... FULLTEXT语句,却没检查当前实例是否加载了ngram插件 - 看到别人代码里写了
my_custom_func(),误以为是 MySQL 自带函数,实际是对方自己CREATE FUNCTION的
检查插件是否已加载(针对 ngram、re2 等解析器类函数)
ngram 不是函数,是全文解析器(fulltext parser),但它在 SQL 中以类似函数名的形式出现在 WITH PARSER 子句里,所以报错信息会显示 Function 'ngram' is not defined —— 这是 MySQL 的误导性提示。
验证和启用方式:
- 执行
SHOW PLUGINS;,查找name列含ngram且Status为ACTIVE的行 - 若未启用,用
INSTALL PLUGIN ngram SONAME 'ha_ngram.so';加载(Linux)或ha_ngram.dll(Windows) - 注意:MySQL 8.0.11+ 默认启用
ngram,但某些精简版或容器镜像可能跳过了插件安装步骤 - 加载后需重启连接,旧连接不会自动识别新插件
排查自定义函数是否存在且权限正确
如果你自己或团队创建过 CREATE FUNCTION xxx(...),报这个错大概率是函数没建成功,或当前用户无执行权限。
快速定位步骤:
- 用高权限账号(如 root)执行
SELECT * FROM mysql.func WHERE name = 'xxx';,确认函数元数据是否存在 - 检查函数体中是否引用了未声明的变量或外部 UDF(用户自定义函数)动态库,比如
_mysql是旧版 MySQLdb 驱动的 C 模块名,不是 MySQL 内置函数 —— 此时错误本质是 Python 层误用了驱动符号 - 执行
SHOW CREATE FUNCTION xxx;,看是否返回语法错误或“function does not exist” - 确认当前登录用户有
EXECUTE权限:SHOW GRANTS FOR CURRENT_USER;
避免混淆 UDF 动态库与 SQL 函数名
像 _mysql、lib_mysqludf_sys 这类名字,常出现在 Python 报错栈里(如 NameError: name '_mysql' is not defined),但它们根本不是 MySQL 服务端的函数,而是客户端驱动或扩展模块的内部符号。这类错误不该去 MySQL 里查 CREATE FUNCTION,而应检查 Python 依赖:
- 用
mysql-connector-python就别 import_mysql—— 那是 PyMySQL 或 MySQLdb 的底层模块 - 如果硬要调用 UDF,确保
.so/.dll文件已拷贝到 MySQL 的plugin_dir,且用CREATE FUNCTION xxx RETURNS STRING SONAME 'xxx.so';正确注册 - UDF 注册后,必须由具有
INSERT权限的用户操作mysql.func表,普通账号无法绕过
最易被忽略的一点:MySQL 对函数名大小写敏感性取决于系统变量 lower_case_table_names,而函数名本身在 SQL 中不强制小写 —— 但 UDF 的 SONAME 字符串必须与磁盘文件名完全一致(包括大小写)。











