migrations表“损坏”实为状态错乱,表现为字段长度不足、表不存在或记录残留;修复前须确认表存在性、字段类型(应为VARCHAR(255))及迁移状态;开发环境可删表+清缓存+重迁,但需预设Schema::defaultStringLength(191)并检查innodb_large_prefix与ROW_FORMAT配置。

为什么 migrations 表会“损坏”
它不是传统意义的损坏,而是状态错乱:Laravel 用 migrations 表记录哪些迁移文件已执行(靠 migration 字段值,如 2014_10_12_000000_create_users_table),但物理表可能并不存在、字段长度不足、或被手动删过又残留记录。典型表现是:php artisan migrate 报 SQLSTATE[22001]: String data, right truncated 或直接提示 Base table or view not found: 1146 Table 'xxx.migrations' doesn't exist。
手动修复前必须确认的三件事
别急着删表或改结构,先验证:
- 检查数据库里是否真有
migrations表:SHOW TABLES LIKE 'migrations'; - 如果存在,查它的建表语句:
SHOW CREATE TABLE migrations;—— 关键看migration字段是不是VARCHAR(255)(utf8mb4 下易超索引限制) - 运行
php artisan migrate:status,观察输出里有没有???或状态异常的迁移项(说明 Laravel 读不到对应记录)
安全删除并重建 migrations 表的步骤
仅限开发/测试环境;生产环境必须走备份+回滚流程,此处不覆盖。
- 先停掉所有迁移相关命令,避免并发写入
- 手动删表(MySQL):
DROP TABLE IF EXISTS migrations; - 清空 Laravel 迁移缓存(尤其 Laravel 9.22+):
php artisan migrate:clear - 再跑一次迁移:
php artisan migrate—— Laravel 会自动重建migrations表,并用当前配置的Schema::defaultStringLength()值(如 191)定义字段长度
⚠️ 注意:如果项目没提前在 AppServiceProvider::boot() 里设 Schema::defaultStringLength(191),重建后仍可能再次触发 767 字节限制错误。
修复后仍报错的隐藏原因
最常被忽略的是 MySQL 的 innodb_large_prefix 和 row_format 配置。即使你设了 191,若数据库全局配置为 innodb_large_prefix = OFF 且表格式是 COMPACT,InnoDB 依然按老规则算索引上限。此时需确认:
-
SELECT @@innodb_large_prefix;返回OFF?那得配合SET GLOBAL innodb_large_prefix=ON;(需 SUPER 权限) -
SELECT TABLE_NAME, ROW_FORMAT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'your_db_name' AND TABLE_NAME = 'migrations';—— 若是COMPACT,建议在迁移前加DB::statement('ALTER TABLE migrations ROW_FORMAT=DYNAMIC');
真正卡住的往往不是代码,而是数据库服务层那几行没被读到的配置。


















