Die Situation
Ich habe ein Problem mit einem PHP-Skript, bei dem die folgende Fehlermeldung angezeigt wird:
Fatal error: Out of memory (allocated 359923712) (tried to allocate 72 bytes) in /path/to/piwik/core/DataTable.php on line 969
Das Skript, das ich ausführe, ist: /path/to/piwik/misc/cron/archive.sh
Ich gehe davon aus, dass die Zahlen Bytes sind, was bedeutet, dass die Gesamtzahl ungefähr 360 MB beträgt.
In jeder Hinsicht habe ich die Speicherbeschränkungen auf dem Server deutlich über 360 MB erhöht, aber dies ist die Anzahl (Geben oder Nehmen eines Bytes), bei der ständig Fehler auftreten.
Bitte beachten Sie : Bei dieser Frage geht es weder um die Behebung eines Speicherverlusts im Skript noch darum, warum das Skript selbst so viel Speicher verwendet. Das Skript ist Teil des Piwik-Archivierungsprozesses, daher kann ich keine Speicherlecks usw. beheben. Weitere Informationen zu diesem Skript und warum ich das Speicherlimit erhöhe, finden Sie unter "Einrichten der automatischen Archivierung".
Die Frage
Angesichts der Tatsache, dass das Skript versucht, mehr als 360 MB Speicher zu verwenden, den ich nicht ändern kann, warum scheint es mir nicht möglich zu sein, die für PHP auf meinem Server verfügbare Speichermenge zu erhöhen?
Update 23. Juni : Hintergrundinformationen finden Sie unter "Was ich versucht habe"> "Erhöhen der Speicherbeschränkungen pro Prozess unter Linux". Wenn ich dies einstelle ulimit -v 1024000
, überprüfen Sie es mit " ulimit -v
Ich erhalte den korrekten Wert" 1024000 ". Wenn ich das Skript erneut ausführe, wird es viel weiter gehen, aber irgendwann wird ein Fehler auftreten, wenn das gleiche Speicherlimit (~ 360 MB) erreicht wurde. Wenn ich es sofort überprüfe ulimit -v
, wurde es auf den ursprünglichen Wert von '524288' zurückgesetzt. Dies scheint die Hauptursache des Problems zu sein.
Was ich versucht habe
Erhöhung des Speicherlimits von PHP
Angesichts der Datei php.ini:
php -i | grep php.ini
Configuration File (php.ini) Path => /usr/local/lib
Loaded Configuration File => /usr/local/lib/php.ini
Ich habe diese Datei bearbeitet, daher lautet die Anweisung memory_limit.
memory_limit = -1
Starten Sie Apache neu und überprüfen Sie, ob der neue Wert feststeckt.
$ php -i | grep memory_limit
memory_limit => -1 => -1
Führen Sie das Skript aus und erhalten Sie den gleichen Fehler.
Ich habe auch versucht 1G
, 768M
usw. alle zum gleichen Ergebnis (dh keine Änderung).
Update 22. Juni : Basierend auf Vangel's Hilfe habe ich versucht, post_max_size
in Kombination mit der Einstellung 20M einzustellen memory_limit
. Auch dies hat keine Auswirkung.
Update 23. Juni : Basierend auf der Hilfe von olefebvre kann ich bestätigen, dass der Benutzer, der das Skript ausführt, über Lese- / Schreibberechtigungen für die Datei php.ini verfügt, die die Einstellungen von enthält memory_limit
.
Entfernen des Speicherlimits für untergeordnete Prozesse von Apache
Ich habe die Datei httpd.conf gefunden und bearbeitet, um sicherzustellen, dass es keine RLimitMEM
Direktive gibt.
Ich habe dann WHMs Apache-Konfiguration> Speichernutzungsbeschränkungen verwendet, um eine Einschränkung zu generieren, die angeblich 1000 MB betrug (und durch Überprüfen von httpd.conf bestätigt wurde).
Beides führte zu keiner Änderung des Skriptfehlers bei 360 MB.
Erhöhen der Speichergrenzen pro Prozess unter Linux
Die im System festgelegten aktuellen Grenzwerte:
$ ulimit -m
524288
$ ulimit -v
524288
Ich habe versucht, beide auf unbegrenzt zu setzen:
$ ulimit -m unlimited
$ ulimit -v unlimited
$ ulimit -m
unlimited
$ ulimit -v
unlimited
Dies hat wiederum zu keiner Verbesserung meines Problems geführt.
Update 23. Juni : Ich bin hier auf ein verwandtes Problem gestoßen. Wenn ich einstelle ulimit -v 1024000
, überprüfe es mit ulimit -v
Ich erhalte den korrekten Wert von '1024000'. Wenn ich das Skript erneut ausführe, wird es viel weiter gehen, aber irgendwann wird ein Fehler auftreten, wenn dasselbe Speicherlimit erreicht wurde. Wenn ich es sofort überprüfe ulimit -v
, wurde es auf den ursprünglichen Wert von '524288' zurückgesetzt. Dies scheint die Hauptursache des Problems zu sein.
Mein Setup
$ 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"
Ausgabe von $ php -i
: http://pastebin.com/EiRut6Nm
Antworten:
Hintergrund:
Ich habe gerade die aktuelle Version von Piwik gekauft. In Version 1.5 wird Zeile 969 wie folgt angezeigt:
und ist speziell
$serialized = unserialize($stringSerialized);
. Der Anruf beiunserialize
kann unglaublich speicherintensiv sein. Es gibt einen ausgezeichneten Beitrag hier .Wie Sie bereits bemerkt haben, ist dies eindeutig kein Fehler in Ihrem Skript und ein gültiger Speichermangel .
Vorschlag: In der Konfigurationsdatei, wie oben in meinem Kommentar angegeben:
/.../piwik/config/global.ini.php
Ich denke, Sie müssen möglicherweise eine dieser Grenzen erhöhen:
wo ich die Semikolons in # Zeichen geändert habe, nur um die Autocolor von sf lesbar zu machen.
Sie können auch versuchen, Folgendes hinzuzufügen:
in archive.sh, um festzustellen, ob andere Einstellungen im Gange sind, die die Datei php.ini überschreiben.
quelle
memory_minimum_limit
auf 1024 erhöht und die von Ihnen aufgelisteten Variablen um jeweils den Faktor 10 erhöht und ulimit -m und ulimit -v auf 'unbegrenzt' gesetzt. Die Fehlermeldung, die ich jetzt erhalte, lautet:SQLSTATE[08S01]: Communication link failure: 1153 Got a packet bigger than 'max_allowed_packet' bytes
Weitere Untersuchungen haben mich dazu veranlasst, mysqlds zu erhöhenmax_allowed_packet=32M
(war zuvor bei1M
). Lief das Drehbuch perfekt! Ich werde es eingrenzen und über die genaue Lösung berichten :)/etc/my.cnf
und einstellenmax_allowed_packet=32M
. 2. Bearbeiten/usr/local/lib/php.ini
und einstellenmemory_limit = 512M
. 3. Stellen Sie einulimit -v 1048576
. Ich weiß nicht warum, aber das Ändern der Einstellungen, die Sie in der Konfigurationsdatei von piwik erwähnt haben, scheint den zweiten oben angegebenen SQL-Fehler verursacht zu haben, der mich dazu veranlasste, max_allowed_packet festzulegen. Vielen Dank für Ihre Hilfe!ulimit
Ihnen angegebenen großzügigen Einstellungen verfügt.Die Antwort von M. Tibbits spielt darauf an, dass Piwik während des Archivierungsprozesses mehr Ressourcen verwenden kann.
Es gibt eine Einschränkung, wie groß ein SQL-Befehl ausgeführt werden kann, der standardmäßig nur 1 MB beträgt. Für mehr Information; Paket zu groß
Um die Größenbeschränkung in MySQL zu erhöhen, bearbeiten
/etc/my.cnf
und festlegenmax_allowed_packet=32M
Stellen Sie sicher, dass das PHP-Speicherlimit pro gegabeltem Prozess durch Bearbeiten
/usr/local/lib/php.ini
und Festlegen hoch genug eingestellt istmemory_limit = 512M
Stellen Sie schließlich sicher, dass alle Prozesse mindestens eine feste Grenze von 1 G haben, bevor das System sie durch Ausführen
über die Befehlszeile abschaltet .ulimit -v 1048576
Aktualisieren
ulimit -v 1048576
erhöht nur die weiche Grenze. Wenn das harte Limit nicht hoch genug ist, setzt das System das weiche Limit automatisch auf das des harten Limits zurück.Fügen Sie den
-H
Schalter hinzu, um das harte Limit festzulegen:gefolgt von einer Erhöhung des Soft-Limits auf diesen Wert:
quelle
Dies ist definitiv ein Skriptfehler. Es scheint, dass es einen Speicherverlust gibt, egal wie sehr Sie das Speicherlimit in PHP erhöhen, es wird es treffen.
Ich benutze Piwik auf einer grundlegenden Ebene und kann mich nicht erinnern, jemals ein Archivierungsskript direkt verwendet zu haben. Piwik ist immer noch ein bisschen fehlerhaft, aber die neueste Version ist 1.4 und scheint viel weniger fehlerhaft zu sein als die vorherigen.
Ich empfehle, nicht mit System- oder PHP-Einstellungen herumzuspielen, um ein fehlerhaftes Skript aufzunehmen. Das Piwik-Support-Forum zu besuchen, könnte eine bessere Idee sein
quelle
Haben Sie versucht, die Befehlszeilenoption definieren zu verwenden? php -d memory_limit = 512M test.php
Übrigens, haben Sie überprüft, ob die php.ini für den Benutzer lesbar ist, der php über die Befehlszeile ausführt?
quelle
php -d memory_limit=512M
erzeugt das gleiche Ergebnis wie das Festlegen des Werts in der Datei php.ini. Vielen Dank für die Vorschläge :)php -d memory_limit=2G /path/to/test.php
Ihrer Information : Ich habe versucht, mit test.php anzurufen,<?php $str = ""; while(true) $str .= "M";?>
das Folgendes enthielt: was zu der gleichen Fehlermeldung führte:Fatal error: Out of memory (allocated 362545152) (tried to allocate 362282961 bytes) in /path/to/test.php on line 1
Das Linux-Limit pro Prozess / Benutzer hat damit nichts zu tun. Der Fehler, den Sie erhalten, ist speziell an PHP gebunden.
In diesem Sinne vermute ich, dass es irgendwo eine ini_set-Direktive gibt, die Ihr Limit überschreibt. Selbst wenn Sie ini_set in eine Datei der obersten Ebene einfügen, wird diese von der Datei der unteren Ebene überschrieben.
Führen Sie einfach `grep -r -i" ini_set "/ path / to / piwiki" aus und prüfen Sie, ob das Limit manuell überschrieben wird.
quelle
Können Sie bestätigen, in welcher Konfigurationsdatei Sie die Speicherbeschränkungen geändert haben? Beachten Sie, dass es zwei verschiedene Konfigurationen gibt: eine für PHP, das über den Webserver ausgeführt wird, und die zweite für PHP, das über die CLI ausgeführt wird.
Wenn dies über einen Browser in demselben Verzeichnis ausgeführt wird, in dem sich das eigentliche Skript befindet, erstellen Sie eine temp.php-Datei mit den folgenden Inhalten:
Überprüfen Sie, wie das
memory_limit
angezeigt wird, wenn Sie zu dieser Datei navigieren.quelle
php -i
bestätigt die Ausgabe von , dass ich memory_limit an der richtigen Stelle gesetzt habe. Vielen Dank für die Eingabe.Ich habe dieses Problem letzte Woche, meine Lösung in CentOS Rehel ist
Suche RLimitMEM-Direktive löschen oder kommentieren Nein verwendet diese Direktiven oder wenn Verwendung erlauben 2000000 Wert
quelle