mysqldump --no-data 默认不导出存储过程,需显式添加 --routines 参数;导出文件缺少 delimiter 会导致执行失败,应手动补充或用 source 命令处理。

mysqldump --no-data 无法导出存储过程
直接用 mysqldump --no-data 导出数据库时,存储过程(PROCEDURE)、函数(FUNCTION)、事件(EVENT)和触发器(TRIGGER)默认**不会被包含**——哪怕加了 --no-data,它只跳过表数据,不自动启用程序体导出。这是最常踩的坑:以为“没数据=只导结构”,结果打开 SQL 文件发现空空如也。
根本原因在于:MySQL 把存储过程等对象归类为“数据库元数据”,但不属于表结构(CREATE TABLE),必须显式开启对应选项。
必须加 --routines 参数才能导出存储过程
--routines 是开关,告诉 mysqldump 把 CREATE PROCEDURE 和 CREATE FUNCTION 语句一并写入输出。它和 --no-data 完全正交,要一起用:
mysqldump -u root -p --no-data --routines --skip-triggers database_name > procedures_only.sql
-
--no-data:跳过所有表的数据(INSERT)和表结构(CREATE TABLE) -
--routines:强制导出存储过程与函数定义(CREATE PROCEDURE/CREATE FUNCTION) -
--skip-triggers:避免意外导出触发器(它们默认随表结构导出,但这里不需要)
注意:--routines 需要用户有 SELECT 权限在 mysql.proc 表上,否则会报错 Access denied; you need (at least one of) the SUPER privilege(s) for this operation(5.7+ 版本中部分部署改用 SELECT on mysql.proc,而非 SUPER)。
导出后 SQL 文件里没有 DELIMITER,执行可能失败
导出的 procedures_only.sql 通常不含 DELIMITER 声明,而原存储过程中用了分号(;)作语句结束符。如果直接用 mysql 命令执行该文件,客户端会把第一个 ; 就当作整个 CREATE PROCEDURE 的结束,导致语法错误:
ERROR 1064 (42000): You have an error in your SQL syntax...
解决方法有两个:
- 手动在 SQL 文件开头加上
DELIMITER $$,并在每个CREATE PROCEDURE结尾补$$,最后再写DELIMITER ; - 更稳妥:用
mysql客户端时加--binary-mode并配合source命令(它内部处理 delimiter),或直接使用mysql -e "source procedures_only.sql"(部分版本更兼容)
也可以用 --skip-definer 避免导出 DEFINER=`user`@`host`,防止目标库因用户不存在而创建失败。
只想导特定一个存储过程?mysqldump 不支持,换 SHOW CREATE
mysqldump 只能按数据库粒度导出全部 routine,不支持 --routines=proc_name 这种过滤。如果只要某一个过程:
mysql -u root -p -Nse "SHOW CREATE PROCEDURE database_name.proc_name" > single_proc.sql
-N 去掉列名,-s 禁用表格格式,-e 直接执行 SQL;输出是三列(Procedure、sql_mode、Create Procedure),需手动截取第三列,或用 awk '{print $3}' 提取(注意字段含空格时需更严谨处理)。
这个方式绕过了权限检查(只要对过程有 EXECUTE 权限即可),也避免了 mysqldump 对 mysql.proc 的依赖,适合受限环境。
真正麻烦的不是命令怎么写,而是导出后要不要改 DEFINER、要不要调 DELIMITER、目标 MySQL 版本是否支持导出的语法特性——这些细节不验证,导入时大概率卡住。











