Riesige Menge an bestimmten Datensätzen löschen (MySQL)

Dieses Thema im Forum "Technischer Support" wurde erstellt von xgamer405, 24. April 2014.

  1. xgamer405
    Offline

    xgamer405

    Registriert seit:
    11. Juni 2012
    Beiträge:
    91
    Minecraft:
    xgamer405
    Hallo zusammen,

    ich habe einen Tekkit Server auf dem das Plugin Core Protect installiert, allerdings vergessen das ich Wasser und Lava auf die Blacklist schreiben soll (also das dieses nicht geloggt werden soll). Jetzt habe ich das Problem das meine Datenbank innerhalb einem halben Jahr auf 44,4 GB gewachsen ist und so langsam der Platz auf der Festplatte (SSD) knapp wird.
    Jetzt würde ich gerne bestimmte Datensätze die aus der Relation "co_block" und in der Spalte "user" die ID's 8 und 10 (Wasser und Lava) rausfiltern und diese löschen. Das ganze habe ich schon mit Navicat probiert, (besagte ID's anzeigen und dann alle ersichtlichen Einträge löschen) allerdings schmiert mir da recht schnell das Programm ab, bzw. wenn ich die Einträge Pro Seite runterstelle, dann würde ich ewig brauchen bis ich alles löschen kann.
    Gibt es da einfachere Möglichkeiten? Beispielsweise einen MySQL Befehl den ich ausführen kann, oder ist das bei dieser Datengröße schon enorm schwierig geworden das umzusetzen?

    Mit freundlichen Grüßen
    XGaMeR
     
    #1
  2. Elrontur
    Offline

    Elrontur Ehem. Teammitglied

    Registriert seit:
    5. April 2013
    Beiträge:
    138
    Minecraft:
    Elrontur
    Idee mit PDO...

    Ich könnte dir zufälligerweise einen kleinen Code anbieten, den du evtl. irgendwie ausführen könntest:
    PHP:
    1. <?php
    2.   $dbconfig['host'] = 'localhost';
    3.   $dbconfig['base'] = 'minecraft'; /* DATENBANK-NAME */
    4.   $dbconfig['user'] = 'root';
    5.   $dbconfig['pass'] = '';
    6.   $dbconfig['char'] = 'utf8';
    7.  
    8.     try { /* VERSUCHE, CONNECTION AUFZUBAUEN */
    9.     $pdo = new PDO('mysql:host='.$dbconfig['host'].';dbname='.$dbconfig['base'].';charset='.$dbconfig['char'].';', $dbconfig['user'], $dbconfig['pass']);
    10.     $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    11.   } catch (PDOException $e) { /* "FANGE" FEHLERMELDUNGEN AB UND GIB SIE AUS */
    12.      die('[MySQL > PDO] ERROR: '.$e->getMessage());
    13.   }
    14.  
    15.   $checkusers = $pdo->prepare("SELECT user FROM co_block WHERE user=:userid"); /* IST ETWAS IN DER DATENBANK DRIN? - KANN SCHON ALLE KRAFT DES WEBSPACES AUFSAUGEN BEI SO VIEL DATEN! */
    16.     $checkusers->bindValue(':userid', '8'); /* DA KOMMT DIE "USER-ID" BZW. DIE BLOCK-ID REIN! */
    17.     $checkusers->execute();
    18.                    
    19.   if($checkusers->rowCount() >= 0) { /* IST MEHR ALS 0 DA, TU DAS */
    20.     while($row_useredit = $checkusers->fetchAll()) { /* fetchAll() VON NÖTEN? KEINE AHNUNG... :D */
    21.       $edituser = $pdo->prepare("DELETE FROM co_block WHERE user=:userid"); /* LÖSCHE ALLE EINTRÄGE - DENKE ICH JEDENFALLS... '/
    22.         $edituser->bindValue(':userid', '8'); /* NOCHMAL DIE ID ZUM LÖSCHEN... */
    23.         $edituser->execute();
    24.       echo '<p> Der User <b>&laquo;'.$row_useredit['user'].'&raquo;</b> wurde erfolgreich gelöscht. </p>';
    25.     }
    26.   } else { /* ANSONSTEN GIB FEHLER AUS */
    27.     echo '<p> Der User wurde nicht gefunden! </p>';
    28.   }
    29.  
    30.   $pdo = null;
    31. ?>
    Dinge zu beachten:
    • Ich habe die Datenbank mittels $pdo = null; geschlossen, habe das jedoch vorher noch nie gemacht... (Weil oben steht $pdo = new PDO(....) - da ich den Code jedoch mal übernommen hab, stand da eig. mal $dbh. Unten jedoch habe ich vergessen, das mal zu ändern! -.-)
    • Den Code habe ich jetzt mal nur improvisiert. (Siehe nächsten Punkt)
    • Ich kenne mich mit dieser Datenbank nicht aus... :D Vielleicht muss noch irgendwas essentielles geändert werden.
    • Es ist PDO und ist nur auf einem Webspace ausführbar. Dazu braucht der das Recht, externe (oder solche) MySQL-Verbindungen aufnehmen zu können, ist die MySQL-Datenbank nicht auf dem gleichen Webspace.
    • Ich habe jetzt nur die Abfrage gestaltet, ohne irgendwelche Sicherheitsmaßnahmen in Bezug auf die enorme Datengröße, die zu bearbeiten ist... Sowas kann ich nicht. :(
    Und allgemein habe ich nur etwas zusammengeschnipselt und das ist vielleicht total falsch. Jedoch ist es eine Idee und einen Versuch wert.
     
    #2
    1 Person gefällt das.
  3. xgamer405
    Offline

    xgamer405

    Registriert seit:
    11. Juni 2012
    Beiträge:
    91
    Minecraft:
    xgamer405
    Schon jetzt vielen Dank für den Code, allerdings funktioniert der noch nicht ganz.
    Wenn ich die Seite dann aufrufe bekomme ich folgende Fehlermeldung:
    Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2097152 bytes) in E:\**\**\mysql.php on line 22
    (Was bei mir übrigens
    PHP:
    1. while($row_useredit = $checkusers->fetchAll())
    ist).
    Die Seite braucht ca. 1-2 Sekunden um sich aufzubauen, dann bricht er mit dieser Fehlermeldung ab.


    Ich habs jetzt ganz simpel gelöst und in PhpMyAdmin folgenden Command ausgeführt:
    DELETE FROM co_block WHERE user=8
    Seitdem ist er mit 100% SSD Last am Arbeiten :D (seit ca. 12:10)
     
    #3
  4. xgamer405
    Offline

    xgamer405

    Registriert seit:
    11. Juni 2012
    Beiträge:
    91
    Minecraft:
    xgamer405
    Okay, nachdem ich jetzt einfach den Befehl in PhpMyAdmin ausgeführt habe, so Arbeitet die Festplatte ca. 2 Stunden. Währenddessen steht in dem Browserfenster "lade.." irgendwann scheint dieser Ladevorgang fertig zu sein und ich werde auf eine andere Seite weitergeleitet und das Lade steht nicht mehr da. Schätze das soll bedeuten das er Fertig ist, dem ist aber nicht der Fall. Ich habe jetzt immer noch 306 Millionen Datensätze (und Datensätze mit User ID 8 sind auch noch massig dabei)..

    Weiß da jemand vielleicht eine effizientere Variante?
     
    #4
  5. AnonymusChaotic
    Offline

    AnonymusChaotic

    Registriert seit:
    22. November 2013
    Beiträge:
    762
    Ort:
    Wien, Österreich
    Minecraft:
    AnonymusChaotic
    Warum löschst du nicht einfach die ganze Datenbank und beginnst neu zu sammeln? :)
     
    #5
  6. xgamer405
    Offline

    xgamer405

    Registriert seit:
    11. Juni 2012
    Beiträge:
    91
    Minecraft:
    xgamer405
    Weil ich alle anderen Teile der Datenbank noch brauche, ich logge alle Aktionen von Usern, hat jetzt jemand etwas gegrieft und ich würde die Datenbank nicht mehr haben könnte ich nicht nachweisen, wer diese Aktion durchgeführt hat.
     
    #6
  7. GermanUbuntu
    Online

    GermanUbuntu

    Drueck doch einfach mall ein Auge zu ;)
     
    #7
  8. xgamer405
    Offline

    xgamer405

    Registriert seit:
    11. Juni 2012
    Beiträge:
    91
    Minecraft:
    xgamer405
    Gibts denn keine Möglichkeit das irgendwie zu bereinigen, weil es wirklich zu groß ist?
     
    #8
  9. AnonymusChaotic
    Offline

    AnonymusChaotic

    Registriert seit:
    22. November 2013
    Beiträge:
    762
    Ort:
    Wien, Österreich
    Minecraft:
    AnonymusChaotic
    Ev. Auf eine neue datenbank zu speichern beginnen und nur von der alten noch eine gewisse zeit daten abrufen?
    Und irgendwann löschst du die alte einfach...
    Ist das technisch möglich?
     
    #9