必须用绝对路径调用mysqldump,如/usr/bin/mysqldump;避免密码明文,改用.chf配置文件并设600权限;需调整php超时与内存限制,加--single-transaction等参数,并校验备份完整性与定期清理。

mysqldump 命令必须用绝对路径调用
PHP 的 exec() 或 shell_exec() 在 Web 环境下通常没有配置 PATH,直接写 mysqldump 很大概率返回空或报错 command not found。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 先在服务器终端执行
which mysqldump,常见路径是/usr/bin/mysqldump或/usr/local/mysql/bin/mysqldump - PHP 中必须写全路径,例如:
shell_exec('/usr/bin/mysqldump -u root -p123456 mydb > /backup/mydb_20240501.sql 2>&1') - 密码明文写在命令里有风险,生产环境优先用配置文件方式(见下一条)
避免密码暴露:用 .my.cnf 配置文件代替命令行密码
把数据库账号密码硬编码进 PHP 字符串,既不安全,又容易被日志、进程列表或错误输出泄露(比如 ps aux | grep mysqldump 就能看到明文密码)。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 在 PHP 进程有读权限的目录(如
/home/www/.my.cnf)创建配置文件,内容为:
[client] user = backup_user password = your_strong_password host = localhost
- 设置严格权限:
chmod 600 /home/www/.my.cnf,否则mysqldump会拒绝读取 - 调用时去掉
-u和-p参数,改用--defaults-extra-file指定配置:/usr/bin/mysqldump --defaults-extra-file=/home/www/.my.cnf mydb > /backup/...
备份大库时注意超时和内存限制
Web 请求默认有 max_execution_time(常为 30 秒)和 memory_limit 限制,而导出百 MB 以上数据库可能卡住或中断,但实际 SQL 文件已部分生成——导致你以为失败了,其实备份半截躺在磁盘上。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 脚本开头加:
set_time_limit(0)和ini_set('memory_limit', '512M')(仅限 CLI 模式有效;Web 模式需同步调整 php.ini) - 用
--single-transaction替代--lock-tables,减少对线上业务影响(InnoDB 表适用) - 加上
--routines --triggers --events才能完整备份存储过程、触发器等,缺一不可 - 导出后务必检查返回值:
$output = shell_exec($cmd . ' 2>&1'); if (strpos($output, 'ERROR') !== false || !file_exists($target_file)) { /* 处理失败 */ }
PHP 脚本无法写入 /backup 目录?看 SELinux 和用户权限
Linux 下即使 chown www-data:www-data /backup 并 chmod 755,PHP 仍可能提示 Permission denied——尤其在 CentOS/RHEL 上,SELinux 默认阻止 Apache/Nginx 进程写入非标准目录。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 临时确认是否 SELinux 导致:
getenforce返回Enforcing且ausearch -m avc -ts recent | grep httpd有拒绝记录 - 临时放行(测试用):
setsebool -P httpd_can_network_connect_db 1 && setsebool -P httpd_read_user_content 1,更稳妥的是用semanage fcontext给/backup加标签 - Web 服务运行用户(如
www-data、nginx、apache)必须对目标目录有写权限,ls -ld /backup必须显示该用户在属组或属主位置
备份不是“跑一次就完事”,关键在于校验和清理。每次生成后用 mysqlcheck -u user -p --check mydb 验证 SQL 可导入性,再用 find /backup -name "*.sql" -mtime +7 -delete 自动清理旧文件——这两步漏掉一个,半年后你面对的就是一堆打不开的 .sql 文件。











