新手问题 求解关于 log 中 set NAMES utf-8, @@SESSION.wati_timeout,EXPLAIN 的含义和解决方法

yfscret · 2020年09月23日 · 最后由 yfscret 回复于 2020年11月07日 · 1560 次阅读

以前在本地开发,启动 rails s 时候,log 中会有这么一行 set NAMES utf-8, 然后开发过程中,不会再出现这个,最近发现,过个十几秒没操作页面的话,再刷新一下页面或者任意发个 get , put, post 等请求,log 都会在发出请求后卡住一会,然后显示 set NAMES 这一行,比如: 有时会显示多行这 中间可能还会夹杂着 EXPLAIN,比如:

请教以下问题:

  • 1. set NAMEs 这一行是干啥的
  • 2. EXPLAIN 这一行是干啥的
  • 3. 怎么能让 log 中不出现些,也就是让发送请求后直接读取数据库,而不是卡住先去 set NAMES 这些,不让 EXPLAIN

@huacnlee @Rei @rocLv 求大佬指导

EXPLAIN 就是 sql 查询分析 https://juejin.im/post/6844904035900719111

你是不是用了啥插件?

EXPLAIN 是 Rails 的特性:

https://weblog.rubyonrails.org/2011/12/6/what-s-new-in-edge-rails-explain/

config.active_record.auto_explain_threshold_in_seconds = 0.5

Rails 3.2 有这个功能,当你的某个 SQL 查询时间超过了设定的档位,将会自动做 EXPLAIN 动作。

这个功能我很少关注,貌似 Rails 4.0 去掉了这个功能。

Remove automatic execution of EXPLAIN queries. The option active_record.auto_explain_threshold_in_seconds is no longer used and should be removed.

https://guides.rubyonrails.org/4_0_release_notes.html


你用的什么版本 Rails?


第二个问题:set NAMES utf-8

看起来,你的数据库可能不是 UTF-8 的

huacnlee 回复

rails 是 5.1.7 版本,ruby 是 2.3.1 版本,你说的 config.active_record.auto_explain_threshold_in_seconds 在项目里没有设置。 数据库我查了一下 charset

lidashuang 回复

经你的提醒,我猜是不是因为用了 newrelic 的原因,我正在测试去掉后还会不会 explain

piecehealth 回复

你好,我 rails server 启动时候会执行这个,就是你说的新建数据库连接,但是现在问题是启动后,每发一个请求,都是 log 中等待十几秒或者几十秒看到再去执行一次或几次这个 set NAME, 然后才会接着往下去读取数据库,我就是不明白为什么 server 启动后,每发一个请求都会去 set NAME 这个,另外您发的这个链接的代码,我也搜到过,但是我不懂对解决我这个问题有什么帮助,您能帮帮忙吗

yfscret 回复

先说输出这些 log 是在哪里:

输出 sql 到 log 是https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb#L680-L695https://github.com/rails/rails/blob/master/activerecord/lib/active_record/log_subscriber.rb#L22-L44 做的

你可以在这里设断点来调试(改 gem 代码记得先 spring stop 才能重新加载你改过的代码)

再说你遇到的现象: 你的环境老是要重新新建数据库连接,而且还挺慢。这应该跟你本地数据库有关系,不像 rails 这边的问题。正常 rails 本地环境不需要如此频繁的建立数据库连接。建议从 mysql 这边找原因。

提供一个思路,你可以在ActiveRecord::LogSubscriber#sql源代码里加一些 debug 信息,然后新建一个 rails 项目,console 里用ActiveRecord::Base.connection_pool.send(:new_connection)模拟新建一个数据连接来看是不是也很慢。

piecehealth 回复

我链接的是阿里云的 mysql 数据库,我同事和我 database.yml 里同样的设置,他就好的,不会出现我这种情况,就我这样,我俩在不同地方办公,网络环境不一样,我猜是不是跟我使用的 wifi 有关

yfscret 回复

那就应该是你网络问题了。(以下是推论,没自己实际测试过)

当你改动代码的时候,rails 会清 databse connection https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railtie.rb#L248

然后新请求会尝试建立数据库链接,但是比较慢,就看到 log 了。console 用ActiveRecord::Base.connection_pool.send(:new_connection)单独测一下你连阿里云数据库需要多长时间吧

piecehealth 回复

单独发送 ActiveRecord::Base.connection_pool.send(:new_connection),马上就有结果,速度很快,我估计也是我网络的问题,我找机会换几个网络测测,还是非常谢谢你

yfscret 回复

经测试,explain 的问题确实是 newrelic 的行为

huacnlee 回复

经测试,explain 的问题确实是 newrelic 的行为

经过测试,发请求时候卡住一会,然后显示 set NAMES 这一行,是网络的原因,具体网络哪里的问题就不知道了,换个 wifi 就没这事了

yfscret 关闭了讨论。 10月14日 10:29
yfscret 重新开启了讨论。 11月07日 15:55

经过这 2 月的反复测试,终于搞明白是什么问题了,explain 的问题确实是 newrelic 的行为,set NAMES 这个是因为家里 wifi 链接的智能设备太多,超出服务商光猫拨号上网设备上限了(联通业务员说家庭光猫拨号上网设备上限是 5 个),上网超过 5 个设备,就会随机挤掉超出设备的网络链接,我电脑出现这个时候是因为被挤掉了,然后再联网的话,光猫就会重新拨号,最终业务员修改为路由器拨号后终于 ok 了,他说如果设备再多(超过 10 几个吧),还出现这问题的话就得换成商业宽带了。

yfscret 关闭了讨论。 11月07日 16:02
需要 登录 后方可回复, 如果你还没有账号请 注册新账号