spatie/laravel-backup需手动注册服务提供者、启用gzip压缩、用绝对路径+系统crontab调度、显式指定utf8mb4字符集,并确保temporary_directory权限与空间充足,否则备份静默失败或恢复乱码。

直接用 spatie/laravel-backup 配合系统 cron,别碰 Laravel 自带的 schedule:run 调度器——它在生产环境掉备概率高,不是设计来扛备份这种重 IO 任务的。
backup:run 命令找不到?先查服务提供者和配置发布
装完包却报 Command "backup:run" is not defined,90% 是启动流程断了。Laravel 10+ 虽支持自动发现,但不保险。
- 确认
config/app.php的providers数组里有Spatie\Backup\BackupServiceProvider::class - 必须执行
php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider",否则config/backup.php不会出现,命令也不会注册 - 如果用了 Laravel Sail 或 Docker,所有命令(包括
vendor:publish)必须进容器执行,宿主机上跑无效
备份文件越来越大,磁盘悄悄爆掉
默认生成的是未压缩的 SQL 文件,对日志表、订单表这类大表极其危险。一次备份可能几百 MB,一周就占满磁盘。
- 打开
config/backup.php,把'database_dump_compressor' => null改成'database_dump_compressor' => Spatie\DbDumper\Compressors\GzipCompressor::class - Linux/macOS 一般自带
gzip;Windows WSL 需确认gzip --version可用;原生 Windows 得换SevenZipCompressor并装 7-Zip - 别忽略
'temporary_directory' => storage_path('app/backup-temp')——这个临时目录空间不足时,mysqldump会静默失败,只留空 ZIP
crontab 定时没反应,不是 schedule 没配好,是路径和环境错了
php artisan schedule:run 在本地能跑,服务器上 cron 不触发,问题几乎全出在环境隔离上。
- 绝对不用相对路径:
cd /var/www/myapp && php artisan backup:run是错的;必须写死 PHP 和 artisan 全路径:/usr/bin/php /var/www/myapp/artisan backup:run --no-interaction - 查真实 PHP 路径:
which php,别用php别名;不同用户(如www-datavsroot)的$PATH可能不含mysqldump - 确认
APP_ENV=production生效——config/backup.php默认有'only_on_envs' => ['production'],开发环境会直接跳过
恢复时乱码或报 Unknown character set
备份成功不代表能恢复。从 SQL 文件导入时崩在 utf8mb4_0900_ai_ci,本质是 mysqldump 没锁定字符集,依赖了 MySQL 服务端默认值。
- 在
config/backup.php的database_dumpers.mysql.dump_options里加参数:--default-character-set=utf8mb4 - 同时确保目标库也用
utf8mb4,建库语句带上CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci - 别信
backup:list显示“成功”——一定要手动抽一个备份文件,用gunzip -c xxx.sql.gz | head -20看开头有没有SET NAMES utf8mb4
最常被跳过的其实是临时目录权限和字符集显式声明——前者让备份无声失败,后者让恢复变成猜谜。这两处不盯紧,其他都白搭。











