mysqldump --routines 备份不到存储过程是因为用户缺少 execute 权限;--triggers 导出的触发器因 definer 报错需加 --skip-definer;仅导 routines/triggers 用 --no-data 配合过滤;5.7 与 8.0 元数据表不同影响权限校验和兼容性。

mysqldump --routines 备份不到存储过程?检查这个权限
默认情况下,mysqldump --routines 不会导出存储过程和函数,不是命令写错了,而是当前用户缺少 SELECT 权限以外的必要权限。MySQL 要求用户必须拥有 SELECT + SHOW VIEW + LOCK TABLES(若未加 --single-transaction)+ 还有关键的 EXECUTE 权限,才能读取 mysql.proc 表里的 routine 定义。
常见错误现象:mysqldump --routines -u user -p db_name 输出里没有 CREATE PROCEDURE 或 CREATE FUNCTION 语句,只看到表结构和数据。
- 用
SHOW GRANTS FOR 'user'@'host';确认是否含GRANT EXECUTE ON *.* TO ... - 临时修复可执行:
GRANT EXECUTE ON `db_name`.* TO 'user'@'host'; FLUSH PRIVILEGES; - 如果只备份单库,
EXECUTE权限只需授予对应库,不必给全局
mysqldump --triggers 导出的触发器在恢复时报错?注意 DEFINER
mysqldump --triggers 会把触发器原样导出,包括开头的 DEFINER=`user`@`host`。目标库若不存在该用户,或用户无 TRIGGER 权限,CREATE TRIGGER 就会失败,报错类似:ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration(实际是 DEFINER 导致权限校验失败)。
- 最稳妥做法:导出时加
--skip-definer,让 mysqldump 自动去掉所有DEFINER子句 - 也可用
--set-gtid-purged=OFF配合--skip-definer,避免 GTID 相关干扰 - 不建议手动 sed 替换,容易误伤注释或字符串里的
@
只备份 routines 和 triggers,不导出表数据?用 --no-data 配合 --routines --triggers
很多人想单独提取存储过程和触发器用于版本管理或迁移审查,但 mysqldump --routines --triggers 默认仍会导出表结构(CREATE TABLE)和数据(INSERT),冗余且体积大。
- 加
--no-data可跳过所有INSERT语句,但表结构仍保留 —— 这是预期行为 - 若连表结构都不要,只留 routines/triggers,得额外过滤:用
mysqldump --no-data --routines --triggers db_name | grep -E "^DELIMITER|^CREATE (PROCEDURE|FUNCTION|TRIGGER)" -
--no-create-info不能替代--no-data:它只跳过CREATE TABLE,但INSERT依然存在
MySQL 5.7 与 8.0 的 routines 导出差异在哪?重点看 mysql.proc vs mysql.routines
MySQL 5.7 及以前,存储过程元数据存在 mysql.proc 表;8.0 起迁移到 mysql.routines 和 mysql.triggers,字段名、类型、权限检查逻辑都有变化。虽然 mysqldump --routines 在两个版本都能用,但底层行为不同:
- 5.7 下,
EXECUTE权限检查走mysql.proc行级访问控制 - 8.0 下,检查更严格,还依赖
information_schema.routines的可读性,某些只读实例可能返回空 - 跨版本还原要特别注意:8.0 导出的 routine 若含
JSON_TABLE或WINDOW语法,在 5.7 上直接执行会报错
真正麻烦的不是导出,是还原时的兼容性判断 —— 比如一个用了 VALIDATE PASSWORD 相关函数的 procedure,在目标实例没装插件就会静默失败,错误日志里也不报具体哪行。










