Hilfe: Datenbank löscht am Ende einer Anweisung plötzlich selbstständig tausende Datensätze

Nokiland

Benutzer
Beiträge
11
Ein "Hallo" in die Runde

Heue wende ich mich endlich an Experten - bisher dachte ich das "Problem" allein "irgendwie" weg zu bekommen.

Es wird eine CSV-Datei mit über 138.000 Datensätzen eingelesen. Jeder Datensatz wird in eine Tabelle geschrieben.

PHP:
$sql = "INSERT INTO TABELLE (AnzahlFall)VALUES('$AnzahlFall')";

Das klappt zunächst auch wunderbar. Doch plötzlich - die Tabelle enthält genau so viele Datensätze wie die CSV Datei - verringert sich die Anzahl der Datensätze in der Datenbank wie von Geisterhand.

Hier ist alles noch okay:
tabelle_1.jpg


Das Script läuft noch etwas weiter und .....
tabelle_2.jpg


Es werden über 3.000 Datensätze wieder schrittweise gelöscht.

Die Tabellenstruktur:
tabelle_struktur.jpg


Ich verglich die in der Tabelle gespeicherten Datensätze mit den Datensätzen der CSV Datei. Es wurden keine bestimmten Datensätze nach einem bestimmten Muster entfernt. Es wurden schlicht die letzten xyz Tausend Datensätze wieder entfernt, nachdem sie eingetragen wurden. In einem Durchlauf mal mehr, im nächstern weniger.

Was kann passiert sein? Ist jemand so etwas schon unter gekommen?

Viele Grüße ... und bleibt alle gesund ....
 
Werbung:
mal als wilde Vermutung: Du machst das mit PHP und kommst an die Grenzen der Scriptlaufzeiten oder so. Hint: man kann CSV direkt einlesen, das kann wohl sogar MySQL.
 
Hallo akretschmer,
danke für Deine Antwort.

Ja, PHP. Die Scriptlaufzeit habe ich auf 2.000 Sekunden gesetzt, das Script läuft maximal 20 Minuten.

CSV-Datei direkt in MySql einlesen? Hm, wäre auch schön, wenn es besser klappen würde.

Zunächst würde es mir helfen, wenn das aktuelle Script funktioniert.

Der Fehler muss irgendwie an der Datenbank liegen. Nirgendwo in meinem Script stehen Anweisungen zum löschen von Datensätzen.
 
wie viele Datensätze enthält Deine CSV? Du kennst die exakte Anzahl? Dein Script (was wir nicht kennen und was hier auch Offtopic wäre) läuft fehlerfrei? Jeder einzelne Insert?
 
Es wurden keine Daten "vergessen". Das Script läuft sauber. Es ist wie oben beschrieben. ALLE Datensätze werden eingelesen und am Ende der Laufzeit werden von der Datenbank automatisch ein paar tausend Sätze wieder gelöscht. Siehe Bilder. Ich kann mir das alles nicht erklären. Als ob die Datenbank am Ende irgendetwas "bereinigt". Speicher habe ich genug, bin bei 1&1 und belege nur die Hälfte meines Datenbank Speichers.
Ich wüßte auch nicht, wie ich vom PHP-Skript aus die Tätigkeit der Datenbank stoppen könnte, sobald sich die Zahl der Datensätze wieder verringert.
 
  • keine Antwort auf die Frage, ob die exakte Anzahl bekannt ist
  • falls bekannt, stimmt sie exakt mit dem ersten Bild überein?
  • die Bilder sind vermutlich PMA, darauf sollte man sich nicht generell verlassen. Zu den Fehlern von MySQL kommen die von PMA noch dazu. Die DB hat eigene Befehle, die Datensätze zu zählen. Hint: die Anzahl von Datensätzen in einer Tabelle kann für dieselbe Tabelle in unterschiedlichen Transaktionen unterschiedlich sein.
  • nebenläufige Clients, die Rows löschen?
  • verwendest Du evtl. Blackhole als Storage Engine?
  • wer keine wichtigen Daten verlieren will, verwendet kein MySQL. Zumindest nicht ein zweites Mal.
 
- Die exakte Zahl der Datensätze ist bekannt,
- Ja, die Bekannte Zahl der Datensätze stimmt mit dem angefertigten Screenshot überein,
- PMA - was ist das?
- Andreas: was sind nebenläufige Clients, die Zeilen löschen? In einer einfachen Schleife wird die CSV Datei eingelesen und jede Zeile in die Tabelle geschaufelt. Danach ist Pumpe im Schacht

- Blackhole ist bei mir deaktiviert

Bei den Erweiterungen ist aufgelistet: binlog,CSV,GPL,InnoDB, MRG_MYISAM,MyISAM
 
PMA = PhpMyAdmin. Ein buntes Etwas, was Du offenbar benutzt.

Es gibt Datenbanken, da können mehrere Leute in unterschiedlichen Sessions auf z.B. auch auf dieselbe Tabelle zugreifen. Die einen fügen was ein, andere führen Updates durch und wieder andere löschen Datensätze. Klingt verdammt spannend, gell?
 
Nee, bei mir greift keiner ein.
Aber eine Frage: Hattest Du schon so ein "Problem" wie ich? Hast Du von Jemand gehört, bei dem automatich Datensätze gelöscht wurden?
Das Problem trat erst auf, als ich über (schätzungsweise) 110.000 Datensätze einlesen wollte. Mir fiel vor einigen Tagen einfach auf, daß die Zahlen aus meiner Datenbank nicht mit dem Datenbestand des RKI überein stimmte. Davor lief alles wunderbar, ohne dass mir tausende Datensätze gelöscht wurden.
 
Ich tippe auf ... ein Rollback.

Eher nicht. Vermutlich ist das MyISAM (MyISAM speichert IIRC im Table-Header die aktuelle Anzahl Rows, weil MVCC noch unbekannt ist, ebenso Transaktionen), und wenn es InnoDB wäre, würde PMA als zweiter Client nur bereits commitete Rows sehen (erste Anzahl, die ja nach seinen Worten korrekt ist). Ich würde ja die Anzahl mal direkt in der DB erfragen. Keine Ahnung, wie PMA die Zahl würfelt. Davon abgesehen - man kann CSV auch direkt einlesen, das dürfte bei der lächerlich geringen Datenmenge deutlich schneller als in 20 Minuten gehen.
 
Werbung:
Hallo Walter,
Fehler im Script schließe ich zu 99% aus. Die paar Zeilen sind übersichtlich.

PHP:
if (($handle = fopen($CSV_Datei, "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 9000, "\t")) !== FALSE) {
        $row++;
        for ($c=0; $c < $num; $c++) {
            $Zeile =  $data[$c];
            $daten = EXPLODE(",",$Zeile);
            $FID             = $daten[0];   
            $IdBundesland    = str_pad($daten[1], 2 ,'0', STR_PAD_LEFT);
            $AnzahlFall     = $daten[6];
            $AnzahlTodesfall= $daten[7];
            $IdLandkreis     = str_pad($daten[9], 5 ,'0', STR_PAD_LEFT);
            $AnzahlGenesen     = $daten[17];

            if($Speichermodus  == 2 AND $row > 1 ){
                $sql_save_2 = "INSERT INTO cor_fallzahlen_RKI_fall (
                            FID,
                            IdBundesland,
                            AnzahlFall,
                            AnzahlTodesfall,
                            IdLandkreis,
                            AnzahlGenesen
                        )VALUES(
                            '$FID',
                            '$IdBundesland',
                            '$AnzahlFall',
                            '$AnzahlTodesfall',
                            '$IdLandkreis',
                            '$AnzahlGenesen'
                        )";
                if (DB_Query($DBCon, $sql_save_2) != FALSE) {
                }else{
                    echo "FEHLER! $sql_save<br>";
                }
            } // if($Speichermodus ...
        } // for ...
    } // while ...
} // if (($handle ...

Ich würde ja die Anzahl mal direkt in der DB erfragen.

Oh, das habe ich vor ein paar Tagen mal getan und mich gewundert. Ich wollte die ID (AUTO_INCREMENT) des letzten Datensatzes haben, damit ich nur NEUE CSV-Datensätze einfügen lassen kann. Also nur die Zeilen der CSV-Datei ab Zeile XYZ in die Datenbank ein tragen. Aber mein Query gab eine scheinbar fehlerhafte ID aus. So viele Datensätze waren gar nicht in meine Tabelle drin.

"LOAD DATA LOCAL INFILE" - ist ja alles schön. Aber ich bin kein wirklicher Programmierer. Ich wurstele mich so durch, weiß wie ich von A nach B komme bei dem was ich vorhabe - aber wenn ein "LOAD DATA LOCAL INFILE" daher kommt, muss ich auf die Schulbank.

Eigentlich kein großes Ding - wenn ich Zeit für die Schulbank hätte. Ergo versuche ich ein Problem mit dem zu lösen, was mir in die Hände fällt. Mein nächster Versucht wäre: ich splitte die CSV-Datei und schaue was da passiert. Aber vermutlich werden auch dann noch Datensätze geklaut. Ich weiß es nicht. Ich weiß auch nicht, ob die "LOAD DATA LOCAL INFILE" Geschichte zuverlässig werkelt.

Aber .... ich beschäftige mich in der Tat gerade mit dem direkten einlesen der CSV-Datei.

Nebenbei: vorhin lief fast alles super.
Zeige Datensätze 0 - 24 (138127 insgesamt, Die Abfrage dauerte 0.0936 Sekunden.)
138.307 Datensätze hätten heute im Kasten sein müssen, fehlen diesmal nur ein paar ....
 
Zurück
Oben