mysql如何备份存储过程与触发器_mysql –routines与–triggers

2次阅读

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

mysql如何备份存储过程与触发器_mysql –routines与–triggers

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 PROCEDURECREATE 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.routinesmysql.triggers,字段名、类型、权限检查逻辑都有变化。虽然 mysqldump --routines 在两个版本都能用,但底层行为不同:

  • 5.7 下,EXECUTE 权限检查走 mysql.proc 行级访问控制
  • 8.0 下,检查更严格,还依赖 information_schema.routines 的可读性,某些只读实例可能返回空
  • 跨版本还原要特别注意:8.0 导出的 routine 若含 JSON_TABLEWINDOW 语法,在 5.7 上直接执行会报错

真正麻烦的不是导出,是还原时的兼容性判断 —— 比如一个用了 VALIDATE PASSWORD 相关函数的 procedure,在目标实例没装插件就会静默失败,错误日志里也不报具体哪行。

text=ZqhQzanResources