mysqldump导出失败主因是path缺失、权限不足、stderr未捕获、内存超限或编码不匹配;需用绝对路径、重定向stderr、流式输出、指定utf8mb4字符集并校验环境。

mysqldump 命令导出失败:提示 command not found 或权限拒绝
说明:很多 PHP 环境(尤其是 Docker、Mac M1/M2、Windows WSL)里 mysqldump 不在系统 PATH,或当前用户没权限执行。PHP 的 exec() 或 shell_exec() 调用时直接报错,不是 MySQL 连接问题,而是 shell 层面找不到命令。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 先在终端手动运行
which mysqldump,确认路径(常见为/usr/bin/mysqldump、/opt/homebrew/bin/mysqldump、C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqldump.exe) - PHP 中必须写绝对路径,不能只写
mysqldump;例如:/usr/bin/mysqldump -hlocalhost -uuser -ppass dbname > backup.sql - 检查 Web 服务器用户(如
www-data、_www)是否对目标目录有写权限;导出路径别用./backup.sql,改用绝对路径如/var/www/html/backups/backup_202405.sql - Windows 下注意反斜杠和空格:路径含空格时,整个命令要用双引号包裹,且
mysqldump.exe路径也得加引号,例如:"C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqldump.exe" -hlocalhost ...
PHP 执行 mysqldump 后文件为空或只有报错信息
说明:mysqldump 把错误输出(stderr)和正常输出(stdout)混在一起,PHP 默认只捕获 stdout。一旦认证失败、表不存在或字符集不匹配,错误被丢弃,你看到的是空文件或意外的 HTML/PHP 输出。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 把 stderr 重定向到 stdout:在命令末尾加
2>&1,例如:/usr/bin/mysqldump -hlocalhost -uuser -ppass dbname 2>&1 > /path/to/backup.sql - 用
shell_exec()拿完整输出,先检查返回值是否含ERROR、Access denied、Unknown database等关键词,再决定是否保存文件 - 避免在命令里明文写密码(
-ppass),改用配置文件方式:创建/tmp/my.cnf,内容为:[client] host=localhost user=username password=password
,然后调用mysqldump --defaults-file=/tmp/my.cnf dbname;记得chmod 600 /tmp/my.cnf并导出后立即unlink()
导出大库时超时或内存溢出(PHP 报 Fatal error: Allowed memory size exhausted)
说明:用 file_get_contents() 或 shell_exec() 读取整个 SQL 文件内容再输出给浏览器,会把几百 MB 的 dump 全塞进 PHP 内存,必然崩。这不是 mysqldump 的问题,是 PHP 层处理方式错了。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 绝不把 dump 结果读进 PHP 变量;让
mysqldump直接写磁盘,PHP 只负责触发命令 + 校验文件大小 - 导出完成后,用
readfile()+header()流式输出,例如:header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="backup.sql"'); header('Content-Length: ' . filesize($file)); readfile($file); - 设置超时:
set_time_limit(0),但更关键是限制mysqldump自身行为,加--single-transaction --skip-lock-tables减少锁等待,加--routines --triggers --events按需选,别无脑全导
中文乱码或特殊字符变成问号(导出 SQL 里汉字变 ???)
说明:mysqldump 默认用 latin1 编码连接 MySQL,而你的库/表是 utf8mb4,结果字符被错误转码。不是 PHP 文件编码问题,也不是浏览器显示问题,是 dump 过程中就已损坏。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 强制指定字符集:在
mysqldump命令中加--default-character-set=utf8mb4,且确保 MySQL 服务端character_set_server和库级COLLATE一致 - 验证导出文件编码:用
file -i backup.sql或 VS Code 查看实际编码,应为utf-8;若仍是iso-8859-1,说明参数没生效或 MySQL 版本太老( - 如果用
PDO或mysqli在 PHP 里拼接 SQL 导出(不推荐),必须统一设置连接字符集:$pdo->exec("SET NAMES utf8mb4"),但不如直接用mysqldump











