Hallo an alle,
sorry, falls ich im falschen Forum bin, verschiebt den Thread einfach, falls es doch ins PHP-Anfänger- oder SQL-Forum gehört. Danke :)
Hier mein Problem:
Ich habe mir ein etwas größeres Script geschrieben, welches von einem meiner Server zweimal täglich mehrere GZ-Dateien herunterladen soll. Diese GZ-Dateien enthalten jeweils eine CSV-Datei und sollen dann lokal entpackt werden. Die nun entstandene CSV-Dateien sollen jeweils in eine MySQL-Datenbank eingetragen werden. Ich behandel immer nur jeweils eine Datei nach der anderen, also Download, entpacken, eintragen, fertig! Download, entpacken, eintragen, fertig!....
Die Größe der GZ-Dateien schwankt hierbei von wenigen KB bis hin zu mehreren hundert MB. Die CSV-Datei beinhalteen je nach Größe auch zwischen wenigen hundert bis hin zu 4 Mio Datensätzen.
Ich habe mir für jeden einzelnen Schritt eine eigene Funktion geschrieben. Somit kann ich auch zu Testzwecken jeden Schritt manuell und getrennt testen.
Hier nun ein Teilausschnitt, wie ich die GZ-Datei herunterlade:
PHP-Code:
$handle = fopen($result2['downloadlink'],'r');
$handle2 = fopen($tmpgzname,'w');
while(!feof($handle)) {
$buffer = fgets($handle, 9216);
fwrite($handle2,$buffer);
}
fclose($handle);
fclose($handle2);
Hier ein Teilausschnitt, wie ich die GZ-Datei entpacke:
PHP-Code:
$handle = gzopen($result2['tempgzname'],'r');
$handle2 = fopen($result2['tempcsvname'],'w');
while(!gzeof($handle)) {
$buffer = gzread($handle, 9216);
fwrite($handle2,$buffer);
}
gzclose($handle);
fclose($handle2);
Hier ein Teilausschnitt, wie ich die CSV-Datei in die Datenbank eintrage:
PHP-Code:
$handle = fopen ($result2['tempcsvname'],"r");
while (($data = fgetcsv ($handle, 9216, ";")) !== FALSE ) {
$sql3 = "INSERT INTO csv (val1, val2, val3.......val67) VALUES ('".$val1."','".$val2."','".$val3."'............'".$val67."')";
$result3 = mysql_query($sql3) OR die (mysql_error());
}
fclose ($handle);
Ich habe bei den Teilausschnitten natürlich nur das notwendigste gepostet, der originalcode ist um einiges länger. In den ersten Zeilen der PHP-Datei habe ich folgende Einstellungen vorgenommen:
PHP-Code:
ignore_user_abort(1);
set_time_limit(0);
clearstatcache();
ini_set('implicit_flush', 1);
Tests funktionieren einwandfrei bis zu einer Größe von etwa 110.000 Datensätzen. Der Download und das Entpacken funktioniert auch mit GZ-Dateien, die knapp 400.000 Datensätze enthalten. Ich konnte mich bisher eigentlich nicht beschweren.
Nur bricht mir das Script jedesmal nach ziemlich genau 50-60 Sekunden ab....ohne Fehlermeldung....ohne alles....innerhalb dieser 50-60 Sekunden schafft es das Script etwa 110.000 Datensätze einzutragen. Wenn ich alle vorherigen Schritte durchlaufen lasse, vergehen ja auch schon etwa 2 bis 3 Minuten, die ohne Abbruch funktionieren. Nur beim letzten Schritt bricht es mir immer wieder ab. Ich habe auch schon einen kleinen do { bla } while(true); - Test geschrieben, um eventuelle andere Timeouts zu testen. Ich habe das Testscript mit kill (über die shell) nach 321 Minuten manuell beendet. Es liegt also meiner Meinung nach nicht an PHP und auch nicht am Apache. Versuche, nach jedem kleinen Schritt eine kleine Erfolgs- oder Fehlermeldung mit "echo" an den Browser zu senden lassen das Script leider trotzdem abbrechen. Ich sehe
"Download gestartet",
"Download beendet",
"Entpacken gestartet",
"Entpacken beendet",
"DB-Insert gestartet...",
"5% fertig",
"10% fertig"
...
"40% fertig"
und dann hörts auf.
Auch habe ich schon die Funktion einzeln laufen lassen, um die Zeit korrekt messen zu können. Also ohne Download und entpacken (die Dateien sind ja schon vorhanden). Es bringt alles nichts. Ich versteh einfach nicht, warum das Script hier abbricht. Liegt es (meine letzte Vermutung) an MySQL?
Oder mach ich doch etwas anderes grundlegend falsch?
Ich muss ehrlich sein, dass ich mir (leider leider) nicht so ganz sicher bin, ob ich die Buffereinstellung der ersten beiden Funktionen (9216) richtig gesetzt habe. Bei der dritten Funktion muss der Buffer auf jeden Fall über 8000 stehen, da die einzelnen Datensätze ziemlich lange Texte mit beinhalten können.
Allerdings haben die ersten beiden Funktionen ja auch nichts mit dem eigentlichen Problem zu tun.
PHP-Code:
ini_set('max_execution_time', '300');
ini_set('max_input_time', '10');
error_reporting(E_ALL);
ini_set( 'display_errors', 'On' );
Die eben genannten Einstellung habe ich Testweise mal aktiviert, bringen mich aber auch um keinen Schritt weiter.
Bin für jeden Tipp, Trick dankbar.
Grüße