php artisan migrate:rollback --step=n 按 batch 回滚,非按文件数;每个 batch 对应一次 migrate 命令执行的所有迁移,--step=2 即回滚最近两个 batch 的全部迁移。

php artisan migrate:rollback --step=N 是按 batch 回滚,不是按文件数
很多人执行 php artisan migrate:rollback --step=2 后发现删掉了 8 张表,以为命令“失控”了——其实它完全正常。--step=2 表示回滚最近 2 个 batch,每个 batch 对应一次 php artisan migrate 执行时写入 migrations 表的所有记录。
比如你昨天跑了 php artisan migrate,一次性执行了 5 个新迁移,它们在 migrations 表里共享 batch = 7;今天又跑了一次,新增 3 个迁移,batch = 8。那么 --step=1 就会触发这 3 个迁移的 down(),--step=2 则再加回 batch = 7 的全部 5 个。
-
--step不接受负数、小数或字符串,只认正整数 - 若某
batch中任一迁移的down()报错(如SQLSTATE[HY000]: General error: 1025 Error on rename),整个 step 立即终止,后续 batch 不再尝试 - 执行前建议先查当前最高 batch:
SELECT MAX(batch) FROM migrations;,避免误判“最近几个”
为什么不能指定某个迁移文件单独回滚
Laravel 迁移系统从设计上就不支持按文件名或时间戳回滚单个迁移。它的原子单位是 batch,底层依赖 migrations 表的 batch 字段做顺序控制,没有 id 或 migration_name 索引用于精确寻址。
试图用 --batch=3 或 --id=123 直接跳转?这两个参数在 Laravel 10 和 11 中均未实现,命令行会报 Unknown option。
- 官方没提供类似
php artisan migrate:rollback --only=2024_05_01_120000_create_posts_table的语法 - 强行“局部回滚”的唯一可行路径是手动改
migrations表:把目标迁移记录的batch值临时改成一个孤立值(如 999),再跑--step=1,完事再改回去——但风险高,易导致下次migrate重复执行或跳过 - 如果
down()方法里用了不可逆操作(比如DB::statement('DROP TABLE ...')而没加Schema::hasTable()判断),手动干预后更难恢复
回滚中断后怎么继续
当 --step=3 执行到第 2 个 batch 就因外键约束失败卡住,Laravel 不会自动跳过出错 batch 继续下一个。它停在那儿,且已成功执行 down() 的迁移不会被“撤回”——也就是说,数据库状态是混合的:batch 8 完成,batch 7 半途而废,batch 6 没动。
- 必须人工检查
migrations表,确认哪些 migration 的batch值还存在、哪些已删 - 查看对应迁移文件的
down()方法,补上防御逻辑(例如删表前加if (Schema::hasTable('xxx')) { ... }) - 不要直接删
migrations表记录来“假装没执行过”,这会导致后续migrate重复建表或字段冲突 - 真要清理残局,优先用
php artisan migrate:fresh(开发环境)或手动 SQL 修复,而不是靠 rollback 续跑
批量回滚和全量重置的适用边界
php artisan migrate:rollback --step=N 只适合“倒退几步再调整”,不是用来清库或重搭结构的。一旦你发现需要回滚超过一半迁移,或者中间穿插了手动 SQL 修改,就该换策略了。
-
php artisan migrate:reset是清空所有迁移,但它不重建表,只是逐个调down()——如果某些 down() 已失效,它一样会中断 -
php artisan migrate:fresh更可靠:先删库再重跑全部up(),跳过migrations表状态校验,适合本地开发重来 -
php artisan migrate:refresh --seed在 fresh 基础上自动跑 seeders,适合测试数据初始化场景 - 生产环境严禁用任何带
:fresh或:reset的命令,只允许用--step且必须提前备份 + 验证 down() 可逆性
migrate 打包了不该一起上线的变更,后续回滚就会被迫“全进全出”。











