Große mysql Datenbank verkleinern

yago

Member
Hallo,

ich habe hier einen mysql Server mit einer großen Datenbank am laufen.
Die Datenbank enthält extrem viele alte Einträge, die überhaupt nicht mehr benötigt werden, und mittlerweile ist aufgrund der Größe der Datenbank (ca. 18GB) und der zur Verfügung stehenden Ressourcen die performance extrem mies.

Leider hat derjenige der sich das ausgedacht hat nicht nachgedacht, daher handelt es sich um eine MYISAM table, und alte Einträge werden nie gelöscht, obwohl im Prinzip immer nur die Einträge der letzen 24h benötigt werden. (dann wäre die ganze Datenbank vermutlich immer kleiner als 100mb, statt 18GB).
Ich würde daher gerne alle alten Einträge löschen, und die Tabelle auf InnoDB umstellen, und dann regelmäßig alle Einträge die älter als 24h Stunden sind löschen.

Wie gehe ich da am besten vor?
Das Problem ist, wenn ich jetzt einfach mit einem delete query alle Einträge lösche die älter als 24h sind, und auf InnoDB umstelle, wird die ganze Tabelle vermutlich mehrere Stunden blockiert sein, was eigentlich nicht passieren darf.

Gibt es da eine bessere Vorgehensweise?
 
Das Problem ist, wenn ich jetzt einfach mit einem delete query alle Einträge lösche die älter als 24h sind, und auf InnoDB umstelle, wird die ganze Tabelle vermutlich mehrere Stunden blockiert sein, was eigentlich nicht passieren darf.

Dann dreh das Ganze doch rum...exportiere alles <24Std, lösch die alte DB und importiere den Rest in die neue DB. So ist die Downtime minimal.
 
Sofern es eine kurze downtime geben darf: Du machst die Anwendung kurz dicht, kopierst alle benötigten Einträge in eine neue DB, auf neue DB umswitchen. Danach kannst Du die alte DB problemlos und effizient eliminieren?
 
Bevor man wild einfach in eine neue DB kopiert: ggfls die Zeit nehmen und suchen, ob man nicht die Struktur weiter verbessern kann, das erspart viel Ärger und eine gute Struktur bringt auch Performance.
Unabhängig davon halte ich den Weg, den Nexus aufgezeigt hat für sehr gut.
 
Unabhängig davon halte ich den Weg, den Nexus aufgezeigt hat für sehr gut.

Wobei das auch nur die Quick&Dirty-Variante ist. Man sollte schon wissen, was man da tut und sicherheitshalber den ganzen Prozeß vorher in einer lokalen VM testen, um sicherzustellen, daß danach auch wieder alles so läuft, wie es soll ;)
 
Datenbank(en) global locken, die Einträge der letzten 24h per SELECT...INTO...; in eine neue DB kopieren, App(s) auf neue DB ausrichten, globale Locks aufheben und wenn alles funktioniert hat, die alte(n) Datenbanken löschen.
Geht noch schneller als der Umweg per Dump+Reimport.
 
Man kann doch auch sicherlich die DB anweisen alle Datensätze einer Tabelle zu löschen, dessen Datensätze älter als ein Tag sind. Ich denke mal, dass ihr in einem Feld das Datum speichert. Um das dann alle 24 Stunden zu machen, kann ein Cronjob dafür angelegt werden, die nur einen SQL-Befehl schickt.
 
@Joe: stimmt, die Idee ist noch effizienter, weil auf die aufwendige SQL-Syntax-Erstellung und beim Import auf das Parsing verzichtet wird.

@Dead_EyE: Genau das sollte umgangen werden, weil die "Kosten" für das Löschen von ca. 18 GB - 100 MB Datensätze größer eingeschätzt werden als das Selektieren der 100 MB. Dazu spar man sich noch die u.U. notwendige Reorganisation der DB, um den physischen Platz tatsächlich freizugegeben zzgl. Reorganisation des Index.
 
Back
Top