You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel在Docker搭配MariaDB10.6执行alter table迁移报连接拒绝错误

问题成因
  • MariaDB 10.6 新增的原子DDL特性和Laravel默认开启的PDO持久化连接存在兼容性冲突,这是问题的核心原因:
    1. Laravel 执行上述Schema::create闭包时会拆分两次SQL请求:首先执行CREATE TABLE创建表结构,再单独执行ALTER TABLE添加联合唯一索引
    2. MariaDB 10.6默认开启原子DDL,执行完DDL操作后会主动断开当前持有的非交互式持久化PDO连接,Laravel执行第二步加索引操作时复用已被断开的连接,就会抛出Connection refused报错
    3. 手动执行SQL时使用的是交互式连接,不会被服务端主动断开,因此可以正常执行
  • MariaDB 10.5及更早版本不支持原子DDL,执行DDL后不会主动断开持久化连接,因此迁移可正常运行。
  • 附加触发条件:Laravel数据库配置默认开启PDO持久化连接,同时MariaDB 10.6的wait_timeout默认值相比10.5有所下调,进一步提升了问题触发概率。
解决方案

按优先级从高到低可选择以下任意一种方案:

方案1:关闭PDO持久化连接(最稳妥,无副作用)

修改config/database.php中mysql连接的options配置,关闭持久化连接:

'mysql' => [
    // 原有配置项保持不变
    'options' => [
        PDO::ATTR_PERSISTENT => false,
        // 其他原有option配置保留即可
    ],
],

修改后执行php artisan config:clear清除配置缓存,再重新运行迁移即可正常执行。

方案2:调整MariaDB配置适配现有连接逻辑

修改MariaDB 10.6的配置文件(Docker环境通常挂载的my.cnf),添加以下参数:

# 关闭原子DDL特性
atomic_ddl=OFF
# 延长非交互式连接超时时间
wait_timeout=600
interactive_timeout=600

重启MariaDB容器后重新运行迁移即可。

方案3:拆分迁移的DDL操作

将原迁移文件拆分为两个独立迁移,分别执行建表和加索引操作,避免同一个连接内连续执行两次DDL:
第一步迁移(仅建表):

Schema::create('team_invitations', function (Blueprint $table) {
    $table->id();
    $table->foreignId('team_id')->constrained()->cascadeOnDelete();
    $table->string('email');
    $table->string('role')->nullable();
    $table->timestamps();
});

第二步迁移(单独加索引):

Schema::table('team_invitations', function (Blueprint $table) {
    $table->unique(['team_id', 'email']);
});

内容的提问来源于stack exchange,提问作者anotherOneHere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 07:48:00