Загрузка данных локального файла с использованием http: // местоположение повреждено

Фон:
Я переместил некоторые сайты с общего хостинга на VPS. Все работает очень гладко, за исключением тех строк кода php, которые выполняют запросы с LOAD DATA LOCAL INFILE, используя источники данных с внешних серверов (т.е. http://server1.net/getfile.php?f=101). Этот код работает (и работал в течение длительного времени) на учетной записи общего хостинга, однако эта учетная запись достигает ограничений по ресурсам, особенно в области размера / скорости базы данных.

Проблема:
Код с LOAD DATA INFILE, который загружается с адреса http: //, больше не работает после перемещения на (новый) VPS.

Система и программное обеспечение:
VPS используется в качестве веб-сервера, на котором, среди прочего, работает Ubuntu (Ubuntu 14.04) с Vesta (0.9.8 (amd64)), apache, nginx, mysql (5.5.44), app-armor. Все недавно установлено и очень мало или не изменено.

Выбор из вывода phpinfo ():

System  Linux MyServer 3.13.0-62-generic #102-Ubuntu SMP Tue Aug 11 14:29:36 UTC 2015 x86_64
Apache Version  Apache/2.4.7 (Ubuntu) mod_fcgid/2.3.9 PHP/5.5.9-1ubuntu4.11 OpenSSL/1.0.1f
Server Root     /etc/apache2
PATH    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
SERVER_SOFTWARE     Apache/2.4.7 (Ubuntu) mod_fcgid/2.3.9 PHP/5.5.9-1ubuntu4.11 OpenSSL/1.0.1f
allow_url_fopen On  On
allow_url_include   Off
doc_root    no value
docref_ext  no value
docref_root no value
file_uploads    On
open_basedir    no value
sys_temp_dir    /tmp
upload_tmp_dir  /tmp
user_dir    no value
cURL support    enabled
mysql
Directive                   Local Value  Master Value
mysql.allow_local_infile    On           On
mysqli
Directive                   Local Value  Master Value
mysqli.allow_local_infile   On           On

Несколько строк из /etc/mysql/my.cnf

[client]
loose-local-infile=1
local-infile=1

[mysqld]
basedir=/usr
datadir=/var/lib/mysql
tmpdir=/tmp
local-infile=1

Ниже код работает в том же каталоге, что и файл с phpinfo()

Тестовый код:

$url = "http://myserver.net/x.csv";
$file = "/var/lib/mysql/test2.csv";

$handle = curl_init($url);
curl_setopt($handle,  CURLOPT_RETURNTRANSFER, TRUE);
/* Get the HTML or whatever is linked in $url. */
$response = curl_exec($handle);
/* Check for 404 (file not found). */
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
echo("<br>Http code: ". $httpCode);
curl_close($handle);

echo "<br>Temp_name: ". $_FILES["file"]["tmp_name"];
echo "<br>Host info: " . $conn->host_info . "\n";
echo "<br>Client info: ".mysqli_get_client_info($conn) ."\n";

$conn = mysqli_init();
if (!$conn) {
die('mysqli_init failed');
}

if (!$conn->options(MYSQLI_OPT_LOCAL_INFILE, true)) {
die('Setting MYSQLI_OPT_LOCAL_INFILE failed');
}

if (!$conn->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5)) {
die('Setting MYSQLI_OPT_CONNECT_TIMEOUT failed');
}

if (!$conn->real_connect('localhost','root','pass','database')) {
die('Connect Error (' . mysqli_connect_errno() . ') '
. mysqli_connect_error());
}

$conn->query("LOAD DATA INFILE '". $file ."' INTO TABLE x_import (@col1) SET ID = @col1;");
echo("<br>Error file: " . mysqli_error($conn));

$conn->query("LOAD DATA INFILE '". $url ."' INTO TABLE x_import (@col1) SET ID = @col1;");
echo("<br>Error url: " . mysqli_error($conn));

$conn->query("LOAD DATA LOCAL INFILE '". $file ."' INTO TABLE x_import (@col1) SET ID = @col1;");
echo("<br>Error file (LOCAL): " . mysqli_error($conn));

$conn->query("LOAD DATA LOCAL INFILE '". $url ."' INTO TABLE x_import (@col1) SET ID = @col1;");
echo("<br>Error url (LOCAL): " . mysqli_error($conn));

$conn->query("SELECT * INTO OUTFILE 'andreas.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' LINES TERMINATED BY '\n' FROM x_import;");
echo("<br>Error OutFile: " . mysqli_error($conn));

Результат кода:

Http code: 200
Temp_name:
Host info:
Client info: 5.5.44
Error file:
Error url: Can't get stat of '/var/lib/mysql/http:/myserver.net/x.csv' (Errcode: 2)
Error file (LOCAL): File '/var/lib/mysql/test2.csv' not found (Errcode: 13)
Error url (LOCAL): File 'http:/myserver.net/x.csv' not found (Errcode: 2)
Error OutFile: File 'andreas.txt' already exists

В php-коде используется root-аккаунт с mysql, поэтому полного доступа / привилегий нет.

Первая строка с кодом SQL (LOAD DATA INFILE без LOCAL с использованием локального файла) правильно добавляет данные из файла в базу данных.

Последняя строка с кодом INTO OUTFILE правильно создает файл в / var / lib / mysql / database / (и 2-й раз дает уже существующую ошибку)

Из всех исследований до сих пор я понимаю:

  • Код ошибки 13 — это разрешение проблем.
  • Код ошибки 02 — это когда невозможно найти файл.
  • «LOAD DATA» — для файла на сервере базы данных.
  • «LOAD DATA LOCAL» — для файла на клиенте (apache / php-код).

Я не понимаю, почему в URL-адресе отсутствует / отсутствует при использовании LOCAL (см. Вывод кода). Я также не понимаю, почему возникает код ошибки 13, когда LOCAL добавляется к URL (php получает код 200 в первой части кода). Мне кажется, что и php, и mysql не могут посмотреть в нужном месте по нескольким причинам.

Ниже я объясню несколько попыток многих вещей, которые я пробовал (в основном из множества других ответов на этом сайте):

Я изменил права доступа к файлам для / var / и / var / lib / на 755 (и один раз на 777), но это не изменило вывод моего тестового кода. / tmp / уже был установлен с 777.

В app-armor я перевел mysql в режим жалобы, а также попытался внести некоторые изменения в конфигурационный файл mysql для app-armor (usr.sbin.mysqld), но оба не изменили вывод тестового кода.

Полезная документация (но, возможно, я не до конца понял):
http://dev.mysql.com/doc/refman/5.5/en/load-data-local.html

Я предпочитаю использовать LOAD DATA LOCAL, но если он работает как-то иначе, я тоже счастлив.

Пожалуйста помоги. Любые вопросы и предложения приветствуются.

3

Решение

Я сталкиваюсь с той же проблемой, когда я пытаюсь использовать mysql load infile (файл данных и проект на локальном хосте и удаленной базе данных). Я использую прямой mysql команда от php (с помощью system функция). Вот пример моего кода:

system('mysql --local-infile -h '.$host. ' -D '.$dbname.' -u'.$dbuser.' -p'.$password." -e \"LOAD DATA LOCAL INFILE '". $pathToFile . "' INTO TABLE table FIELDS TERMINATED BY ';' (field1, field2, field3)\"");

Я надеюсь, что это может быть полезно для вас.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]