I am using MySQL LOAD DATA LOCAL INFILE
command and I get this error:
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1148 The
In addition to using local-infile
with the MySQL server (you can put this in the /etc/my.cnf file too), you also need to enable PDO to allow it:
<?php
$pdo = new PDO($dsn, $user, $password,
array(PDO::MYSQL_ATTR_LOCAL_INFILE => true)
);
Otherwise it won't work, regardless of the value of local-infile
on the MySQL server.
Loading a local file in MySQL is a security hazard and is off by default, you want to leave it off if you can. When it is not permitted you get this error:
ERROR 1148 (42000): The used command is not allowed with this MySQL version
Solutions:
Use --local-infile=1
argument on the mysql commandline:
When you start MySQL on the terminal, include --local-infile=1
argument, Something like this:
mysql --local-infile=1 -uroot -p
mysql>LOAD DATA LOCAL INFILE '/tmp/foo.txt' INTO TABLE foo
COLUMNS TERMINATED BY '\t';
Then the command is permitted:
Query OK, 3 rows affected (0.00 sec)
Records: 3 Deleted: 0 Skipped: 0 Warnings: 0
Or send the parameter into the mysql daemon:
mysqld --local-infile=1
Or set it in the my.cnf file (This is a security risk):
Find your mysql my.cnf
file and edit it as root.
Add the local-infile
line under the mysqld and mysql designators:
[mysqld]
local-infile
[mysql]
local-infile
Save the file, restart mysql. Try it again.
More info can be found here: http://dev.mysql.com/doc/refman/5.1/en/load-data-local.html
The legacy mysql_connect also has a parameter 'client_flag
' that can be used to set the mysql parameter.
The client_flags parameter can be a combination of the following constants: 128 (enable LOAD DATA LOCAL handling), MYSQL_CLIENT_SSL, MYSQL_CLIENT_COMPRESS, MYSQL_CLIENT_IGNORE_SPACE or MYSQL_CLIENT_INTERACTIVE. Read the section about MySQL client constants for further information. In SQL safe mode, this parameter is ignored. http://php.net/function.mysql-connect
Example:
$db = mysql_connect($host, $user, $pass, FALSE, 128);
However, you may also encounter the following error:
ERROR 29 (HY000): File '/var/www/.../mysql_import.csv' not found (Errcode: 13)
In which case, you may need to check your App Armor settings to allow MySQL access to the import files on the filesystem.
In particular I added:
/import/ r,
/import/* rw,
To give MySQL read/write access to /import
e.g: Sample App Armor profile
cat /etc/apparmor.d/usr.sbin.mysqld
# vim:syntax=apparmor
# Last Modified: Tue Jun 19 17:37:30 2007
#include <tunables/global>
/usr/sbin/mysqld {
#include <abstractions/base>
#include <abstractions/nameservice>
#include <abstractions/user-tmp>
#include <abstractions/mysql>
#include <abstractions/winbind>
capability dac_override,
capability sys_resource,
capability setgid,
capability setuid,
network tcp,
/etc/hosts.allow r,
/etc/hosts.deny r,
/etc/mysql/*.pem r,
/etc/mysql/conf.d/ r,
/etc/mysql/conf.d/* r,
/etc/mysql/*.cnf r,
/usr/lib/mysql/plugin/ r,
/usr/lib/mysql/plugin/*.so* mr,
/usr/sbin/mysqld mr,
/usr/share/mysql/** r,
/var/log/mysql.log rw,
/var/log/mysql.err rw,
/var/lib/mysql/ r,
/var/lib/mysql/** rwk,
/var/log/mysql/ r,
/var/log/mysql/* rw,
/var/run/mysqld/mysqld.pid w,
/var/run/mysqld/mysqld.sock w,
/run/mysqld/mysqld.pid w,
/run/mysqld/mysqld.sock w,
# Custom import folders start
# These folders will also be read/writeable by mysql.
/import/ r,
/import/* rw,
# Custom import folders end
/sys/devices/system/cpu/ r,
# Site-specific additions and overrides. See local/README for details.
#include <local/usr.sbin.mysqld>
}
After that MySQL could read files from the /import
directory.
The main reason why we are using the LOCAL keyword is explained in the MySQL manual:
On the other hand, you do not need the FILE privilege to load local files.
So if you in fact do have file access to the server then try to skip using the word "LOCAL" in SQL query, and instead copy the file to the server and the directory mysql/data/[tablename].
More about this LOCAL/non-LOCAL here: PHPMyAdmin Bug
You don't have to worry any longer about making changes to /etc/mysql/my.cnf
Just follow the following process to solve the problem:
Login to mysql using command line.
mysql -u root -p
Check the local infile status:
SHOW VARIABLES LIKE 'local_infile';
If the output is Off, run this command:
SET GLOBAL local_infile = 1;
Check the status again:
SHOW VARIABLES LIKE 'local_infile';
The output will be: see now
Finally restart mysql:
service mysql restart