我们将生产服务器升级到新服务器,从使用PHP 5.6升级到PHP 7.1,并在其上托管了Drupal 7网站。在大多数情况下,该站点似乎正常运行。服务器移动后,我看到的问题是,与以前相比,CSV导入花费的时间超长。 csv导入会将每一行添加到数据库中。
$fp = fopen($file_path, 'r');
if ($fp === FALSE) {
// Failed to open file.
watchdog('ea_test', 'Failed to open %file_path', array('%file_path' => $file_path));
$context['finished'] = TRUE;
return;
}
fseek($fp, $context['sandbox']['offset']);
for ($i = 0; $i < $limit; $i++) {
$line = fgetcsv($fp);
if ($line == FALSE) {
$done = TRUE;
}
// If first line just skipping ahead.
elseif ($context['sandbox']['records'] < 1) {
$context['sandbox']['records']++;
}
else {
try {
db_insert('ea_csv_test')
->fields(array(
'agent_number' => $line[0],
'total_signatures' => $line[1],
'template_number' => $line[2],
'photo' => $line[3] ? 1 : 0,
'total_views' => $csv_line[4],
'total_clicks' => $csv_line[5],
'annual_cost' => $csv_line[7],
'monthly_cost' => $csv_line[8],
'popular_button' => $csv_line[9],
'month' => $csv_line[10],
'asof' => date('Y-m-d 00:00:00'),
))->execute();
}
catch (Exception $e) {
// By setting the databse error it will fail and display the last bad
// record. Normally I would log/email this but I think it
// will send too many. More than likely if one is bad they all
// will be bad.
$database_insert_error = $e->getMessage();
$error = TRUE;
}
// Set the current position of the file so it starts from there.
$context['sandbox']['offset'] = ftell($fp);
$context['sandbox']['records']++;
}
}
$eof = feof($fp);
问题出在本地,在我的登台站点上,我无法复制该问题。唯一的区别是,我在本地使用PHP 7.1.17,在生产上使用PHP 7.1.25。本地和产品都使用mariadb 5.5.5-10.2.19-MariaDB-log。
时间比较:
本地/暂存需要9.51秒来处理。
生产过程需要276.12秒。
修改
我直接从数据库运行了导入(没有任何PHP),而且速度非常快。在我看来,它必须是某种php设置:
truncate TABLE ea_csv_test;
LOAD DATA INFILE '/tmp/test.csv' into table ea_csv_test
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;
编辑2
提到在生产中未启用APCu。我启用了它,它有所帮助。从276秒增加到166秒。
答案 0 :(得分:0)
我开始比较innodb的设置,发现在本地我将innodb_flush_log_at_trx_commit
设置为2,但在生产环境中将其设置为1。一旦在生产环境中将其更改为2,就解决了我的问题。
根据我的理解,如果设置为2,它将每秒记录一次日志,而不是任何事务。最坏的情况是,如果服务器出现故障,我们可能会丢失1秒钟的数据。在我的情况下,如果我们正在导入并且服务器关闭,则无论如何我都需要重新上传,因为导入将永远无法完成。我认为,如果我们进行货币交易,将其保持在1是合理的。