LoginSignup
1
1

More than 5 years have passed since last update.

ActiveRecord::LockWaitTimeoutが発生したときにtransactionでハマってた

Last updated at Posted at 2019-04-12

背景

railsでウェブサービスを作っています。ありがたいことにユーザー数も増えてきました。そこで起きたことについてのメモです。

結論

ActiveRecord.transactionを貼っていたことが原因でLockWaitTimeoutが発生していました。

before

ActiveRecord.transaction do
  users.each do |user|
    user.do_something
    user.profile.do_something
  end
end

after

users.each do |user|
  ActiveRecord.transaction do
    user.do_something
    user.profile.do_something
  end
end

「transactionを全体に貼るなよ」というのはあると思いますが、お金の関わるところだったので全体で処理が完了するように担保したかったという背景もあり。。

起きたこと

ユーザー数が増えてきたタイミングから ActiveRecord::LockWaitTimeout が発生するようになりました。

調査1(パフォーマンス・チューニング)

まずはログを見ましたが、アクセスが増えてるわけでも重い処理が走っているわけでもなさそうでした。
ということでnginx / puma / mysql の設定を疑いました。

nginx

ワーカープロセス数は auto になっていたので自動でコア数に合わせて作成されます

/etc/nginx.conf
worker_processes auto;

puma

pumaのドキュメントより
ワーカー数→CPUコア数 ~ 1.5倍
スレッド数→16
が良いそうです。

RAILS_MAXTHREADS = 16
WEB_CONCURRENCY = CPU_NUM * 1.5 = xx
config/puma.rb
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
threads threads_count, threads_count
workers ENV.fetch("WEB_CONCURRENCY") { 2 }

mysql

RAILS_MAXTHREADS = 16
WEB_CONCURRENCY = CPU_NUM * 1.5 = xx
config/database.yml
pool: <%= ENV['RAILS_MAX_THREADS'] || 5 %>

結果

ユーザーの接続数などが原因かと思っていましたがそんなこともなくLockWaitTimeoutは引き続き発生していました。

調査2

ログ見ても特に問題点がなさそうだったので、ダメ元で社内の人に確認すると「運用のとある処理中」にLockWaitTimeoutが発生していることが判明。
ユーザーの動きとは別のものがトリガーで起きていたようです。

該当するソースを読んだらtransactionを貼っていて、修正したら発生しなくなりました。

最後に

ActiveRecord::LockWaitTimeout
まわりで調べても設定まわりの話が多くメモ的に残しておこうと思いました。どなたか同じように詰まっている方のお力に慣れれば幸いです。

ActiveRecord.transactionが何をしているか気になったので追ってみました。

ソースを読む。

多分データベースのトランザクションを開始してる。

mysqlのトランザクションのかかり方は以下のURLより
http://bluerabbit.hatenablog.com/entry/2013/12/07/075759
https://qiita.com/dorarep/items/d7d767e1bceb2d5649a7

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1