Ошибка 1148 MySQL Использованная команда не допускается с этой версией MySQL

Я использую команду MySQL LOAD DATA LOCAL INFILE, и я получаю эту ошибку:

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).

Какую настройку можно изменить, чтобы разрешить LOAD DATA LOCAL infile?

Вот код Drupal 7, который мы используем:

$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);

Ответ 1

Загрузка локального файла в MySQL является угрозой безопасности и по умолчанию отключена, вы можете оставить ее, если сможете. Если это не разрешено, вы получите эту ошибку:

ERROR 1148 (42000): The used command is not allowed with this MySQL version

Решения:

  • Используйте аргумент --local-infile=1 в командной строке mysql:

    Когда вы запустите MySQL на терминале, включите аргумент --local-infile=1, что-то вроде этого:

    mysql --local-infile=1 -uroot -p
    
    mysql>LOAD DATA LOCAL INFILE '/tmp/foo.txt' INTO TABLE foo 
    COLUMNS TERMINATED BY '\t';
    

    Тогда команда разрешена:

    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Deleted: 0  Skipped: 0  Warnings: 0
    
  • Или отправьте параметр в демон mysql:

    mysqld --local-infile=1
    
  • Или установите его в файле my.cnf(это угроза безопасности):

    Найдите файл mysql my.cnf и отредактируйте его как root.

    Добавьте строку local-infile под обозначениями mysqld и mysql:

    [mysqld]
    local-infile 
    
    [mysql]
    local-infile 
    

    Сохраните файл, перезапустите mysql. Повторите попытку.

Дополнительную информацию можно найти здесь: http://dev.mysql.com/doc/refman/5.1/en/load-data-local.html

Ответ 2

В дополнение к использованию local-infile с сервером MySQL (вы также можете поместить это в файл /etc/my.cnf), вам также необходимо включить PDO, чтобы разрешить его:

<?php
$pdo = new PDO($dsn, $user, $password, 
    array(PDO::MYSQL_ATTR_LOCAL_INFILE => true)
);

В противном случае он не будет работать, независимо от значения local-infile на сервере MySQL.

Ответ 3

Унаследованный mysql_connect также имеет параметр 'client_flag', который может использоваться для установки параметра mysql.

Параметр client_flags может быть комбинацией следующих константы: 128 (включить LOAD DATA LOCAL), MYSQL_CLIENT_SSL, MYSQL_CLIENT_COMPRESS, MYSQL_CLIENT_IGNORE_SPACE или MYSQL_CLIENT_INTERACTIVE. Прочтите раздел о клиенте MySQL константы для получения дополнительной информации. В безопасном режиме SQL этот параметр игнорируются. http://php.net/function.mysql-connect

Пример:

$db = mysql_connect($host, $user, $pass, FALSE, 128);

Однако вы также можете столкнуться со следующей ошибкой:

ERROR 29 (HY000): File '/var/www/.../mysql_import.csv' not found (Errcode: 13)

В этом случае вам может потребоваться проверить настройки App Armor, чтобы MySQL мог получить доступ к файлам импорта в файловой системе.

В частности, я добавил:

  /import/ r,
  /import/* rw,

Чтобы предоставить MySQL доступ для чтения/записи в /import

Например: Пример профиля брони приложения

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>
}

После этого MySQL может читать файлы из каталога /import.

Ответ 4

Основная причина, по которой мы используем ключевое слово LOCAL, в руководстве MySQL:

С другой стороны, вам не нужна привилегия FILE для загрузки локальных файлы.

Итак, если у вас действительно есть доступ к файлу на сервере, попробуйте пропустить, используя слово "LOCAL" в SQL-запросе, и вместо этого скопируйте файл на сервер и в каталог mysql/data/[tablename].

Подробнее об этом LOCAL/non-LOCAL здесь: Ошибка PHPMyAdmin

Вам больше не нужно беспокоиться о внесении изменений в/etc/mysql/my.cnf