簡體   English   中英

PHP/Mysql “致命錯誤:允許的 memory 大小已用盡..”嘗試在塊中插入大量數據時

[英]PHP/Mysql “Fatal error: Allowed memory size exhausted ..” when trying to insert a big amount of data in chunks

我正在將舊的 PHP 項目遷移到新的 Laravel 應用程序。 有幾百萬條記錄表user_category_views我打算分塊遷移。 我使用mysqli獲取舊記錄並使用 Laravel DB::Statement插入。 出於某種原因,在大約一百萬條記錄之后,此代碼將出現異常:

致命錯誤:允許 memory 大小為 268435456 字節用盡(試圖分配 73728 字節)

memory 這里溢出了什么? 也許$result->free()不像我想的那樣工作?

        $count = 2000000; // actual number will be received from count(*) stmt
        $vendors = [561 => '618', 784 => '512' /* and so on */ ];
        $step = 5000;
        for( $i=0; $i<=$count; $i+=$step ){

            $q = "SELECT * FROM `user_category_views` LIMIT $i, $step;";

            if ($result = $this->mysqli->query($q)) {

                $stmt = "INSERT INTO vendor_views (`vendor_id`, `counter`, `created_at`) VALUES";

                /* fetch associative array */
                while ($row = $result->fetch_assoc()) {

                    $vendor_id = null;

                    $id = $row['user_category_id'];

                    // Here I'm trying to prevent Laravel 
                    // from throwing the exception if the entry 
                    // is not found in $vendors array. 
                    // This habit I've gained from js coding  
                    try{
                       $vendor_id = $vendors[$id];
                    } catch (Exception $e) {
                       continue;
                    }

                    if(empty($vendor_id)) continue;

                    $counter = $row['counter'];
                    $created = $row['created'] ;

                    $stmt .= " ($vendor_id, $counter, '{$created}'),";

                }

                $result->free();

                DB::statement( trim($stmt, ",") );

                $stmt = null;

            }
        }

感謝 Nigel Ren,他指出我在濫用 try/catch 構造

所以而不是

    .....
    try{
        $vendor_id = $vendors[$id];
    } catch (Exception $e) {
        continue;
    }
    ....

我現在正在使用

$vendor_id = $vendors[$id]??null;

並且不再有 memory 泄漏問題。 不知道為什么,但是現在可以了

我想您需要在 php.ini 中設置upload_max_filesizepost_max_size的值

upload_max_filesize = 1000M (or more)
post_max_size = 1000M (or more)

然后重新啟動服務器並檢查結果。

重啟Apache: service apache2 restart

你的問題是因為你的 memory 是有限的。 嘗試在 PHP 文件的頂部設置:

ini_set('memory_limit', '-1');

增加 PHP 的 memory 限制。

如果上述解決方案不起作用。 也許你的內存是 go over。 請檢查一下。 你也可以像 $step = 5000; 這樣減少你的步數。 到 $step = 1000; 我覺得更好

希望它有所幫助。 謝謝

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM