Fixing "Can't find file: ... (errno: 13)" on mysql
I've been beating my head against this one for a few days now. We have a two weeks' worth of daily backup snapshots of our production mysql data dir (i.e. the actual binary files, not sql dumps) and I need to restore a table from one of the backups so we can compare it to what we have now.
So I created a dummy schema directory and extracted the relevant table files (.MYI, .MYD and .frm) and restarted mysql. It shows up, I can "show tables", but if I try to interact with it in any way ("desc tablename", "select...", etc) I get:
Can't find file: './schema_name/table_name.frm' (errno: 13)
[ed: real names sanitized]
Errno 13 is permissions so I double-checked everything. The directory and files have the same owner and group (mysql:mysql) as all the other schemas. They also have the same perms (700 on the dir, 660 on the files). Looking at "ls -n" the uids also match up exactly.
Most recently I have tried doing a full extract of a different backup and then linking it into the mysql data dir (there's not enough room on that volume to extract the full thing) and I get the same error. I've also tried pointing mysql's data dir in my.cnf to the dir holding the backup and restarting. It built out the mysql tables that needed to be there but I still got the same error.
The only thing I can find through googling is people who had this problem because of actual ownership or permission errors, which does not seem to be the case for me. I've also found some remark in passing about a UMASK env variable that can result in this error but I think that has to do with fresh installs, which this is not.
Solution 1:
Are you running something like selinux or some other similar package? I'd suggest disabling that (or modifying the security policies) to see if something there is preventing MySQL from being able to access the files.
[edit] If so, check syslog to see if selinux is blocking mysql from doing anything. If it is SELinux, I'm told this may disable it so that you might test this theory.
/usr/sbin/setenforce Permissive
Solution 2:
strace is your friend in this instance. Find the process id of your mysql then run:
strace -efile -f -o /tmp/mysql.log -p $pid
In another window do something that causes the error. You can then press ctrl-c to kill strace. If you look in /tmp/mysql.log you should see what caused the problem.
As an aside, I really recommend you don't rely on copying the binary datafiles. SQL dumps are a lot more reliable and flexible. Also, it would appear you're using MyISAM. I'd really recommend against using those unless you don't care about the data in them. InnoDB has so many advantages over MyISAM.