Não é possível remover o limite de uso de memória para script PHP

6

A situação

Estou tendo um problema com um script PHP recebendo a seguinte mensagem de erro:

Fatal error: Out of memory (allocated 359923712) (tried to allocate 72 bytes) in /path/to/piwik/core/DataTable.php on line 969

O script que estou executando é: /path/to/piwik/misc/cron/archive.sh

Estou assumindo que os números são Bytes, o que significa que o total é de aproximadamente 360 MB.

Para todas as intenções e propósitos, eu aumentei os limites de memória no servidor bem acima de 360MB, mas este é o número (mais ou menos um byte) em que ele é consistentemente com erros.

Por favor note : Esta questão não é sobre como consertar um vazamento de memória no script, nem sobre por que o próprio script está usando tanta memória. O script é parte do processo de arquivamento do Piwik, portanto não posso consertar qualquer vazamento de memória, etc. Para obter mais informações sobre esse script e por que estou aumentando o limite de memória, consulte " Como configurar o arquivamento automático "

A questão

Dado que o script está tentando usar mais de 360MB de memória, o que não posso mudar, por que não parece possível aumentar a quantidade de memória disponível para php no meu servidor?

Atualização 23 de junho : Veja "O que eu tentei" > "Aumentando os limites de memória por processo do Linux" abaixo para segundo plano ... Se eu definir ulimit -v 1024000 , então verifique com ulimit -v , recebo o valor correto de '1024000'. Se eu executar o script novamente, ele irá progredir muito mais, mas acabará por errar com o mesmo limite de memória (~ 360MB) atingido. Se eu verificar imediatamente ulimit -v , ele foi redefinido para o valor original de '524288'. Isso parece que pode ser a causa raiz do problema.

O que eu tentei

Aumentando o memory_limit do PHP

Dado o arquivo php.ini:

php -i | grep php.ini
Configuration File (php.ini) Path => /usr/local/lib
Loaded Configuration File => /usr/local/lib/php.ini

Eu editei esse arquivo, então a diretiva memory_limit lê;

memory_limit = -1

Reinicie o Apache e verifique se o novo valor está parado;

$ php -i | grep memory_limit
memory_limit => -1 => -1

Execute o script e obtenha o mesmo erro.

Eu também tentei 1G , 768M , etc, todos com o mesmo resultado (ou seja, sem alteração).

Atualização 22 de junho : Baseado em A ajuda do Vangel , tentei definir post_max_size para 20M em combinação com a configuração memory_limit . Mais uma vez, isso não tem efeito.

Atualização 23 de junho : Baseado em ajuda do olefebvre , posso confirmar que o usuário que está executando o script tem permissão de leitura / gravação para o arquivo php.ini contendo as configurações de memory_limit .

Removendo o limite de memória nos processos filhos do Apache

Eu encontrei e editei o arquivo httpd.conf para ter certeza de que não há uma diretiva RLimitMEM .

Eu então usei o Apache Configuration > Restrições de uso de memória para gerar uma restrição, que alegou ter sido em 1000M (e confirmada pela verificação de httpd.conf).

Ambos resultaram em nenhuma alteração no script com erros de 360MB.

Aumentando os limites de memória por processo do Linux

Os limites atuais definidos no sistema:

$ ulimit -m
524288

$ ulimit -v
524288

Eu tentei definir ambos para ilimitado:

$ ulimit -m unlimited
$ ulimit -v unlimited

$ ulimit -m
unlimited

$ ulimit -v
unlimited

Mais uma vez, isso resultou em absolutamente nenhuma melhoria no meu problema.

Atualização 23 de junho : encontrei uma questão relacionada aqui. Se eu definir ulimit -v 1024000 , verifique com ulimit -v e obtenho o valor correto de '1024000'. Se eu executar o script novamente, ele progredirá muito mais, mas acabará com o erro com o mesmo limite de memória atingido. Se eu verificar imediatamente ulimit -v , ele foi redefinido para o valor original de '524288'. Isso parece que pode ser a causa raiz do problema.

Minha configuração

$ cat /etc/redhat-release
CentOS release 5.5 (Final)

$ uname -a
Linux example.com 2.6.18-164.15.1.el5 #1 SMP Wed Mar 17 11:30:06 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

$ php -i | grep "PHP Version"
PHP Version => 5.2.9

$ httpd -V
Server version: Apache/2.0.63
Server built:   Feb  2 2011 01:25:12
Cpanel::Easy::Apache v3.2.0 rev5291
Server's Module Magic Number: 20020903:13
Server loaded:  APR 0.9.17, APR-UTIL 0.9.15
Compiled using: APR 0.9.17, APR-UTIL 0.9.15
Architecture:   64-bit
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/prefork"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D HTTPD_ROOT="/usr/local/apache"
 -D SUEXEC_BIN="/usr/local/apache/bin/suexec"
 -D DEFAULT_PIDLOG="logs/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="logs/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"

Saída de $ php -i : link

    
por Jess Telford 16.06.2011 / 05:04

7 respostas

2

M. A resposta do Tibbits alude a permitir que o Piwik use mais recursos durante o processo de arquivamento.

Existe uma limitação de quão grande um comando SQL pode ser executado, cujo padrão é de apenas 1 MB. Para mais informações; Pacote muito grande

Para aumentar a limitação de tamanho no MySQL, edite /etc/my.cnf e defina max_allowed_packet=32M

Verifique se o limite de memória do PHP está definido para ser alto o suficiente por processo bifurcado editando /usr/local/lib/php.ini e defina memory_limit = 512M

Por fim, certifique-se de que todos os processos tenham pelo menos um limite rígido de 1G antes que o sistema os desligue executando ulimit -v 1048576 na linha de comando.

Atualizar

ulimit -v 1048576 aumentará apenas o limite soft . Se o limite hard não for alto o suficiente, o sistema redefinirá automaticamente o limite flexível para o limite máximo.

Para definir o limite máximo, adicione a opção -H :

ulimit -vH 1048576

seguido pelo aumento do limite suave até este valor:

ulimit -vS 1048576
    
por 22.06.2011 / 10:54
2

Histórico:

Acabei de pegar a versão atual do Piwik - Na versão 1.5, a linha 969 aparece como:

public function addRowsFromSerializedArray( $stringSerialized )
{
    $serialized = unserialize($stringSerialized);
    if($serialized === false)
    {
        throw new Exception("The unserialization has failed!");
    }
    $this->addRowsFromArray($serialized);
}

e é especificamente $serialized = unserialize($stringSerialized); . A chamada para unserialize pode ser incrivelmente intensiva em memória. Há uma excelente postagem aqui .

Como você observou, isso claramente não é um bug no seu script e é um Out of Memory válido .

Sugestão: no arquivo de configuração, conforme mencionado acima no meu comentário:

/.../piwik/config/global.ini.php

Acho que você pode precisar aumentar um desses limites:

# during archiving, Piwik will limit the number of results recorded, for performance reasons
# maximum number of rows for any of the Referers tables (keywords, search engines, campaigns, etc.)
# this limit will also be applied to the Custom Variables names and values reports
datatable_archiving_maximum_rows_referers = 1000
# maximum number of rows for any of the Referers subtable (search engines by keyword, keyword by campaign, etc.)
datatable_archiving_maximum_rows_subtable_referers = 50

# maximum number of rows for any of the Actions tables (pages, downloads, outlinks)
datatable_archiving_maximum_rows_actions = 500
# maximum number of rows for pages in categories (sub pages, when clicking on the + for a page category)
# note: should not exceed the display limit in Piwik_Actions_Controller::ACTIONS_REPORT_ROWS_DISPLAY
#       because each subdirectory doesn't have paging at the bottom, so all data should be displayed if possible.
datatable_archiving_maximum_rows_subtable_actions = 100

# maximum number of rows for other tables (Providers, User settings configurations)
datatable_archiving_maximum_rows_standard = 500

onde eu mudei o ponto-e-vírgula para # sinais apenas para tornar legível o autocolor do sf.

Você também pode tentar adicionar:

CMD_TO_CHECK_SETTINGS="$PHP_BIN -i > /tmp/piwik-php-env.out"
$CMD_TO_CHECK_SETTINGS

para o arquivo archive.sh para determinar se há outras configurações em andamento que substituam o arquivo php.ini.

    
por 22.06.2011 / 07:08
0

este é definitivamente um bug de script. Parece que há um vazamento de memória, portanto, não importa o quanto você aumente o limite de memória no PHP, ele será atingido.

Eu uso o Piwik em um nível básico e não me lembro de usar um script de arquivamento diretamente. Piwik ainda é um pouco bugs, mas a versão mais recente é 1.4 e parece ser muito menos bugs que as anteriores.

Eu recomendo não mexer nas configurações do sistema ou do PHP para acomodar um script incorreto. Atingir o fórum de suporte do piwik pode ser uma ideia melhor

    
por 16.06.2011 / 05:36
0

Já tentou usar a opção definir linha de comando? php -d memory_limit = 512M test.php

btw você verificou o php.ini é legível pelo usuário executando php a partir da linha de comando?

    
por 22.06.2011 / 12:11
0

O Linux por proc / limite de usuário não tem nada a ver com isso; o erro que você está recebendo é especificamente ligado ao PHP.

Por esse motivo, suspeito que exista uma diretiva ini_set em algum lugar que substitua seu limite; mesmo se você colocar ini_set no arquivo de nível superior, o arquivo de nível inferior irá sobrescrevê-lo.

Basta executar "grep -r -i" ini_set "/ caminho / para / piwiki" e verificar se eles estão sobrescrevendo manualmente o limite.

    
por 23.06.2011 / 03:45
0

Você pode confirmar em qual arquivo de configuração você modificou os limites de memória? Note que existem duas configurações diferentes: uma para PHP executada via servidor web e a segunda para PHP executada via CLI.

~$ ls /etc/php5/
apache2  cli  conf.d
~$ ls /etc/php5/apache2/
conf.d  php.ini
~$ ls /etc/php5/cli/    
conf.d  php.ini

Além disso, se isso for executado por meio de um navegador, no mesmo diretório em que se encontra o script, crie um arquivo temp.php com o seguinte conteúdo:

<?php phpinfo(); ?>

Verifique o que o memory_limit mostra quando você navega para esse arquivo.

    
por 29.06.2011 / 03:20
0

Eu tenho esse problema na semana passada, minha solução no CentOS rehel é

nano /etc/httpd/conf/hpptd.conf

pesquisa diretiva RLimitMEM excluir ou comentado não usa essas diretivas ou se usar permitir 2000000 valor

  • salve este arquivo
  • reinicie o serviço
  • serviço httpd restart
por 11.02.2012 / 01:36