この記事は「MySQL Advent Calendar 2023」の14日目の記事です!
一言で書くと
InnoDBはdiskに書くときページ単位でCRC計算してるそれを使って検出してる
本文
MySQLに限った話ではないですがデータ自体が破損するケースは往々にしてあります。よくある(?)例としては以下のような原因があります。
- ハードウェア起因
- ソフトウェア起因
- 突然のシャットダウン(カーネルパニック、電源断、コンセントブチ抜き...)
- ファイルシステムエラー
- ヒューマンエラー(コマンドミスとか悪意ある人物が侵入してきたとか)
こういったことが起きても問題とならないようにInnoDBではchecksumを用いた書き込みを行っています。InnoDBでは、データの整合性を保つために、ディスクには16KBのブロック単位でデータを書き込む必要があります。これはトランザクションのAtomicの担保を意味し書き込み操作が完全に行われるか、全く行われないかのどちらかであることを意味します。InnoDBは各ブロックにチェックサムを計算し、保存します。これにより、データの整合性を保証し、ページの破損を検出することができます。
ページ破損を検出したら
MySQLのエラーログに以下のようなメッセージが出力されます。MySQL、(特にInnoDBストレージエンジン)がページ破損を検出したことを示しています。(InnoDBはページ番号4651のページで破損を検出したことも書かれていて、これは、チェックサムの不一致によって確認されています。)
InnoDB: Page may be an index page where index id is 22 InnoDB: (index "PRIMARY" of table "test"."t") InnoDB: Database page corruption on disk or a failed InnoDB: file read of page 4651. InnoDB: You may have to recover from a backup. InnoDB: It is also possible that your operating InnoDB: system has corrupted its own file cache InnoDB: and rebooting your computer removes the InnoDB: error. InnoDB: If the corrupt page is an index page InnoDB: you can also try to fix the corruption InnoDB: by dumping, dropping, and reimporting InnoDB: the corrupt table. You can use CHECK InnoDB: TABLE to scan your table for corruption. InnoDB: See also http://dev.mysql.com/doc/refman/5.6/en/forcing-innodb-recovery.html InnoDB: about forcing recovery. InnoDB: Database page corruption on disk or a failed InnoDB: file read of page 4651. InnoDB: You may have to recover from a backup.
こうなってしまったらあとはログや以下の記事にも書かれているようにリカバリ処理を実行する必要があります。(ちなみにクラッシュ後に自動的に再起動されるように設定する方法は、使用しているオペレーティングシステムとその管理システムに依存します。systemdとかでも自動起動とかは可能です)
innodb_force_recoveryをつけて再起動することで壊れ方次第ですが復旧することができます(クラッシュリカバリは過去に色々書いてるのでみていただければと)
innodbのチェックサムアルゴリズムは指定できる
ディスクブロックに格納されている checksum を生成および検証する方法はinnodb_checksum_algorithm
で指定することができるようです。デフォルト値はcrc32
。innodbを指定するとInnoDB固有のチェックサムアルゴリズムを使用するらしいです。これは、古いバージョンのMySQLで標準的に使用されていたアルゴリズムとのこと。noneを指定することもできるらしいです。整合性を無視してパフォーマンスが欲しい場面とかでは有効なのでしょうか。(チェックサムハードウェアアクセラレーターを導入することでハードウェアの資源を借りつつみたいな世界がどこかにあるのかなと思いましたが知ってる方いたら教えてください)
innochecksum オフラインでチェックサムの整合性確認ができる
innochecksumはMySQL で使用される InnoDB ストレージエンジンのテーブルスペースファイル(.ibd ファイル)のチェックサムを検証および再計算するためのコマンドラインツールです。InnoDBはページの破損を検出した時点で停止するのでその状態でこのツールは、InnoDB テーブルスペースのページの整合性をチェックするのに役立ちます。当たり前ですがオンラインでやろうとすると整合性が取れてるページでも不整合ありと出力したりします。(5.7以降だとどうやらオンラインだとそもそもエラーになるらしいです。)
# 実行イメージ $ innochecksum -d ibdata1
終わりに
データ破損。怖いですね(?)