InnoDBのロールバックがあとどれくらいかかるかをなんとなく見積もる
mysql

InnoDBのロールバックがあとどれくらいかかるかをなんとなく見積もる

このエントリーをはてなブックマークに追加

こんにちは、DBAのたなかです。

MySQLに向かってテキトー(またはテキトーでない)な更新クエリーを放り投げたは良いけれど、なかなか返ってこなくてCtrl+Cで停止したり、killステートメントでスレッドを殺したり、もしくは流れ終わったけど想像通りにいかずにROLLBACKしたり。そんな経験ありませんか?

私はあります。というかこの記事書いてるという時点で何かを察していただけるとありがたい。

Undoセグメント(デフォルトではibdata1上にある)からデータを引っ張りだしてバッファプール上に展開する以上、InnoDBのロールバックはまあそれなりに重いわけで、というか更新そのものよりもロールバックの方がよっぽど重い。

それは重々承知の上なんだけれど、ロールバックしてる時というのは往々にして「動け! 動け! 動いてよ! 今動かなきゃ、今やらなきゃ、みんな死んじゃうんだ!」状態になっているので、せめてあとどれくらいでロールバックが終わるかを知りたいわけです。

で、私がいつも見ているのはこれ。

mysql> SHOW ENGINE INNODB STATUS\G
..
------------
TRANSACTIONS
------------
Trx id counter 22588
Purge done for trx's n:o < 22588 undo n:o < 0 state: running but idle
History list length 678
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 2, OS thread handle 0x7f6bd0094700, query id 13 localhost root init
show engine innodb status
---TRANSACTION 22275, ACTIVE 1397 sec rollback
ROLLING BACK 542497 lock struct(s), heap size 64420280, 100542496 row lock(s), undo log entries 52636267
MySQL thread id 1, OS thread handle 0x7f6bd00d5700, query id 8 localhost root init
ROLLBACK
--------
FILE I/O
--------
..

これは今、手でROLLBACKを叩いてロールバックしているところですが、TRANSACTION 22275, ..の次の行に、undo log entriesの記載があります。

これが今、このトランザクション内の操作でUNDOセグメントに載っているレコードの数。UNDOセグメントからレコードを全部引っ張り出せばロールバックが終わるので、これが0に近付いていくのを見て、なんとなく進捗を知ります。

SHOW ENGINE INNODB STATUSそのままの出力で何度も確認するのは辛いので、pager(標準出力をパイプに噛ませられるやつ)を噛ませてやったりします。

mysql> pager grep "undo log entries"
PAGER set to 'grep "undo log entries"'

mysql> SHOW ENGINE INNODB STATUS\G
ROLLING BACK 542497 lock struct(s), heap size 64420280, 100542496 row lock(s), undo log entries 39531691
1 row in set (0.69 sec)

mysql> SHOW ENGINE INNODB STATUS\G
ROLLING BACK 542497 lock struct(s), heap size 64420280, 100542496 row lock(s), undo log entries 6184252
1 row in set (0.63 sec)

終わりが見えてくると元気が出ますね。

それでは。


名無しのエンジニア
dev.mysql.comの歩き方(ドキュメント編)
スマホUI勉強会 -実装×UI/UX×ガイドライン-でおしゃべりしてきました。