背景 我将一些网站从共享主机帐户移动到VPS。除了使用来自外部服务器(即http://server1.net/getfile.php?f=101)的数据源的LOAD DATA LOCAL INFILE执行查询的PHP代码行之外,一切都非常流畅。此代码在共享主机帐户上工作(并且长时间工作),但是,此帐户正在达到资源限制,尤其是在数据库大小/速度方面。
问题: 从http://地址下载的带有LOAD DATA INFILE的代码在移动到(新)VPS后不再起作用。
系统和软件: VPS用作Web服务器,运行带有Vesta(0.9.8(amd64))的Ubuntu(Ubuntu 14.04),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
使用带有mysql的root帐户的php代码,所以那里有完全访问/权限。
带有sql代码的第一行(没有使用本地文件的LOCAL的LOAD DATA INFILE)正确地添加了数据库中文件的数据。
使用INTO OUTFILE代码的最后一行在/ var / lib / mysql / database /中正确创建了一个文件(第二次给出了已经存在的错误)
到目前为止,我从所有研究中了解到:
我不明白为什么在使用LOCAL时URL中存在/缺失(参见代码输出)。当LOCAL被添加到URL时,我也不明白为什么会出现错误代码13(php在代码的第一部分接收代码200)。在我看来,由于几个原因,php和mysql都无法查看正确的位置。
下面我将解释一些我尝试过的尝试(主要来自本网站上的大量其他答案):
我已将/ var /和/ var / lib /的文件权限更改为755(并且一次更改为777),但这并未更改我的测试代码输出。 / tmp /已经设置为777。
在app-armor中我已经将mysql更改为抱怨模式,并且在app-armor(usr.sbin.mysqld)的mysql配置文件中尝试了一些更改,但两者都没有更改测试代码输出。
有用的文档(但我可能没有完全理解): http://dev.mysql.com/doc/refman/5.5/en/load-data-local.html
我更喜欢使用LOAD DATA LOCAL,但如果它以任何其他方式工作,我也很高兴。
请帮忙。欢迎任何问题和建议。
答案 0 :(得分:0)
当我尝试使用mysql load infile
(localhost和远程数据库上的数据文件和项目)时遇到同样的问题。我使用来自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)\"");
我希望这对你有用。