ablog

不器用で落着きのない技術者のメモ

SHOW ENGINE INNODB STATUS の History list length

SHOW ENGINE INNODB STATUS の History list length の見方をメモ。

mysql> show engine innodb status\G

(中略)
------------
  TRANSACTIONS
------------
Trx id counter 0 80157601
Purge done for trx's n:o <0 80154573 undo n:o <0 0 
History list length 6
Total number of lock structs in row lock hash table 0
  • Trx id counter: 現在のトランザクションID。トランザクションが発行されるとカウントアップされる。
  • Purge done for trx's n:o: このトランザクションIDまでパージ済。Trx id counter からこの値を引くと存在するMVCCの行のバージョン数になる。
  • undo n:o : パージ中のUNDOログのレコード数
  • History list length: InnoDB の UNDO スペースのページ数(InnoDBのデフォルトのページサイズは 8KB、Aurora MySQL は16KB)。
  • 「Trx id counter」から「Purge done for trx's n:o」を引くと、MVCC の行のバージョン数になる。

参考

High Performance MySQL: Optimization, Backups, and Replication

High Performance MySQL: Optimization, Backups, and Replication

  • 作者: Baron Schwartz,Peter Zaitsev,Vadim Tkachenko
  • 出版社/メーカー: O'Reilly Media
  • 発売日: 2012/04/02
  • メディア: ペーパーバック
  • クリック: 2回
  • この商品を含むブログを見る

  • Appendix B. MySQL Server Status
    • SHOW ENGINE INNODB STATUS
      • TRANSACTIONS

TRANSACTIONS
This section contains a little summary information about InnoDB transactions, followed by a list of the currently active transactions. Here are the first few lines (the header):

1  ------------
2  TRANSACTIONS
3  ------------
4  Trx id counter 0 80157601
5  Purge done for trx's n:o <0 80154573 undo n:o <0 0
6  History list length 6
7  Total number of lock structs in row lock hash table 0

The output varies depending on the MySQL version, but it includes at least the following:

  • Line 4: the current transaction identifier, which is a system variable that increments for each new transaction.
  • Line 5: the transaction ID to which InnoDB has purged old MVCC row versions. You can see how many old versions haven’t yet been purged by looking at the difference between this value and the current transaction ID. There’s no hard and fast rule as to how large this number can safely get. If nothing is updating any data, a large number doesn’t mean there’s unpurged data, because all the transactions are actually looking at the same version of the database. On the other hand, if many rows are being updated, one or more versions of each row is staying in memory. The best policy for reducing overhead is to ensure that transactions commit when they’re done instead of staying open a long time, because even an open transaction that doesn’t do any work keeps InnoDB from purging old row versions.Also in line 5: the undo log record number InnoDB’s purge process is currently working on, if any. If it’s “0 0”, as in our example, the purge process is idle.
  • Line 6: the history list length, which is the number of pages in the undo space in InnoDB’s data files. When a transaction performs updates and commits, this number increases; when the purge process removes the old versions, it decreases. The purge process also updates the value in line 5.
  • Line 7: the number of lock structs. Each lock struct usually holds many row locks, so this is not the same as the number of rows locked.

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

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に近付いていくのを見て、なんとなく進捗を知ります。

InnoDBのロールバックがあとどれくらいかかるかをなんとなく見積もる | GMOメディア エンジニアブログ
  • innodb_purge_threads
    • あまり意識している人はいない気がするパラメータ。5.6ではデフォルト1、5.7ではデフォルト4となっています。更新が多く、show engine innodb status\Gを見た場合に History list length [数字] の数字が肥大化していっている場合は増やす事が推奨されます。但しMySQLの再起動が必要です。History list lengthが増えているということはundo領域(デフォルトではibdata1と同居)が肥大化する要因となるため気を配ったほうが良いです。またHistory list lengthが大きくなっていくと基本的には性能が劣化する傾向があります。
    • 何か時間の超絶かかるSELECTとかが実行されている場合もHistory list lengthが増える事があります。その場合は増やしてもたいした効果はないと考えられます(だってpurge出来ないし)
    • なお、過去の記憶ですが、無駄に増やしすぎるとコンテキストスイッチが増加して少ない設定の時よりも性能が下がるので程ほどに設定して下さい。5.7なら殆どのケースでデフォルトで十分だと思います。
MySQL関連のパラメータ(主にInnoDB)について - hiroi10の日記

  • The InnoDB Shared Tablespace (ibdata1) is Growing in Spite of Using innodb_file_per_table (Document ID 1472410.1)
  • How to Investigate InnoDB Lock Issues? (Documnet ID 1531774.1)