
O script de importação roda dois minutos e morre com Fatal error: Allowed memory size of 134217728 bytes exhausted. O culpado quase nunca é o INSERT: é o array de 50 mil linhas vivo na memória enquanto o laço acumula objetos. O primeiro corte é array_chunk: ele fatia o trabalho em blocos fixos e deixa você fechar transação a cada bloco.
<?php
$pdo = new PDO('mysql:host=127.0.0.1;dbname=loja;charset=utf8mb4', $usuario, $senha);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('INSERT INTO produtos (sku, nome, preco) VALUES (?, ?, ?)');
foreach (array_chunk($linhas, 500) as $i => $lote) {
$pdo->beginTransaction();
try {
foreach ($lote as $linha) {
$stmt->execute([$linha[0], $linha[1], $linha[2]]);
}
$pdo->commit();
} catch (PDOException $e) {
$pdo->rollBack();
throw $e;
}
printf("lote %d | pico %.1f MBn", $i, memory_get_peak_usage(true) / 1048576);
} Uma transação por lote, no lugar de uma por linha, corta o vai e vem com o MySQL 8 sem prender a tabela o script inteiro. O rollBack não é enfeite: um SKU duplicado no meio do bloco deixaria a transação pendurada e a tabela num estado indefinido. Aponte para uma cópia do banco na primeira rodada — 50 mil linhas não têm Ctrl+Z. O printf denuncia o pico subindo a cada volta, sinal de que sobrou coisa na memória.
O limite que confunde: array_chunk não reduz o pico da carga inicial. Ele não duplica o conteúdo das strings, mas monta uma tabela nova para cada fatia enquanto o original continua em pé. Se o estouro vem antes do laço, montando $linhas, nenhum tamanho de lote salva. Aí o caminho é nunca ter o array completo:
<?php
function lerLotes(string $arquivo, int $tamanho = 500): Generator
{
$fh = fopen($arquivo, 'r');
$lote = [];
while (($linha = fgetcsv($fh)) !== false) {
$lote[] = $linha;
if (count($lote) === $tamanho) {
yield $lote;
$lote = [];
}
}
if ($lote !== []) {
yield $lote;
}
fclose($fh);
}
foreach (lerLotes('/var/tmp/produtos.csv') as $lote) {
// mesmo INSERT do bloco acima
} O generator devolve 500 linhas por vez e o resto do CSV fica em disco: o consumo não sobe com o arquivo. Rode com php -d memory_limit=256M importar.php. Se passar, resolveu; se subir o limite até funcionar, só empurrou o problema pro arquivo do mês que vem.
Editou o listing.xml e o admin continua com as colunas antigas ou um filtro travado? O estado da grid está…
Apagou a pasta do módulo e agora todo bin/magento morre reclamando de módulo desconhecido? A lista continua no app/etc/config.php, e…
Preço gravado em post meta sai fora de ordem porque o MySQL compara texto. Use orderby meta_value_num e inclua quem…
Fila do Action Scheduler com dezenas de milhares de ações pendentes na loja? Rode a fila pelo WP-CLI, limpe o…
A consulta volta vazia e você não sabe qual WHERE foi montado. Veja o SQL antes de rodar com getCompiledSelect(false)…
Pare de pedir checkbox para tudo no checkout: mapeie campo a campo qual base legal do artigo 7º sustenta cada…