mysqldump 不加 --routines 不会导出函数,该参数同时导出函数和存储过程,恢复需 create routine 权限并确保 delimiter 结构完整及跨版本兼容性。

mysqldump 不加 --routines 就不会导出函数
默认情况下 mysqldump 只导出表结构和数据,函数、存储过程、触发器这些都属于“routine”,必须显式开启开关。不加 --routines,哪怕你用 --all-databases 或指定了具体库,函数定义照样消失。
- 导出时漏掉这个参数,恢复后调用
CALL my_func()会直接报错PROCEDURE db.my_func does not exist -
--routines会同时导出函数(FUNCTION)和存储过程(PROCEDURE),无法单独只选函数 - 如果只想要函数,导出后得手动从 SQL 文件里删掉
CREATE PROCEDURE块,别指望mysqldump提供过滤选项 - 该参数不依赖
--databases,但建议一起用:例如mysqldump --routines --databases mydb > backup.sql
恢复时权限不足会导致 CREATE FUNCTION 被跳过
MySQL 恢复函数时,需要用户有 CREATE ROUTINE 权限;否则 source backup.sql 或 mysql 过程中,遇到 <code>CREATE FUNCTION 语句会静默失败或报错 ERROR 1418 (HY000),而后续的表数据可能照常导入,造成“看起来恢复成功,实则函数丢了”的假象。
- 检查当前用户权限:
SHOW GRANTS FOR CURRENT_USER;,确认含GRANT CREATE ROUTINE ON *.* TO ... - 临时启用
log_bin_trust_function_creators=1(仅当启用了二进制日志且函数非确定性时才需),否则可能卡在ERROR 1418 - 不要用普通应用账号恢复,优先用
root或明确授过CREATE ROUTINE和ALTER ROUTINE的账号
函数体里含分号会破坏 mysqldump 输出的 SQL 格式
mysqldump 导出函数时,会自动把 DELIMITER 切换逻辑写进 SQL 文件(比如先设为 $$,再还原)。但如果函数定义本身没按规范写——比如函数体里用了未转义的分号、或者 DELIMITER 写错位置——会导致导出的 SQL 文件语法错误,恢复时报 ERROR 1064。
- 导出前可手动验证:登录 MySQL,执行
SHOW CREATE FUNCTION myfunc\G,看输出是否完整、是否有意外截断 - 常见坑是函数里写了
SELECT ... INTO @var;或SET @x = 1;后没注意分号被误当成语句结束符 - 导出后打开
backup.sql,搜索CREATE FUNCTION,确认其前后有正确的DELIMITER块包裹,且函数体内部没裸露分号打断结构
跨版本恢复函数要小心 SQL SECURITY 和特性兼容性
MySQL 5.7 和 8.0 对函数安全属性、内置函数支持、甚至字符集处理都有差异。比如 8.0 默认要求函数声明 SQL SECURITY DEFINER 或 INVOKER,而老版本可能允许省略;又比如 8.0 废弃了 YEAR(2),若函数里用了,恢复会失败。
- 导出时加上
--compatible=mysql40或--compatible=ansi并不能解决函数兼容问题,它只影响建表语句 - 最稳妥方式:在目标版本的 MySQL 上先创建空函数壳(
CREATE FUNCTION f() RETURNS INT RETURN 1;),再用ALTER FUNCTION替换逻辑体 - 特别留意函数里调用的系统函数,如
UUID_SHORT()、JSON_EXTRACT()在低版本不存在,恢复前得人工降级或打补丁
函数定义不是数据,也不是表结构,它是独立的数据库对象,备份恢复链条上任何一环松动——参数漏、权限缺、语法毛、版本跳——都会让函数无声失效。最容易被忽略的是恢复时的权限校验和 DELIMITER 结构完整性,这两处不出错,基本就稳了。











