I failed to drop a database:
mysql> drop database mydb; ERROR 1010 (HY000): Error dropping database (can't rmdir './mydb', errno: 39)
Directory db/mydb exists in mysql tree but has no table:
# ls -l db/mydb -rw-rw---- mysql mysql HIS_STAT.MYD -rw-rw---- mysql mysql HIS_STAT.MYI
What should I do?
Quick Fix
If you just want to drop the database no matter what (but please first read the whole post: the error was given for a reason, and it might be important to know what the reason was!), you can:
SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';service mysql stoporrcmysqld stopor similar on Linux,NET STOP <name of MYSQL service, often MYSQL57 or similar>or throughSERVICES.MSCon Windows)Reasons for Errno 13
MySQL has no write permission on the parent directory in which the
mydbfolder resides.Check it with
On Linux, this can also happen if you mix and match MySQL and AppArmor/SELinux packages. What happens is that AppArmor expects mysqld to have its data in
/path/to/data/dir, and allows full R/W there, but MySQLd is from a different distribution or build, and it actually stores its data elsewhere (e.g.:/var/lib/mysql5/data/**as opposed to/var/lib/mysql/**). So what you see is that the directory has correct permissions and ownership and yet it still gives Errno 13 because apparmor/selinux won’t allow access to it.To verify, check the system log for security violations, manually inspect apparmor/selinux configuration, and/or impersonate the mysql user and try going to the base var directory, then cd incrementally until you’re in the target directory, and run something like
touch aardvark && rm aardvark. If permissions and ownership match, and yet the above yields an access error, chances are that it’s a security framework issue.Reasons for Errno 39
This code means “directory not empty”. The directory contains some hidden files MySQL knows nothing about. For non-hidden files, see Errno 17. The solution is the same.
Reasons for Errno 17
This code means “file exists”. The directory contains some MySQL file that MySQL doesn’t feel about deleting. Such files could have been created by a
SELECT ... INTO OUTFILE "filename";command wherefilenamehad no path. In this case, the MySQL process creates them in its current working directory, which (tested on MySQL 5.6 on OpenSuSE 12.3) is the data directory of the database, e.g./var/lib/mysql/data/nameofdatabase.Reproducibility:
Move the file(s) outside (or delete if not needed) and retry. Also, determine why they were created in the first place – it could point to a bug in some application. Or worse: see below…
UPDATE: Error 17 as exploit flag
This happened on a Linux system with WordPress installed. Unfortunately the customer was under time constraints and I could neither image the disk or do a real forensics round – I reinstalled the whole machine and WordPress got updated in the process, so I can only say that I’m almost certain they did it through this plugin.
Symptoms: the
mysqldata directory contained three files with extension PHP. Wait, what?!? — and inside the files there was a bulk of base64 code which was passed tobase64_decode,gzuncompressand[eval()][2]. Aha. Of course these were only the first attempts, the unsuccessful ones. The site had been well and truly pwn3d.So if you find a file in your mysql data dir that’s causing an Error 17, check it with
fileutility or scan it with an antivirus. Or visually inspect its contents. Do not assume it’s there for some innocuous mistake.(Needless to say, to visually inspect the file, never double click it).
The victim in this case (he had some friend “do the maintenance”) would never have guessed he’d been hacked until a maintenance/update/whatever script ran a
DROP DATABASE(do not ask me why – I’m not sure even I want to know) and got an error. From the CPU load and the syslog messages, I’m fairly positive that the host had become a spam farm.Yet another Error 17
If you
rsyncor copy between two MySQL installations of the same version but different platform or file systems such as Linux or Windows (which is discouraged, and risky, but many do it nonetheless), and specifically with different case sensitivity settings, you can accidentally end up with two versions of the same file (either data, index, or metadata); sayCustomers.myiandCustomer.MYI. MySQL uses one of them and knows nothing about the other (which could be out of date and lead to a disastrous sync). When dropping the database, which also happens in many amysqldump ... | ... mysqlbackup schemes, theDROPwill fail because that extra file (or those extra files) exists. If this happens, you should be able to recognize the obsolete file(s) that need manual deletion from the file time, or from the fact that their case scheme is different from the majority of the other tables.Finding the data-dir
In general, you can find the data directory by inspecting the
my.cnffile (/etc/my.cnf,/etc/sysconfig/my.cnf,/etc/mysql/my.cnfon Linux;my.iniin the MySQL program files directory in Windows), under the[mysqld]heading, asdatadir.Alternatively you can ask it to MySQL itself: