🕶️

Rollback Segment History List Lengthとは何なのか

2024/05/20に公開2

背景

システムを運用する中でAuroraのメトリクスで、Rollback Segment History List Lengthのメトリクスが急激に増加したことがありました。恥ずかしながらこのメトリクス自体を知らなかったので、このメトリクスは何者なのか、このメトリクスが増加すると何が発生するのかを調べたことを書いていきたいと思います。

Rollback Segment History List Length

MySQLのストレージ領域で発行されるundoログの履歴数を示したメトリクスである。

undoログ

MySQLのストレージエンジンであるInnoDBが発行するログの種類の一つです。他にはredoログなども存在します。有名どころのログであるslow queryやaudit logなどはストレージエンジンのログではありません。redoログについては下記記事が詳しいので、一読することをおすすめします。
https://shallow1729.hatenablog.com/entry/2021/04/19/003422

なぜ必要なのか

  • トランザクションのロールバックに使用する
  • 別のトランザクションによる変更を無視して、トランザクション開始時点での一貫したデータを参照できるようにする(過去のバージョンを参照できるようにする)。

どのタイミングでこのメトリクスが増加するのか

ドキュメントでも記載されていますが、以下の場合にメトリクスが増加するようです。

  • 実行時間の長いトランザクション (読み取りまたは書き込み)
  • 書き込み負荷が高い

InnoDB 履歴リストの長さが大幅に増加しました - Amazon Aurora

我々のシステムでも実行時間が長いトランザクションが実行されている際に、上記メトリクスが増加していることを確認しています。

なんかわからん

調べたものの全然しっくりきませんでした。
ということで、もう少しDBについて理解を深めた上で戻ってこようと思います。

DBの前提知識を整理する

色々記事や書籍を読み漁った内容を書き殴ってみます。

  • MySQLはDisk-Oriented DBである。設計思想はデータがメモリに乗り切らないことを前提に設計されたデータベースである
  • MySQLのストレージエンジンはInnoDBを使っており、MVCC(MultiVersion Concurrency Control)の仕組みを採用している。MVCCとは複数のレコードバージョンを許容することで、一貫したデータを参照させる考え方である。実行中のトランザクションがその行を参照しようとした時に最新のものではなく1つ前のデータを参照させる。この古いバージョンのデータを参照させるのに使用しているのがundo ログである
  • InnoDBのログは更新されることはなく、全て追記である。またログ形式はWAL(Write-Ahead-Log)であり、これはログを先行して書き込むことを意味する。目的はクラッシュリカバリ時にログからリカバリするためである
  • InnoDBはファジーチェックポイントを採用しており、その中でLSN(Log Sequence Number)を使用している(ARIES)。ファジーチェックポイントはbegin_checkpoint、last_checkpointというログレコードを持っており、ページがフラッシュされるとlast_checkpointレコードの値がbegin_checkpointレコードのLSNによって更新される。こうすることで常にチェックポイントが更新される(これ自信ない)
  • トランザクション分離レベルがリピータブルリードの場合のMVCCでは、各トランザクションは、開始から終了までのどのタイミングで実行された読み取りクエリであっても、トランザクション開始時点のバージョンのデータを読み取るために、undo レコードを遡って必要な行のバージョンを取得する

InnoDB Architecture
https://dev.mysql.com/doc/refman/5.7/en/innodb-architecture.html より引用

https://www.oreilly.co.jp/books/9784873119540/
https://www.shoeisha.co.jp/book/detail/9784798147406
https://sookocheff.com/post/databases/write-ahead-logging/
https://mond.how/ja/topics/emidxwxfpi42ikd/ztydn4om7804ds6
https://qiita.com/kumagi/items/67f9ac0fb4e6f70c056d
https://qiita.com/kumagi/items/14b6593a2e8ae0c56546
https://qiita.com/dennis_wang/items/52d025ce176cf1a6082d

undoログのライフサイクル

上記前提でundoログのライフサイクルとしてはこんな感じでしょうか。

  • SQL実行時にログが生成される
  • undoログを定期的に削除する(溜め続けないために)
  • ロールバック、クラッシュバック時にundoが使用される

まだまだ掘れるところではありますが、それはまた別の機会で記事にできればと思います。

全体像

増加すると発生しうること

Rollback Segment History List Lengthメトリクスが増加されるケースはドキュメントによると以下2通りでした。前提知識を元に考えてみます。

  • 実行時間の長いトランザクション (読み取りまたは書き込み)

「実行時間の長いトランザクション」については、該当トランザクションのundoログが残り続けるので、このメトリクスが増加すると想像できます。

  • 書き込み負荷が高い

「書き込み負荷が高い」については、シンプルにundoログを生成する頻度が高いことを示すと理解しています。

何を監視するか考える

上記諸々考えた上でRollback Segment History List Lengthが上昇するときに跳ねてくるであろうメトリクスを考えてみたいと思います。

  • DMLThroughputが悪くなっていないか
    • Rollback Segment History List Lengthが伸びている状況は書き込みが多くなっている状況になります。なのでその書き込み自体のスループット自体が悪くなっていないかをみることができます
  • ActiveTransactionsが残り続けていないか
    • トランザクション中はundoログ生成はできていますが、削除はできていません。そのため。あまりに長いトランザクションがあると古いログが残り続けるので、Rollback Segment History List Lengthのメトリクスが伸びることに繋がります
  • readでslow queryが発生していないか
    • 「DBの前提知識を整理する」でも書きましたが、MVCCでは古いバージョンを読み取れるようにしています。その影響でread系のクエリが悪化する可能性があります。理由は遡る必要があるundoログの数も増加するので、その遡る時間分クエリの性能が悪化するというイメージです。更新系クエリは、影響は大きくないだろうなと想像しています。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraMonitoring.Metrics.html

おわりに

DB面白い。

参考記事

https://tech.studyplus.co.jp/entry/2023/11/06/100000
https://studist.tech/aurora-rollback-history-slowdown-f5eb0d2a4e24
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/proactive-insights.history-list.html

tacomsテックブログ

Discussion

dehio3dehio3

Rollback Segment History List Lengthで痛い目見たので共有ですー
Rollback Segment History List Lengthのデータはディスク領域に保存される為、増加を放置するとAuroraMySQLだとVolumeBytesUsedも増加します💦
しかも増加したディスク領域はDBを論理再作成しないと解放されないので、ずっと課金対象として計上されるのでご注意ください!
https://zenn.dev/dehio3/scraps/e3660707859896

yo sanoyo sano

コメントありがとうございます!
なんと、早速チームに共有させていただきます!!