2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

cron+retry+DBで地獄を見た件。

Posted at

概要

アプリケーションにおいてそこで実装された機能の処理とcronにおいてデータベースの更新をすると、処理がかぶり、デッドロックが起こる場合がある。そうして負けた方のロールバックに巻き込まれてデータに不整合が起こるといった件で地獄を見たので共有。

起こった要因

ロックしている時間が長い

大量のINSERTをする+実行計画がindexである場合など様々スロークエリの状況が揃った場合に起こりやすくなっている。

Insertをした時にretryの処理を入れている(特にcron側)

あまり良くないとわかっていてもシステムを落とさないでしっかり動作させるためにこの処理入れているところもあるのではなかろうか。これが地獄を見た主たる原因。

改善策

  • SQLの実行計画の改善 => 処理の時間を短くすることでかぶる確率を下げる
  • cronの頻度を減らす => 上記に同じ。かぶる確率を下げる
  • retryをしない => 処理を落とさないためにその他施策を打つ必要はある

データがどういうことになってしまったか

アプリ側でINSERTなどをテーブルA, B, Cをロックしているとする。
その後、cron側がテーブルAとテーブルCをJOINしてSELECT->INSERTしに行こうとする。
しかしこの時、アプリ側でDBをロックしているのでROLL BACKが走る。
この時にリトライなどの処理を入れてしまうと、テーブルBのみINSERTされるといった現象が起きてしまう。ただ、INSERTはされているので、アプリの処理の書き方によっては、正常終了とみなされる。

処理 テーブルA テーブルB テーブルC
cronの処理 アクセス不可 アクセス不可
アプリの処理 ロック ロック ロック
2
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?