Question

I'm trying to use SELECT INTO OUTFILE to write a file to a custom directory inside another directory that is one level above my document root. I can write to /tmp so I know everything else is working.

I'm using the absolute full path to the file. I'm able to create the directory and chmod to 0777 with PHP. The directory is successfully created and the mode is properly set (as viewed via SSH and FTP).

Example of path I want to use:

/var/www/vhosts/mysite/private_www/data_export/newdir/

I had thought that as long as the directory was world readable/writable/executable, that MySQL would be able to write to it. But I am still getting this error.

Can't create/write to file (Errcode: 13)

I've found lots of posts regarding this error, but no solutions other than write to /tmp. However, if I write to /tmp, I have to add more code to handle filenames and then copy the file to where I want it.

I considered that maybe I needed a different path for MySQL than for PHP. Is there a way to check what MySQL sees as the server root? However, I'm not sure that could be the issue since I am able to LOAD DATA INFILE using the same path.

My Setup

  • CentOS 6
  • PHP 5.3
  • MySQL 5.5
  • Dedicated server with Plesk control panel
  • PHP running as Apache module

What am I missing?

Was it helpful?

Solution

Although you had correctly set writable permissions on the target directory, in order for a user to traverse the directory tree into that target directory, you must supply an execute permission for that user on every higher directory leading into your target directory. This is owing to the fact that in a directory context, execute actually means look inside to list contents.

This means that the minimum (ignoring the owner/group permissions) for each of the directories in the path

/var/www/vhosts/mysite/private_www/data_export

would be 0751, where the final 1 is an execute permission for the "other" user category. So, verify that every directory in your target path has at least execute permissions for the MySQL server user (probably mysql in a CentOS system).

Permitting execute (list-contents) on all those directories does mean that any system user could inspect them, not just the MySQL user. Consider this as you decide where the final path will be. You might want to separate it from your www files if you can.

In your setup you have set the target directory as 0777, world-readable, world-writable. That's not advisable if it can be avoided. Since all that's really necessary there is for MySQL to be able to write to it, consider instead changing its group ownership to the mysql group. That will enable you to avoid making it world writable.

# Give group ownership to mysql
chown :mysql /var/www/vhosts/mysite/private_www/data_export/newdir
# And just make it writable by the group, not everyone
chmod 0770 /var/www/vhosts/mysite/private_www/data_export/newdir
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top