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小时):
若需要永久生效,在MySQL配置文件(如SET GLOBAL interactive_timeout = 86400; SET GLOBAL wait_timeout = 86400;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
相关产品推荐
相关产品推荐

