25

I have some tables that are partitioned and have several indexes on a replicated slave. After copying the snap shot (verified safe) to a new slave and upgrading mysqld from 5.1.42 to 5.5.15 and restarting replication, I'm getting InnoDB crashes with the error message "Invalid pointer ..."

These errors have happened across 2 servers with different hardware and O/S. After running:

ALTER TABLE .... COALESCE PARTION n;

the problem goes away for that table.

My question is larger in scope, though, and that is "How do you identify InnoDB table corruption?" or rephrased "How do you assess InnoDB table health?" Is "CHECK TABLE" the only tool available to identify problems pre-crash?

Not sure if it matters, but the crashes occurred running: Version: '5.5.15-55-log' socket: '/opt/mysql.sock' port: 3306 Percona Server (GPL), Release rel21.0, Revision 158

Derek Downey
  • 23,440
  • 11
  • 78
  • 104
randomx
  • 3,934
  • 4
  • 30
  • 43
  • 2
    Hi Randy! I think the responses here are credible - InnoDB identified its own corruption. Maybe you should rephrase your question, why would what you doing cause InnoDB to be corrupt? – Morgan Tocker Sep 30 '11 at 02:47

4 Answers4

21

Morgan gives a hint in his comment that InnoDB is constantly checking for corrupted pages by doing checksums on the pages it reads. If InnoDB finds a checksum mismatch, it will crash stop the server.

If you want to speed that process up (instead of waiting for InnoDB to read the corrupted page), you can use innochecksum:

Because checksum mismatches will cause InnoDB to deliberately shut down a running server, it can be preferable to use this tool rather than waiting for a server in production usage to encounter the damaged pages.

An interesting caveat:

innochecksum cannot be used on tablespace files that the server already has open. For such files, you should use CHECK TABLE to check tables within the tablespace.

So yes, for an online table CHECK TABLE is probably the tool (or as pointed out in another answer mysqlcheck if you want to do more than a single database at a time.)

If you can shut down your database you can force it the checksums using innochecksum

Anecdotal: On a innodb tablespace of 29GB (with innodb_file_per_table=1), this script took about 2 Minutes

#!/bin/bash
for i in $(ls /var/lib/mysql/*/*.ibd)
do
  innochecksum -v $i
done

As a bonus, though, since you are running Percona, they implemented a new method for fast innodb checksum. I've never used it, but it might speed up the process.

Derek Downey
  • 23,440
  • 11
  • 78
  • 104
  • 1
    Gonna give it a try here, seems to be the solution @randymelder is looking for +1 – marcio Sep 30 '11 at 01:26
  • 2
    Percona server has some other nice features. See innodb_corrupt_table_action http://www.percona.com/doc/percona-server/5.5/reliability/innodb_corrupt_table_action.html (!!) – Morgan Tocker Sep 30 '11 at 03:01
  • @DTest : innochecksum is the way to go. This one's a keeper. +1 !!! – RolandoMySQLDBA Sep 30 '11 at 10:15
  • @DTest : Hats off to you today on this one !!!! – RolandoMySQLDBA Sep 30 '11 at 10:16
  • @MorganTocker Interesting. Going to have to get my knowledge vacuum and do some research into percona – Derek Downey Sep 30 '11 at 11:17
  • Percona, great surprise of the day to me. – marcio Oct 01 '11 at 05:52
  • @DTest You read my question and answered it with probably the best possible answer. Many of my questions are rhetorical in nature as attempt to stimulate discussion and improve the body of knowledge on stack exchange. My intention was to point out that InnoDB has few tools to help out DBAs. I'm really surprised no one mentioned "SHOW ENGINE INNODB STATUS" even though it doesn't target a single table. – randomx Oct 03 '11 at 04:46
  • Good Bounty Hunting on this one !!! – RolandoMySQLDBA Oct 03 '11 at 22:18
7

WARNING: before trying any of these instructions it is strongly recommended to verify that there is a healthy backup of your database in hands, just in case. (thanks to @Nick for the warning)

Try to use the mysqlcheck command. On a terminal:

mysqlcheck -u username -p --databases database1 database2

This command will output a list of all tables and a status telling you if there was some kind of corruption:

table1  OK
table2  OK
table3  OK
tableN  OK

With that in hands you will already know which tables you have to repair. Just in case you want to repair everything at once:

mysqlcheck -u username -p --auto-repair --databases database1 database2 

More about mysqlcheck: http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html

Note: you tagged your question with . I had no clue of what was that so I googled. It seems to be a fork of MySQL, but I have no reason to believe the commands are incompatible (fingers crossed).


Somebody pointed me to this guide that has more specific instructions for InnoDB database recovery for more critical situations where the entire database does not start: http://www.softwareprojects.com/resources/programming/t-how-to-fix-mysql-database-myisam-innodb-1634.html

Derek Downey
  • 23,440
  • 11
  • 78
  • 104
marcio
  • 345
  • 3
  • 6
  • 1
    mysqlcheck is a synonym for 'check table ...' -1 – randomx Sep 27 '11 at 17:31
  • http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html – randomx Sep 27 '11 at 17:55
  • Not true. First, mysqlcheck is a command-line utility and CHECK TABLE is a SQL statement (it's like to compare orange to lemmons).Also, you CAN'T check an entire database with CHECK TABLE without including ALL the table names in the SQL statement (it would not be very productive too) – marcio Sep 27 '11 at 19:03
  • And mysqlcheck has an option to --auto-repair the tables that are corrupted while CHECK TABLE only checks if the tables are corrupted or not, but can't make any repair. – marcio Sep 27 '11 at 19:04
  • Conclusion: they are definitely not synonym. They might have some intersections, but mysqlcheck can do much more for you in this specific case. – marcio Sep 27 '11 at 19:10
  • And to be even more conclusive, the documentation link you sent says: ">mysqlcheck uses the SQL statements CHECK TABLE, REPAIR TABLE, ANALYZE TABLE, and OPTIMIZE TABLE in a convenient way for the user. It determines which statements to use for the operation you want to perform." – marcio Sep 27 '11 at 19:11
  • What are the implications of using --auto-repair? Is there any chance for data loss? I would edit these caveats, if any, into your answer so the careless reader is not surprised when they come across your answer and just blindly run the command against their databases. – Nick Chammas Sep 27 '11 at 19:30
  • Humm, that's an excellent point @Nick. I had to repair databases only in really rare situations and that mysqlcheck command worked like miracle. But I only used it after double check if there was a working backup from the corrupted databases. Better to clarify this. Good point. – marcio Sep 27 '11 at 19:39
  • 3
    @randymelder - You are wrong to say mysqlcheck is a synonym for CHECK TABLE. The documentation you linked to states: "mysqlcheck uses the SQL statements CHECK TABLE, REPAIR TABLE, ANALYZE TABLE, and OPTIMIZE TABLE in a convenient way for the user. It determines which statements to use for the operation you want to perform, and then sends the statements to the server to be executed." That is not a synonym; that is a user interface to a collection of statements. – Nick Chammas Sep 29 '11 at 21:50
  • @Nick - Yes, but you are splitting hairs. The question is about InnoDB. Please describe how any of what mysqlcheck does can detect problems in InnoDB tables. – randomx Sep 29 '11 at 22:45
  • @randymelder - Err, you asked about detecting corruption, and mysqlcheck finds and fixes corruption. For InnoDB, it's true that mysqlcheck will be unable to fix the corruption, it can just find it. In that case you'll have to use mysqldump and the mysql to export and reload the data (search for "InnoDB" on that page). – Nick Chammas Sep 29 '11 at 23:03
7

According to MySQL 5.0 Certification Study Guide, Page 443,444 Section 30.4:

You can check InnoDB tables by using the CHECK TABLE command or using a client program to issue the statement for you. However, if an InnoDB table has problems, you cannot fix it by using REPAIR TABLE because that statement applies only to MyISAM.

If a table check indicates that an InnoDB table has problems, you should be able to restore the table to a consistent state by dumping it with mysqldump, dropping it, and recreating it from that dump.

In the event of a crash of a MySQL Server or on the host on which it runs, some InnoDB tables might need repairs. Normally, it suffices simply to restart the server because the InnoDB storage engine performs auto-recovery as part of its startup sequence. In rare cases, the server might not start up due to the failure of InnoDB auto-recovery. If that happens, use the following procedure:

  • Restart the server with the --innodb_force_recovery option set to a value in the rage from 1 to 6. These values indicate increasing levels of caution in a avoiding a crash, and increasing levels of tolerance for possible inconsistency in the recovered tables. A good value to start with is 4.

  • When you start the server with --innodb_force_recovery set to a non-zero value, InnoDB treats the tablespace as read-only. Consequently, you should dump the InnoDB tables with mysqldump and then drop them while the option is in effect. Then restart the server without the --innodb_force_recovery option. When the server comes up, recover the InnoDB tables from the dump files.

  • If the preceding steps fail, it's necessary to restore the InnoDB tables from a previous backup.

Please read MySQL Docs on InnoDB Forced Recovery  

JYelton
  • 457
  • 1
  • 5
  • 17
RolandoMySQLDBA
  • 182,700
  • 33
  • 317
  • 520
  • 3
    FWIW, the certification guide has a very politically correct answer :) If you CHECK TABLE on an InnoDB table and it actually is corrupt, it will never return as "corrupt", it will crash the server. The statement is almost obsolete in InnoDB, because every time you read InnoDB pages it is checking for corruption (via page checksums). – Morgan Tocker Sep 27 '11 at 21:19
2

I wonder what happens if anyone uses InnoDB data created via InnoDB Plugin and then switch to another version of InnoDB. That could create possible page corruption in the eyes of mysqld.

Note what the MySQL Documentation on InnoDB File Format says about this possibility :

In general, a newer version of InnoDB may create a table or index that cannot safely be read or written with a prior version of InnoDB without risk of crashes, hangs, wrong results or corruptions. The InnoDB Plugin introduces a new mechanism to guard against these conditions, and to help preserve compatibility among database files and versions of InnoDB.

I would scrap the data on the slave. In fact, I would just use brute force by getting a logical dump (mysqldump) of the data:

  • Drop all databases using InnoDB on the slave
  • Shutdown mysql on the slave
  • Delete ibdata1, ib_logfile0, and ib_logfile1 on the slave
  • Start mysql on the slave, letting ibdata1, ib_logfile0, and ib_logfile1 get recreated
  • mysqldump the data from the master into the slave

My original anwser posted is considered 'old school'. Yet, in this case, I would definitely look into the file formats being used by .ibd and/or ibdata1.

RolandoMySQLDBA
  • 182,700
  • 33
  • 317
  • 520