AWS

【Aurora】RDS(MySQL)で長時間残っている無駄なプロセスをkillする

記事内に商品プロモーションを含む場合があります

MySQL でレコードを掴んでしまっているプロセスが発生するケースがあります。

例えば、特定のレコードをロックしたままトランザクションタイムアウトになったものの、ロールバックされないとか・・・。

Spring の @Transactional アノテーションの挙動に悩まされる場面が時々あるのですよね。

@Transactional(timeout = 10, rollbackFor = [Exception::class])

まあ、問題のプロセスを kill すれば解決なのですが、AWS の RDS では素直にいかないようで・・・。

今回は RDS で特定のプロセスを kill する方法を紹介します。

ロックプロセスの確認

MySQL で DB(ストレージエンジンは InnoDB とします)の状態を確認するには、以下のコマンドを実行。

SHOW ENGINE INNODB STATUS\G;

これでトランザクションの状態をチェックすることができます。

チェックすべき箇所は「TRANSACTIONS」の段落の最後の方。

以下のサンプルだと「—TRANSACTION」の項目ですね。

ここに、「MySQL thread id 9999」と書かれていますが、この 9999 がプロセス ID になります。

このプロセスを kill してあげれば、ロック自体の問題は解決なのですが・・・。

MySQLのkillコマンド

MySQL でプロセスを kill するには kill コマンドを使います。

おやっ、「You are not owner」という明らかに権限周りのエラーが出力されます。

どうやら RDS では、マスターユーザーに対して kill の実行権限はないようですね。

RDSのkillコマンド

RDS には以下のプロシージャが用意されています。

mysql.rds_kill(processID)

これを CALL コマンドで実行してあげればいいですね。

無事に実行でき、プロセスも消えました。

ちなみに実行中のクエリを終了させるには、以下のプロシージャを使います。

mysql.rds_kill_query(queryID)

ID が 9999 ならこんな感じ。

プロセスかクエリかは、information_schema.PROCESSLIST のテーブルの COMMAND カラムで判断ですね。

スレッドのコマンド一覧は下記のページで確認できます。

まとめ

RDS におけるプロセスやクエリの終了方法について紹介してきました。

プロセスを強制的に終了させるケースは滅多にないと思いますが、データベース周りの運用コマンドは最低限覚えておきたいですね。

コマンドの詳細は忘れたとしても、知識として持っているだけで十分。

いざ問題が発生した際に、焦らずに落ち着いて調査に入りたいですね。