【问题标题】:Webmin/Virtualmin - Handling with large file - Internal Server ErrorWebmin/Virtualmin - 处理大文件 - 内部服务器错误
【发布时间】:2020-09-10 09:16:20
【问题描述】:

我正在使用 PHP 脚本将数组的唯一值插入到数据库中。这是脚本

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

if (isset($_POST['submit'])) {
    $df = $_POST['df'];

    $arr = array();
    $file = fopen('files/'.$df.'.csv', 'r');
    while (($line = fgetcsv($file)) !== false) {
        $arr[] = $line[2];
    }
    $arruniq = array_unique($arr);
    fclose($file);
    $arr_count = count($arr);

    $time = strtotime(date_default_timezone_get());
    $ts = date("Y-m-d H:i:s", $time);

    $mysqli = new mysqli("localhost", "root", "pass", "tab");
    if ($mysqli === false) {
        die("ERROR: DB could not connect. ");
    }

    $sqlins = "insert into tab (created_time, uniq_id) values (?, ?);";
    for ($i = 0; $i < $arr_count; $i++) {
        if ($stmt = $mysqli->prepare($sqlins)) {
            $stmt->bind_param("ss", $ts, $arruniq[$i]);
            $stmt->execute();
        } else {
            echo "ERROR: Could not prepare query";
        }
    }
    $mysqli->close();
}

脚本正在读取一个 CSV 文件,将值唯一并插入到数据库中。这是问题所在,如果文件较小,脚本可以正常工作,但如果我使用较大的文件,我会收到“500 内部服务器错误”。

服务器 PHP 日志和 apache 日志中没有显示或记录错误。

我什至通过使用ini_set('memory_limit','2048M');max_execution_time 标头增加了脚本的执行时间和脚本的内存限制,但也没有用。

【问题讨论】:

  • 你更新upload_max_filesizepost_max_size了吗?
  • 是的,我也设置了 upload_max_filesize 200Mpost_max_size 200M,但没有更改
  • 我们必须确保问题确实出在 csv 文件中或其他原因。你在哪里检查日志?是否已为您的页面加载了访问日志条目?
  • 这是我从 apache2 错误日志 [fcgid:warn] [pid 3221] mod_fcgid: process 4423 graceful kill fail, sending SIGKILL [mpm_prefork:notice] [pid 3220] AH00169: caught SIGTERM, shutting down 得到的错误
  • 我已经将FcgidConnectTimeout 从 20 更改为 500

标签: php mysql apache mysqli webmin


【解决方案1】:

这是脚本执行时间的问题。 由于我使用的是 webmin/virtualmin ma​​x_execution_time 标头不起作用。所以我在 virtualmin 服务器中改变了它

virtualmin server -> server configuration -> website options -> Maximum PHP script run time

现在问题解决了,但是执行脚本需要更长的时间。

【讨论】:

    【解决方案2】:

    如果您使用准备好的语句和事务,它应该会更快。

    $mysqli->begin_transaction();
    $stmt = $mysqli->prepare("INSERT INTO tab (created_time, uniq_id) values (?, ?);");
    foreach($arruniq as $item) {
        $stmt->bind_param("ss", $ts, $item);
        $stmt->execute();
    }
    $mysqli->commit();
    

    正确使用准备好的语句会给您带来轻微的性能提升,因为服务器不需要每次都解析 SQL,并且事务可以为您节省一些时间,因为不会在每行之后调用 commit

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-30
      • 2013-09-25
      相关资源
      最近更新 更多