Exceder problemas de memória no servidor usando PHP

0

O PHP possui limites de memória definidos em nível global no arquivo PHP.ini. Eu também sei que eles podem ser configurados no nível local.

Nosso limite de memória para uma consulta é definido como 132 MB, mas continuamos recebendo erros como este:

Fatal error: Allowed memory size of 161480704 bytes exhausted (tried to allocate 32 bytes) in #{removed_file_path}/script.php on line #{line}

Atualmente, estamos monitorando nossos sistemas por meio de um arquivo de log incorreto, que armazena erros em cache enquanto os usuários navegam em uma página, além de usar cron ; no entanto, estes não são registrados em qualquer lugar.

O erro pode ser corrigido alterando todas as chamadas para mysql_query para mysql_unbuffered_query , no entanto, preciso saber onde isso precisa ser alterado para todos os arquivos no servidor. Se o script não estiver tendo problemas de memória, não quero alterar o código, pois quero que o servidor leia os resultados para a RAM sempre que possível.

Não queremos aumentar nosso limite de memória em PHP, já que nosso host nos aconselha contra isso.

O que pode ser feito para corrigir os problemas de memória? Estamos rodando no CentOS 6.7.

    
por N Altun 09.02.2016 / 18:10

1 resposta

2

Seu interpretador PHP está definido para finalizar qualquer script que requer mais de 132MB de memória. Seu script está tentando alocar mais de 161 MB de memória. O problema é bem simples e as soluções também. Você pode:

  1. Obtenha seu interpretador PHP para alocar mais. A razão pela qual seu host está desaconselhando é que, se ele não o fizer, ele acabará alocando 8 GB + de memória para você simplesmente porque seu banco de dados continua crescendo.
  2. Esqueça o PHP e a API mysql_* obsoleta e use algo que não impõe restrições de memória. Lembre-se de que, mesmo que o intérprete não o incomode mais, o SO provavelmente irá em algum momento.
  3. Melhore seu script.

Usar mysql_unbuffered_query é a solução 3. Como o PHP não armazena mais o conjunto de resultados do MySQL, ele não ocupa tanta memória e o intérprete para de reclamar. Você está basicamente trocando de consultas bufferizadas para sem buffer (veja os exemplos # 2 e # 3, e considere a mudança para o PDO, isso é 2016 ). Se você quiser continuar trabalhando com o PHP e se achar que seu design está correto, esta é a sua solução.

I don't want to change the code since I want the server to read the results to RAM wherever possible.

As pessoas que trabalham em DBMSes geralmente estão fazendo um ótimo trabalho. Seus mecanismos são otimizados e uma consulta não leva mais tempo do que o necessário. Considerando o fato de que você está usando PHP e a antiga mysql_* API, você não quer que eu acredite que a velocidade é realmente uma preocupação aqui ... Meu palpite é: você pode ter recursos para manter os dados no banco de dados, e não na RAM. Use consultas sem buffer, busque / processe suas linhas uma de cada vez e confie em seu DBMS um pouco mais (além disso, ele provavelmente fará algum buffering para você ...).

Se você ainda não está convencido, uma possível melhora poderia ser repensar as próprias perguntas. Tem certeza de que não está buscando mais dados do que o necessário? (quero dizer, você realmente precisa do SELECT * no início da sua consulta?) Tem certeza de que o MySQL não poderia cuidar de algum processamento para você? DBMSes são ferramentas bastante poderosas, colocá-los para funcionar e não fazem tudo em seu script PHP. Um exemplo típico seria computar uma média: em vez de buscar todos os números na coluna e usar um loop de soma, peça AVG(column) diretamente.

Sem o seu script, é muito difícil dar mais conselhos sobre essa parte (e o pessoal do Stack Overflow provavelmente faria um trabalho melhor). No entanto, se você achar que já trouxe modificações suficientes para o seu script ... que tal submetê-lo à revisão de código ? Se você não consegue ver uma maneira de melhorá-lo ainda mais, é provável que as pessoas lá estejam.

Se, em algum momento, você sentir que já esgotou todas as opções que o PHP e o MySQL tinham a oferecer, acho que você terá que considerar usar outra coisa. Dependendo do tipo de processamento de dados que você está fazendo, você pode encontrar outras ferramentas mais adequadas à tarefa em questão.

    
por 10.02.2016 / 01:09