Restore a corrupted table - mysql

A few days ago my whole server decided to crash itself. Luckily for me, I managed to recover the data folder from my MySQL installation.
The bad part is that not all my tables work as they did before. For example: my users table is useless because it doesn't have any structure anymore but only the rows within it (the .frm and .ibd files). I tried the following query to resolve this problem:
REPAIR TABLE users USE_FRM
Sadly, this showed me the error 'Can't open table' and now I still haven't managed to restore this table.
If anyone could help me out with this problem, I'd realy appreciate it!
I would be happy to share the ibd and frm files if needed.

You may have a try on this:
Use the USE_FRM option only if you cannot use regular REPAIR modes!
Telling the server to ignore the .MYI file makes important table
metadata stored in the .MYI unavailable to the repair process, which
can have deleterious consequences:[.....]
Also you may try to create the .MYI file from scratch like this:
REPAIR TABLE tablename USE_FRM
You may also check these references:
How to Repair MyISAM Tables
Recovering Innodb table Corruption

Related

InnoDB: Cannot open table from the internal data dictionary of InnoDB though the .frm file for the table exists

I am running Windows 10 with XAMPP and several dozen Drupal sites installed on localhost. Everything has been working fine for months.
This morning I performed a Windows restore from a restore point two days ago to get rid of an unwanted Windows update. After I did that, my MySQL stopped working. I tried deleting the file ibdata1 (I now know that that was a bad idea), but when things got worse, I restored the initial ibdata1 that I'd deleted. All the table data (.frm and .ibd files) is still in C:\xampp\mysql\data. Now MySQL will at least start, but all the tables are "gone"... I can load phpMyAdmin in the browser, and when I drop down the databases at left, all the tables show... but when I try to click on one, it tells me "table not found."
In mysql_error.log there are several errors like InnoDB: Cannot open table mysql/slave_master_info from the internal data dictionary of InnoDB though the .frm file for the table exists. There is a URL mentioned in the error message that supposedly tells you how to resolve this issue, but it is uninformative.
I don't think ibdata1 is corrupted... and all the articles regarding recovering data are complicated to a degree that is insanely out of proportion to the problem. No one has a simple spelled-out solution. Am I Googling wrong? This has happened to me at least twice before, and each time the problem spontaneously resolved itself before I was able to start following the 10-hour-long procedures I found online. Not this time, unfortunately. Surely I'm missing something simple. I had hundreds and hundreds of tables in a few dozen databases, and it seems hopeless to try to find the schema for each one and manually plug it in, which is what most recovery articles seem to suggest.
Shouldn't the database just know how to read the .frm and .ibd files, and, you know... work? It feels like there's just one value out of place somewhere, and if I could just find it, everything would just "pop" back into place.
What did the work for us was this link (Restoring Orphan File-Per-Table ibd Files).
In brief, you do:
ALTER TABLE ..... DISCARD TABLESPACE;
For each affected table.
Then, for each affected table:
ALTER TABLE .... IMPORT TABLESPACE; SHOW WARNINGS;
You could do that on the same schema or create a new schema in other database and copy all *.ibd files. In this case:
Create the new schema with table definitions.
Do the discard tablespace for all tables.
Copy the new *.ibd files to the right folder of new schema.
Do de import tablespace for all tables.
IMPORTANT! It's better that the new schema has the same name as the old one.
What worked for me:
https://dba.stackexchange.com/a/42932
My dbs was InnoDB, so there is a problem with id and when upgrading the macos, I got this. I will quote the main part:
You must have:
-ibdata1
-ib_logfile0
-ib_logfile1
-.FRM files from your mysql_database folder
-Fresh installation of MAMP / MAMP Pro that you are willing to destroy (if need be)
SSH into your web server (dev, production, no difference) and browse to your mysql folder (mine was at /var/lib/mysql for a Plesk
installation on Linux)
Compress the mysql folder
Download an archive of mysql folder which should contain all mySQL databases, whether MyISAM or innoDB (you can scp this file, or move
this to a downloadable directory, if need be)
Install MAMP (Mac, Apache, MySQL, PHP)
Browse to /Applications/MAMP/db/mysql/
Backup /Applications/MAMP/db/mysql to a zip archive (just in case)
Copy in all folders and files included in the archive of the mysql folder from the production server (mt Plesk environment in my case)
EXCEPT DO NOT OVERWRITE:
-/Applications/MAMP/db/mysql/mysql/
-/Applications/MAMP/db/mysql/mysql_upgrade_info
-/Applications/MAMP/db/mysql/performance_schema
In my case, I was restoring the backup (done by galera-arbitrator and xtrabackup. Using the first one we took state-snapshot and using the last one we backed up the physical data) for Percona_XtraDB_Cluster. So, after placing the backed up data to the dir /var/lib/mysql of the new mysql server, we did the following select query and got error.
$ mysql -uroot -p$MYSQL_ROOT_PASSWORD -h<NEW_SERVER_HOST_NAME> -e 'show columns from <MY_DB>.<MY_TABLE>'
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1146 (42S02) at line 1: Table 'playground.equipment' doesn't exist
And the server log was:
[Warning] InnoDB: Cannot open table <MY_DB>/<MY_TABLE> from the internal data dictionary of InnoDB though the .frm file for the table exists. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting.html for how to resolve the issue.
We just restarted the container the new data. That's it
Just rename slave_master_info.frm to slave_master_info.BAK and that's it. Restart the mysql service.

Why does renaming a database require copying data?

Using phpMyAdmin, I tried to rename my 6GB database, only to discover that the operation takes a couple of hours. According to this SO question, it sounds like renaming a database requires creating a new database and copying the data over. Why isn't the name just a pointer to some text that can be changed at will?
Edit on 14 March 2016
I originally accepted Gandalf's answer because I could not replicate the DB renaming taking so long. But this long renaming process is happening again. Here is a screenshot of phpMyAdmin hanging:
And here is a screenshot of the results from SHOW PROCESSLIST when connecting directly to the MySQL server:
It looks like the query is spinning on adding a constraint. I'm pretty sure the command that phpMyAdmin ran was:
RENAME TABLE harmonizome_temp TO harmonizome;
This is probably necessary to ensure database integrity if there's an error during the process.
Information about the database is stored in both the filesystem (each database is a directory) and also in the INFORMATION_SCHEMA database. When you rename a database, both have to be updated. If it simply renamed the directory and updated INFORMATION_SCHEMA, there would be a period of time when these are out of sync. And if the process is aborted at this stage, the database will be corrupted.
By copying the data, it can ensure that they're never out of sync. The old directory is not deleted until after everything INFORMATION_SCHEMA is updated to refer to the new database name. If the process is aborted in the middle, you'll have duplicate data in the filesystem, but INFORMATION_SCHEMA will point to one or the other (a transaction can ensure that everything in INFORMATION_SCHEMA is updated atomically).

Corrupted InnoDB export

Yesterday, the hard drive from my dedicated server crashed. The only choice I had was to save what I could, before replacing the hard drive with a new one.
The only thing I could save was the /var/lib/mysql folder. Now I have a new hard drive with a new MySQL database running, but empty. I want to restore the data from the database I had.
I tried several things, and read over the internet that InnoDB export wasn't as easy as copying all the /var/lib/mysql folder, so I'm not sure what solution I have.
I tried to replace the new /var/lib/mysql folder with the new, but now mysqld won't run. The error log looks a lot like this, but adding innodb_force_recovery = 1 is not helping at all.
Now I'm kinda lost and out of options. Anyone faced something similar recently?
Thanks
There is a tool that can retrieve MySQL database from corrupted disk https://launchpad.net/undrop-for-innodb .
I hope you still have old hard drive attached to the server or at least an image taken from it.
Download the last revision and compile it. You'd need gcc, flex and bison as the dependency.
Let's say you have attached the old (corrupted) disk as /dev/sdb
First, you need to scan the disk and find InnoDB pages
./stream_parser -f /dev/sdb
Then you need to recover InnoDB dictionary to know table name -> index_id correspondence. See "Recover InnoDB dictionary" for details.
You would also need tables structure. Take it from some old backup. (Other options would be to recover the structure from .frm files or from InnoDB dictionary)
When you know table structure and index_id of a table you can extract the table records from InnoDB pages:
./c_parser -6f pages-actor.ibd/FIL_PAGE_INDEX/0000000000002655.page -t actor.sql
actor.sql is CREATE TABLE statement
c_parser will generate LOAD DATA INFILE command to load the dump back in MySQL.

MySQL crash -> innodb recovery not working -> trying another way

Good day to you.
I used my MySQL server with "innodb_file_per_table" option, and now server is crashed. I want to recover this server using this way:
Uninstall old MySQL
Install new MySQL
Add "innodb_file_per_table" in MySQL configuration
Copy databases folders (only my, not mysql) from old MySQL/data to new MySQL/data
In every folder I have two files, .frm and .ibd, and looks like this files have all data from my databases tables.
But, after copying, tables in this databases didn't work: when I try to open some table, I get error: Table xxx doesn't exist in engine.
I tried REPAIR command, but it isn't helpful.
If you know how to finish my way of repair — please help.
...I know that I need to copy ibdata1 also, but it looks so dead for recovery, so I try way that I try.
REPAIR command won't help with InnoDB.
If you're lucky enough the best you can do is:
1. Start MySQL with innodb_force_recovery=4 (try 5, 6 values if InnoDB fails to start). Make sure innodb_purge_threads=0.
2. Dump the database with mysqldump tool. Yes, it may be slow, but there is no other choice.
3. Create new empty InnoDB table space and reload the dump.
If MySQL fails to start with innodb_force_recovery=6, then recovery from backups is the only option. Well, you can fetch records from *.ibd files, but this is tedious job - google data recovery tool from percona
UPDATE: Data recovery toolkit moved to GitHub
You need to copy everything, not only the data folder
For example, without the ibdata file, mysql don't know where the tables are stored.
https://serverfault.com/questions/487159/what-is-the-ibdata1-file-in-my-var-lib-mysql-directory

innodb Mysql database keeps getting tables damaged

Somehow, using MAMP PRO in my macbook certain two tables just disappear after a while. This has just started a couple of weeks a go and I can't find why. I read the logs and it points me to the INNODB troubleshooting the website tells this error
[ERROR] Cannot find or open table dbcobros/seguimiento from the
internal data dictionary of InnoDB though the .frm file for the table
exists. Maybe you have deleted and recreated InnoDB data
files but have forgotten to delete the corresponding .frm files of
InnoDB tables, or you have moved .frm files to another database? or,
the table contains indexes that this version of the engine doesn't
support.
is an example of out-of-sync data dictionary. I followed the advice and deleted the .frm orphaned file but I still couldn't recreate the table, so I deleted the database and created one again, and run an SQL dump I had. After a couple of minutes it happened again!
How this happened? How can I re-sync the data dictionary? Is this a problem with the mysql installation of the MAMP? I'm about to go into production with my application but now with this error I'm not sure if it will replicate in the production servers and they will lose critical data. Please help!