So You Just Deleted Your Production Database - What Now

by Jon Buys - Jun. 14, 2011Comments (9)

terminal

It doesn’t matter how it happened, it doesn’t matter why, blame can (and probably will) be placed later. What matters now is that your production MySQL database was just deleted from the filesystem while the MySQL daemon was running. The good news is that the server, somehow, is still running fine, and the system is still up. The bad news is that the directory where MySQL stores the database is now empty.

Take a deep breath, you are running Linux, here is what to do:

  1. 1. Do not shut down MySQL. If you do you lose all your data.

  2. 2. Schedule downtime for your application: You won’t get out of this unscathed.

  3. 3. Find a new home for your server, preferably a new server or a new virtual machine. If you run VMware or another virtualization setup, you can even clone your existing database server.

  4. 4. During downtime, move the IP address from the broken MySQL server over to the new server. Give your old server a temporary IP address.

  5. 5. Use mysqldump to get the data out of your broken, mysteriously missing database into a text file you can move.

  6. 6. Copy the text file over to the new server, import it into the new database, and restart your application. You are good to go.

Now that the crises has been averted, lets talk about why that worked, and the narrow opportunity you had to save the database.

The database was running, accepting queries and responding properly. There was no cache, which means the data was being read and written to the disk, but the file that it was being written to was gone. How could that be? To answer that question we have to dig deep into the gritty depths of how the Linux filesystem works.

When the file was deleted from the disk, what was actually deleted was last remaining pointer to the file’s inode. An inode is a data structure that holds metadata about a file, like the file’s permissions, and, importantly, the location of the actual data on the disk. Data on a disk does not look like a filesystem with folders and directories, it just looks like a stream of bytes. What normally happens when the last hard link to an inode is removed is that the inode is removed and the location of the data on the disk is lost, free for the operating system to overwrite it. In the case of the database, the last hard link was removed, but the MySQL daemon was still accessing the data, which means that a file descriptor was kept in the /proc filesystem. So the data was there, still available, but as soon as MySQL was stopped, or if the server was rebooted, the inode would be gone, taking with it the last known location of the data on disk.

It may be tempting to try to recover the database out of the /proc filesystem using lsof, as described in this excellent Linux.com article. Don’t bother. The minute you attempt to copy the database file without first shutting down MySQL it will become corrupt.

As a last ditch effort, a little knowledge of the Linux filesystem can save the day, but not without taking a few hits along the way. So, remember, always test your backups, always know what the command you are about to type actually does, not just what you think it does.

Of course, this is all hypothetical. It never happened to me. No, never.



John Mark Walker uses OStatic to support Open Source, ask and answer questions and stay informed. What about you?



9 Comments
 

I tried this in a test environment and got an unknown database error when running mysqldump. I suspect this would only work on certain filesystems or versions of MySQL. I'm running MySQL 5.1.55 on an ext4 filesystem.


If I rm the files, issue create database then try to mysqldump then it runs OK but the dump file doesn't contain any tables.


0 Votes

This article makes me sad.


0 Votes

really?


0 Votes

I really doubt this would work. MySQL represents its databases as series of files which it does not maintain a handle to constantly. So therefor you've already lost most of your data files if you rm the data directory.


Instead of saying in your last sentence "Of course, this is all hypothetical. It never happened to me. No, never.", you should consider prefixing your post with that to save readers the time it takes to read it.


0 Votes

This actually happened at a company I worked for, but fortunately I wasn't the one that did it. The person clicked the "drop database" button in phpMyAdmin instead of the "drop table" button, and then clicked "yes" when prompted. Poof! Gone.


We did backups twice a day using mysqldump, so he grabbed the latest dump file and started loading it back in. But it took about half a day to restore, because the database was so large. That's when we started backing up the raw MySQL database files by tar'ing up the entire directory tree while the database was offline.


If you have a master/slave setup, it's even easier because you can just take down the slave without interrupting the master or the applications using it. Restoring is then as easy as un-tar'ing the raw files back into the MySQL directory.


If you use mysqldump, be sure you know how long it'll take to do a restore. :-)


0 Votes

I did not read the last sentence. What's a misleading title!


0 Votes

Genius counseling. You should become a consultant.


Of course, this is all hypothetical. It never happened to me. No, never.


0 Votes

Uh, I'm pretty sure the last line is meant to be taken as a joke. As in: noone would ever admit they stupidly deleted their DB. Man, you guys need to get out more.


0 Votes

Hm. If the process has open handles, I wonder if it would be possible to create a hardlink off of that handle. You'd still have to rebuild metadata like ownership, permissions, ACLs and extended attributes, of course. I guess I'd have to dig through the kernel source and see how that works.


"I really doubt this would work. MySQL represents its databases as series of files which it does not maintain a handle to constantly. So therefor you've already lost most of your data files if you rm the data directory." -- anonymous


I expect it depends on the db engine you're using. Some engines split the data up across many files by default, some after certain configuration settings are changed. Probably doesn't hurt if the disk is being constantly hammered, reducing the likelihood the handle is allowed to close.


0 Votes
Share Your Comments

If you are a member, to have your comment attributed to you. If you are not yet a member, Join OStatic and help the Open Source community by sharing your thoughts, answering user questions and providing reviews and alternatives for projects.


Promote Open Source Knowledge by sharing your thoughts, listing Alternatives and Answering Questions!