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

Ruby升级后Rails控制台出现Mysql2::Error连接超时问题求助

Ruby 3.0.6 + Rails 6.1.7.6 控制台频繁触发 Mysql2 连接超时错误

问题详情

将Ruby版本从2.5.8升级至3.0.6后,Rails控制台频繁出现连接超时错误,但应用运行期间无此问题,Ruby 2.5.8版本下也正常。

错误日志

/usr/local/bundle/gems/mysql2-0.5.5/lib/mysql2/client.rb:151:in `_query': Mysql2::Error: The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior. (ActiveRecord::StatementInvalid)
/usr/local/bundle/gems/mysql2-0.5.5/lib/mysql2/client.rb:151:in `_query': The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior. (Mysql2::Error)

当前database.yml配置

defaults: &defaults
  adapter: mysql2
  wait_timeout: 30 
  timeout: 500
  reconnect: true
  strict: false
  host: somehostname
  port: someportnumber
  username: someusername
  password: somepassword
  database: somedatabasename
  encoding: utf8mb4
  collation: utf8mb4_unicode_ci
  pool: 13

development:
  primary:
    <<: *defaults
  shard1:
    <<: *defaults
    database: shard1
  shard2:
    <<: *defaults
    database: shard2

已尝试的无效操作

  • 将mysql2 gem从0.5.5降级至0.5.4
  • 增大database.yml中的timeout值
  • 依赖reconnect: true自动重连(未生效)

解决方案

1. 标记控制台连接为交互式并调整服务器超时参数

Rails控制台属于交互式连接,MySQL默认使用interactive_timeout而非wait_timeout来管理这类连接的超时时间。

  • 在database.yml的defaults块中添加interactive: true,让客户端标记自身为交互式连接:
    defaults: &defaults
      # ... 原有配置
      interactive: true
    
  • 修改MySQL服务器的interactive_timeout参数(建议设置为86400秒即24小时):
    SET GLOBAL interactive_timeout = 86400;
    SET GLOBAL wait_timeout = 86400;
    
    若需要永久生效,在MySQL配置文件(如my.cnf/my.ini)中添加:
    [mysqld]
    interactive_timeout = 86400
    wait_timeout = 86400
    
  • 重启MySQL服务和Rails控制台。

2. 为控制台添加连接校验钩子

Ruby 3.x与mysql2 0.5.x的组合可能导致Rails自动重连逻辑在控制台中失效,可通过初始化脚本强制检查连接状态:

创建config/initializers/console_reconnect.rb文件,添加以下代码:

if defined?(Rails::Console)
  # 控制台启动时断开旧连接并重新建立
  ActiveRecord::Base.connection_pool.disconnect!
  ActiveSupport.on_load(:active_record) do
    ActiveRecord::Base.connection_pool.establish_connection
    ActiveRecord::Base.connection.verify!
  end

  # 每次执行命令前校验所有连接有效性
  IRB.conf[:IRB_RC] = proc do
    ActiveRecord::Base.connection_pool.connections.each do |conn|
      conn.verify! unless conn.active?
    end
  end
end

重启控制台后,每次执行命令前会自动检查并重建失效连接。

3. 升级mysql2至兼容Ruby 3.x的版本

mysql2 0.5.x对Ruby 3.x的兼容性存在部分问题,尝试升级到更高版本:

  • 修改Gemfile:
    gem 'mysql2', '~> 1.1.0' # Rails 6.1.x兼容该版本
    
  • 执行bundle install更新依赖,重启控制台测试。

4. 调整客户端超时配置

在database.yml中增大wait_timeout和interactive_timeout的客户端配置(与服务器端保持一致):

defaults: &defaults
  # ... 原有配置
  wait_timeout: 86400
  interactive_timeout: 86400
  interactive: true

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 01:44:58