InnoDBのテーブルが突然壊れて起動しなくなったので対応

      2017/07/20

CopyContentDetctorで障害が発生したのでメモです。

 

■障害メールが来る

以下のようなMysqlに接続できないメールが沢山届いて来ました。確認するとDBが停止していました。特に作業などしていなかったので突然でした。

Database connection "Mysql" is missing, or could not be created.

 

■InnoDBの破損

mysqlが停止して接続できなくなっていました。以下のログとバイナリ情報がひたすらダンプされて、mysqlの復帰を試みる→失敗→サーバを停止→復帰を試みる・・・・というのを繰り返していました。これは、世間一般で言うところの「InnoDBのテーブルが破損した状態」というやつです。

 

2017-07-17 00:58:05 7f2d79b00700 InnoDB: uncompressed page, stored checksum in field1 1858044349, calculated checksums for field1: crc32 12293298, innodb 2690990177, none 3735928559, stored checksum in field2 0, calculated checksums for field2: crc32 12293298, innodb 4165938056, none 3735928559, page LSN 5543 1561127476, low 4 bytes of LSN at page end 0, page number (if stored to page already) 226435, space id (if created with >= MySQL-4.1.1 and stored already) 1421
InnoDB: Page may be an index page where index id is 3218
InnoDB: (index "index_id" of table "db"."tables")
InnoDB: Corruption of an index tree: table "db"."tables", index "index_id",
InnoDB: father ptr page no 839167, child page no 839123
PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 4; hex 800a0aff; asc     ;;
 1: len 4; hex 80b26290; asc   b ;;
 2: len 4; hex 962f59f2; asc  /Y ;;
 n_owned: 0; heap_no: 2; next rec: 142
PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 4; hex 800a0aff; asc     ;;
 1: len 4; hex 80b26290; asc   b ;;
 2: len 4; hex 962f5738; asc  /W8;;
 3: len 4; hex 000ccdff; asc     ;;
 n_owned: 0; heap_no: 131; next rec: 2855
InnoDB: You should dump + drop + reimport the table to fix the
InnoDB: corruption. If the crash happens at the database startup, see
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/forcing-innodb-recovery.html about
InnoDB: forcing recovery. Then dump + drop + reimport.
2017-07-17 00:58:05 7f2d79b00700  InnoDB: Assertion failure in thread 139833291835136 in file btr0btr.cc line 1466
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
15:58:05 UTC - mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed,
something is definitely wrong and this may fail.

 

ログを見てみると、indexのCHECKSUM的なのが合わないからだめです。というのが出ています。INDEXの情報が壊れたってことでしょう。悲しい。

予兆として、mysqld.logに以下のようなログが数回出ているのを確認しました。この時間帯、ちょうどデータのアーカイブバッチが実行されていて少しだけデータ削除が発生していました。壊れかけのデータの対象レコードが削除されたために致命傷になって上記のエラーが発生して起動しなくなった。というのが今回の予測です。

InnoDB: Corruption of an index tree: table "database"."tables", index "index_name",

 

■解決方法を確認と実施

URLを確認して見ます。内容を確認すると、【リカバリとかを省略して、一旦起動させるからdumpとかしてデータを戻せ】ということみたいです。

https://dev.mysql.com/doc/refman/5.6/ja/forcing-innodb-recovery.html

 

この数字を1から順番に変更していって起動したら、そこからバックアップを取るということみたいですね。4以上になるとデータの変更が発生するみたいで、データの欠落等が発生する可能性もあります。DBのファイルを直接cpコマンドなどでバックアップを推奨されています。今回は【innodb_force_recoverty = 2】することで起動しました。ただし、この状態だと起動はするもののテーブルの変更等は出来ない状態です。ここからmysqldump→リカバリをする必要があります。

[mysqld]
innodb_force_recovery = 1

 

■結局の対応

今回は、マスターサーバを復帰しようとすると時間かかりすぎると判断して、DBのマスターとスレーブの入れ替えを実施してとりあえずサービス復帰完了です。停止から約15分くらいでした。後ほどすべてのデータを削除して、新マスターのデータを配置して作業完了しました。

壊れた原因ですが、前回の【waiting for table metadata lock でDBが死んだ】辺りが非常に怪しい。データ量がとても多くなってきたので、データ管理方法の変更や対策を考えないといけなくなってきました。

 

■追記 Mysqlの不具合の可能性

また、変なエラーが出てました。何か起こる前に予防として全部やり直しです。緩やかに破壊されていくっぽいので今のうちになんとかします。

InnoDB: tried to purge sec index entry not marked for deletion in
InnoDB: index "index_name" of table "db_name"."table_name"
InnoDB: tuple DATA TUPLE: 3 fields;
 0: len 4; hex 80b8b636; asc    6;;
 1: len 4; hex 80000000; asc     ;;
 2: len 4; hex 9b2bb66b; asc  + k;;

InnoDB: record PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 4; hex 80b8b636; asc    6;;
 1: len 4; hex 80000000; asc     ;;
 2: len 4; hex 9b2bb66b; asc  + k;;

 

これはまた、Indexが壊れているかもなエラーメッセージですね。探してみるとフォーラムに以下がありました。

https://bugs.mysql.com/bug.php?id=73767

このあたりの不具合を踏んでる可能性があります。真ん中あたりで、「クラスタリングインデックスとセカンダリインデックスの不整合が発生する再現性のものすごく低い不具合があるんだー」とかあります。悲しい。mysqlのマイナーバージョン上げてみて様子を見ます。

 

今後共CopyContentDetectorをよろしくお願いいたします。

megane

megane

最近、個人事業主から法人へと進化しました。 エンジニア歴13年位です。PHPとかMysqlを使ってWebシステムを構築します。 Javaも書きます。 CakePHPも使います。 サーバのチューニングもごりごりやります。 あと、お肉と自動車が好きです。Twitterとか申請どうぞ。

 - mysql, コピペチェック