If there is database page corruption, you may want to dump your
tables from the database with
SELECT ... INTO
OUTFILE. Usually, most of the data obtained in this
way is intact. However, it is possible that the corruption might
cause SELECT * FROM
statements or
tbl_nameInnoDB background operations to crash or
assert, or even cause InnoDB roll-forward
recovery to crash. In such cases, you can use the
innodb_force_recovery option to
force the InnoDB storage engine to start up
while preventing background operations from running, so that you
are able to dump your tables. For example, you can add the
following line to the [mysqld] section of
your option file before restarting the server:
[mysqld] innodb_force_recovery = 1
Only set
innodb_force_recovery to a
value greater than 0 in an emergency situation, so that you
can start InnoDB and dump your tables.
Before doing so, ensure that you have a backup copy of your
database in case you need to recreate it. Values of 4 or
greater can permanently corrupt data files. Only use an
innodb_force_recovery setting
of 4 or greater on a production server instance after you have
successfully tested the setting on separate physical copy of
your database. When forcing InnoDB
recovery, you should always start with
innodb_force_recovery=1 and
only increase the value incrementally, as necessary.
innodb_force_recovery is 0 by
default (normal startup without forced recovery). The
permissible nonzero values for
innodb_force_recovery are 1 to
6. A larger value includes the functionality of lesser values.
For example, a value of 3 includes all of the functionality of
values 1 and 2.
If you are able to dump your tables with an
innodb_force_recovery value of
3 or less, then you are relatively safe that only some data on
corrupt individual pages is lost. A value of 4 or greater is
considered dangerous because data files can be permanently
corrupted. A value of 6 is considered drastic because database
pages are left in an obsolete state, which in turn may introduce
more corruption into B-trees and other database structures.
As a safety measure, InnoDB prevents users
from performing INSERT,
UPDATE, or
DELETE operations when
innodb_force_recovery is
greater than 0.
1(SRV_FORCE_IGNORE_CORRUPT)Let the server run even if it detects a corrupt page. Try to make
SELECT * FROMjump over corrupt index records and pages, which helps in dumping tables.tbl_name2(SRV_FORCE_NO_BACKGROUND)Prevent the main thread from running. If a crash would occur during the purge operation, this recovery value prevents it.
3(SRV_FORCE_NO_TRX_UNDO)Do not run transaction rollbacks after recovery.
4(SRV_FORCE_NO_IBUF_MERGE)Prevent insert buffer merge operations. If they would cause a crash, do not do them. Do not calculate table statistics. This value can permanently corrupt data files. After using this value, be prepared to drop and recreate all secondary indexes.
5(SRV_FORCE_NO_UNDO_LOG_SCAN)Do not look at undo logs when starting the database:
InnoDBtreats even incomplete transactions as committed. This value can permanently corrupt data files.6(SRV_FORCE_NO_LOG_REDO)Do not do the log roll-forward in connection with recovery. This value can permanently corrupt data files. Leaves database pages in an obsolete state, which in turn may introduce more corruption into B-trees and other database structures.
You can SELECT from tables to
dump them, or DROP or
CREATE tables even if forced recovery is
used. If you know that a given table is causing a crash on
rollback, you can drop it. You can also use this to stop a
runaway rollback caused by a failing mass import or
ALTER TABLE. You can kill the
mysqld process and set
innodb_force_recovery to
3 to bring the database up without the
rollback, then DROP the table that is causing
the runaway rollback.
I came to this page after receiving the "error 2002 Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) when trying to connect" error, and read the instructions, and had some luck with them, without even getting all the way through the steps.
I put the force_recovery mode to 1, then restarted mysqld, exported the entire database (i expected to get an error when it got to the bad table, but i never had a problem). After dumping the database, i removed the force_recovery option from my.cnf and restarted the service, and after a few moments, it started back up, and the problem was gone.
I suspect that dumping the database to disk may have cleaned the filesystem's cache, maybe? Anyway, before dropping tables, try seeing if just exporting the database and restarting in normal mode will work (it may not; i may have just gotten lucky).