简体   繁体   中英

Error 1148 MySQL The used command is not allowed with this MySQL version

I am using MySQL LOAD DATA LOCAL INFILE command and I get this error:

PDOException: SQLSTATE[42000]: Syntax error or access violation: 1148 The used 
command is not allowed with this MySQL version: LOAD DATA LOCAL INFILE 
'/tmp/phpI0ox54' INTO TABLE `dev_tmp` FIELDS TERMINATED BY ',' ENCLOSED 
BY '"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES; Array ( ) in 
dc_real_estate_form_submit() (line 147 of /PATH/TO/PHP/SCRIPT).

What setting can we change to allow LOAD DATA LOCAL infile?

Here is the Drupal 7 code we are using:

$sql = "LOAD DATA LOCAL INFILE '".$file."'
    INTO TABLE `dev_tmp`
    FIELDS
        TERMINATED BY ','
        ENCLOSED BY '\"'
    LINES
    TERMINATED BY '\\r\\n'
    IGNORE 1 LINES";

db_query($sql);

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:

  1. 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
  2. Or send the parameter into the mysql daemon:

     mysqld --local-infile=1
  3. 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

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.

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

eg: 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:

  1. Login to mysql using command line.

    mysql -u root -p

  2. Check the local infile status:

    SHOW VARIABLES LIKE 'local_infile';

  3. If the output is Off, run this command:

    SET GLOBAL local_infile = 1;

  4. Check the status again:

    SHOW VARIABLES LIKE 'local_infile';

  5. The output will be: see now

  6. Finally restart mysql:

    service mysql restart

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM