yii2中通过console命令触发mysqldump备份:在console/controllers/backupcontroller.php中定义actiondb(),动态读取yii::$app->db配置,用escapeshellarg()安全拼接命令,调用/usr/bin/mysqldump | gzip导出压缩包至@runtime/backup/,文件名含时间戳与随机码防冲突,配合mkdir、软链接latest、find自动清理,并在crontab中显式指定path和项目路径确保稳定执行。

Yii2 中如何用 console 命令触发 mysqldump 备份
直接在 Yii2 里“写个 PHP 函数导出 SQL”不现实,真正可靠的数据备份必须依赖 mysqldump 这类数据库原生命令。Yii 的 console 应用是最佳载体——它能安全读取配置、避开 Web 请求限制、支持定时调度。
实操建议:
- 在
console/controllers/BackupController.php中定义actionDb(),用exec()或shell_exec()调用mysqldump - 从
Yii::$app->db动态提取host、username、password、database,避免硬编码 - 务必用
escapeshellarg()包裹所有用户可控参数(尤其是密码含特殊字符时),否则命令会静默失败 - 输出路径建议用
Yii::getAlias('@runtime/backup/'),确保有写权限且不在 Web 可访问目录下
备份文件名怎么带时间戳又不冲突
用 date('Y-m-d-H-i-s') 看似简单,但并发执行时可能生成同名文件——比如两个 backup 命令恰好在同一秒启动。
实操建议:
- 改用
date('Y-m-d-H-i') . '-' . substr(md5(microtime(true)), 0, 6),兼顾可读性与唯一性 - 备份前先
mkdir -p目录,避免因目录不存在导致整个命令退出 - 加一层判断:若上一次备份(如
latest.sql.gz)存在,先unlink()再创建软链接指向本次文件,方便脚本快速定位最新备份
gzip 压缩和自动清理旧备份怎么做
裸 SQL 文件体积大,不压缩会迅速占满磁盘;不清理历史备份则无法长期运行。
实操建议:
- 用
mysqldump ... | gzip > $file.gz一次性完成导出+压缩,避免生成中间大文件 - 清理策略推荐保留最近 7 天 + 最近 4 个周日备份:用
find /path -name "*.sql.gz" -mtime +7 ! -name "*-sun.sql.gz" -delete(注意 shell 环境中$需转义) - 在 PHP 中调用
exec("find ... 2>/dev/null"),屏蔽 find 找不到文件时的 warning 输出
crontab 定时执行时找不到 mysqldump 怎么办
Web 环境下 which mysqldump 返回 /usr/bin/mysqldump,但 crontab 默认 PATH 极简,大概率报错 'mysqldump' not found。
实操建议:
- 在 cron 行首显式声明 PATH:
PATH=/usr/local/bin:/usr/bin:/bin - 更稳妥的做法:在 PHP 中用
exec('which mysqldump', $out); $dumpCmd = $out[0] ?: '/usr/bin/mysqldump';动态获取路径 - crontab 条目示例:
0 2 * * * cd /var/www/myapp && /usr/bin/php yii backup/db >> /var/log/backup.log 2>&1
关键点在于:备份不是“跑通一次就行”,而是持续运行中要扛住密码变更、磁盘告警、MySQL 版本升级、时区切换这些真实运维场景——每个环节漏掉权限、路径或错误处理,都会让备份在某天突然静默失效。











