必须先执行 php artisan migrate,否则应用启动时会因表缺失直接报错;迁移需在 web 服务启动前完成,且须控制顺序、环境与锁表风险,避免并发执行、权限不足或模型未同步导致隐性故障。

必须先执行 php artisan migrate,否则应用启动时会因表缺失直接报错(如 SQLSTATE[42S02]: Base table or view not found),但「先迁移」不等于「无条件全量跑一遍」——顺序、环境、锁表风险都得卡死。
迁移必须在 Web 服务启动前完成
PHP-FPM 或 Apache/Nginx 进程启动后,Laravel 会加载配置、连接数据库、检查缓存。一旦路由或中间件触发模型查询(比如登录验证查 users 表),而该表尚未创建,就会抛出致命错误,进程退出或返回 500。
- 常见现象:Nginx 显示
500 Internal Server Error,日志里反复出现Base table not found - 真实部署链路应为:
git pull→composer install --no-dev→php artisan migrate→php artisan config:cache→ 启动 PHP-FPM/Nginx - 不要把
migrate放进 Dockerfile 的RUN阶段——镜像构建时数据库不可达;应放在容器启动脚本(如entrypoint.sh)中,且需加重试和超时控制
生产环境迁移不能裸跑 php artisan migrate
默认命令会在当前连接下执行所有未运行的迁移,但没做并发保护、没跳过已失败项、也没留回滚余地。线上表大、流量高时极易锁表或中断。
- 加
--force参数才允许在非交互环境执行(否则会卡住等确认) - 用
--path指定单个迁移文件,避免批量误操作;例如只上线用户模块变更:php artisan migrate --path=database/migrations/2025_08_20_100000_add_status_to_users_table.php --force - 加
--pretend先看 SQL 干了啥,尤其涉及外键、索引、TEXT字段变更时 - MySQL 8.0+ 可配合
ALGORITHM=INSTANT的 DDL(如加列),但 Laravel 默认不生成该语法,需手写DB::statement()
多节点部署时迁移只跑一次
负载均衡后挂多个 PHP 容器?所有实例同时执行 migrate 会导致重复建表、主键冲突或迁移记录表(migrations)写入竞争。
- 标准解法:用独立部署任务(CI/CD job 或运维脚本)执行迁移,成功后再滚动更新应用节点
- 若必须容器内执行,需加分布式锁(如 Redis 锁 +
php artisan migrate --step=1分步跑),但复杂度陡增,不推荐 -
migrations表本身必须存在且可写——检查DB_USERNAME是否有INSERT/UPDATE权限,有些 DBA 会禁掉对系统表的写操作
最常被忽略的一点:迁移成功不代表应用就稳了。如果迁移里新增了字段,但 Model 的 $fillable 或 $casts 没同步,后续数据写入会静默失败或类型错乱——得连着测接口,不能只看 migration 输出 “Migrated” 就收工。











