Rails 如何在线上 Rails 环境中对刚刚执行对 SQL 进行 show profile?

woshishui · 2018年01月19日 · 最后由 woshishui 回复于 2018年01月22日 · 1041 次阅读

各位大佬好,我是一个 rails 新手,最近遇到了一点问题:

某一条 sql 在线上环境中有一定概率 (5% 左右) 出现较长的执行时间,而线下环境无法复现。

现在已经进行对思考和简单实践:

  1. 初步怀疑是innodb_buffer_size太小导致,同时查看了cache,发现命中情况并不理想,也怀疑存在 cache lock 有影响。接下来准备调整参数。

  2. 如果想看看具体是哪里慢了,我想到的办法是把过去的 N(15 <= N <= 100) 条 profile 都记录出来,然后 parse 出最近的几条(需要的 sql)query id,然后执行 show profile for query xxx;

  3. 存在的疑惑: profile 的打开与否似乎是 session 级别的(不确定,但是实验现象表面如此),那么我需要每次都在需要定位的模块开头 set profile = 1,然后才能执行下面的操作吗? 我的线上环境是 多进程 + 多线程,那么每一个线程拿到的 connecrtion 是不是只记录了对应的 sql 呢?这样无论多高的并发,我都可以拿到最近执行的 sql profile 情况而不用担心
    被其他 sql 冲走。

    请问我这样的想法有没有问题?害怕在线上这样搞出问题,请指教。

1 楼 已删除

可以使用 rack-mini-profiler这个 gem,然后在production环境进行权限验证

# inside your ApplicationController

before_action do
  if current_user && current_user.is_admin?
    Rack::MiniProfiler.authorize_request
  end
end

把当时你看到那个慢的 SQL 的执行日志(SQL 语句和执行时间)放出来看看

然后你拿那个 SQL 到你线上的 MySQL 里面去 EXPLAIN 看看

你开发环境不出问题,有可能是开发环境数据太少了

huacnlee 回复

已经看了 profile,可能是 rails 配置的问题

需要 登录 后方可回复, 如果你还没有账号请 注册新账号