workerman代码与mysql备份需分离设计:代码备份含vendor、config、启动脚本等,排除runtime/logs;mysql增量依赖binlog,全量用mysqldump加--flush-logs,增量归档binlog文件并记录position。

Workerman 项目本身不直接参与数据库备份,它的备份对象是代码、配置、日志和依赖文件;而 MySQL 的全量/增量备份是独立的数据库运维任务。两者需分开设计、协同执行,不能混为一谈。
Workerman 应用代码与配置怎么全量备份?
核心是「保留可部署状态」:即备份后能直接拉起服务,无需额外安装或手动改配置。
- 必须包含:
vendor/(或composer.lock+composer.json)、config/、start.php及所有自定义启动脚本、.env(若存在) - 建议排除:
runtime/、logs/、storage/(除非含关键运行时数据),这些目录通常由服务启动时自动创建或应通过挂载方式管理 - 压缩打包推荐用
tar -czf workerman-backup-$(date +%Y%m%d_%H%M%S).tar.gz --exclude="logs" --exclude="runtime" ./ - 备份目标路径建议带时间戳+Git commit ID,例如
/backup/workerman-prod-20260521-abc1234.tar.gz,便于定位版本
MySQL 怎么配合 Workerman 做增量备份?
Workerman 运行期间 MySQL 持续写入,所以增量备份必须依赖 binlog,且要求 MySQL 已开启 log_bin 并设置 server_id。
- 确认 binlog 状态:
SHOW VARIABLES LIKE 'log_bin';和SHOW MASTER STATUS; - 全量备份命令(加
--flush-logs切换新 binlog):mysqldump --single-transaction --flush-logs --master-data=2 -u root -p mydb > full_$(date +%F).sql - 增量备份就是复制当前活跃的 binlog 文件(如
mysql-bin.000012),可用cp /var/lib/mysql/mysql-bin.* /backup/binlog/,但更安全的做法是用mysqlbinlog --read-from-remote-server拉取,避免文件被覆盖 - 注意:
mysqldump不生成增量文件,它只做全量;所谓“增量备份脚本”,本质是定时归档 binlog + 记录position偏移
怎么把代码备份和 MySQL 备份串成一个自动化脚本?
不能简单拼接两个命令——失败点不同、权限不同、失败后需各自回滚。推荐分阶段控制流 + 明确 exit code 判断。
- 先备份 Workerman 代码(普通用户权限即可),失败则中止,不碰数据库
- 再执行 MySQL 全量备份(需 DB 用户权限),检查
$?和输出是否含Warning或ERROR - 最后归档 binlog(需 MySQL 服务端文件读取权限或远程拉取权限),并记录
SHOW MASTER STATUS输出到元信息文件 - 示例关键判断:
if [ $? -ne 0 ]; then echo "mysqldump failed"; exit 1; fi - 日志务必重定向到独立文件,如
>/backup/logs/backup_$(date +%F).log 2>&1,否则 cron 执行时 stdout/stderr 会丢失
为什么 backup.sh 在 cron 里总失败,但手动运行正常?
最常见原因是环境变量缺失:cron 使用最小 shell 环境,PATH 不含 /usr/local/bin 或 /usr/bin,导致找不到 mysqldump、mysqlbinlog 或 sshpass。
- 在脚本开头显式声明 PATH:
export PATH="/usr/local/bin:/usr/bin:/bin" - 所有命令用绝对路径:
/usr/bin/mysqldump、/usr/bin/mysqlbinlog - 如果脚本内调用 ssh/scp,确认
~/.ssh/id_rsa权限是600,且 cron 执行用户有对应 home 目录读取权限 - 测试方法:在 crontab 中加一行
* * * * * env > /tmp/cron_env.log,对比手动执行env输出
真正容易被忽略的是备份验证环节——90% 的备份脚本只管“跑完”,不管“有效”。至少应在每次备份后加一句 head -n 20 full_*.sql | grep -q "CREATE TABLE" 或 mysqlcheck -u root -p... --all-databases --silent,否则等到恢复时才发现 SQL 文件为空或损坏,就晚了。











