User hat alle privaten Nachrichten gelöscht - was nun?
Verfasst: 09.05.2008 12:27
Mich wunderts ein bisschen, dass zu dem Thema im Forum nix zu finden ist. Gesucht habe ich heiß und innig danach, aber nichts gefunden.
Genau vor dem Problem stand ich vor ein paar Tagen, ein User hatte aus Versehen anstatt auf "Markierte löschen" auf "Alle löschen" geklickt und das geht schnell, denn die beiden Buttons liegen direkt nebeneinander. Einen Moment nicht aufgepasst und weg sind sie, ohne Chance für den User die wieder zurückzuholen.
Da mich das etliche Stunden gekostet hat, die Persönlichen Nachrichten aus dem letzten Backup herauszufischen und wieder in die Datenbank des Live-Forums einzuspielen, dachte ich mir, ich schreib das mal zusammen. Vielleicht hilfts ja dem einen oder anderen. Ich hatte zunächst keine Idee, wie da dranzugehen ist und hab einiges ausprobiert, bis ich auf den hier beschriebenen Lösungsweg kam.
Zunächst einmal: Wie jedes Wiederherstellen von Datensätzen in der Datenbank geht auch hier ohne Backup nichts. Und auch hier zeigt es sich wieder einmal, dass es schon sehr nützlich sein kann, wenn das letzte Backup der Datenbank nicht gerade 5 Monate alt ist. In meinem Fall hatte der User knapp 2 Stunden vor meinem letzten Backup gelöscht, also musste das vorletzte Backup ran und das war knapp 10 Tage alt. Damit sind halt schon ein paar Nachrichten weg, aber man kann nicht alles haben.
Was wir brauchen: Die Backupdatei (klar
), einen Editor für große Dateien, eine funktionsfähige lokale XAMPP-Installation mit Kopie des Live-Forums (Alle Verzeichnisse und Dateien, so wie es auf dem Live-Server läuft), lokalen und Web-Zugriff von MySQLDumper und phpmyadmin.
Ich arbeite bei so einer Aktion immer mit einer lokalen Installation des Forums, denn dabei kann man sich nicht das Live-System zerschießen. Ausserdem müssen wir das Datenbankbackup einspielen, um die notwendigen Tabellen bearbeiten zu können. Das Live-System würden wir damit auf den Stand des Backups zurücksetzen, das ist eher nicht so wünschenswert.
Im Prinzip läuft das Ganze darauf hinaus, die entsprechenden SQL-Kommandos zusammenzustellen, mit denen die nun fehlenden Datensätze wieder in die Datenbank eingefügt werden. Denn sie sind tatsächlich weg. Möglicherweise geht das auch einfacher über ausgeklügelte SQL-Befehle, aber dafür fehlt mir das entsprechende Wissen. Aber so, wie ich das hier beschreibe, funktioniert es.
Uns interessieren hier 2 Tabellen aus der Datenbank, die Tabelle phpbb_privmsgs und die Tabelle phpbb_privmsgs_text. Aus der ersten erhalten wir die Infos über die ID's der Nachrichten, die dann in der zweiten gesucht werden müssen.
Wie ihr wisst, ist jede PN zwei Mal in der DB vorhanden, bis sie gelöscht werden. Einmal für den Absender und einmal für den Empfänger. Beide haben unterschiedliche ID's, also müssen wir wirklich jede Nachricht einzeln suchen.
Und so gehen wir vor:
Zunächst spielen wir in der lokalen Installation des Forums das Backup mit MySQLDumper ein, passen die Pfade zur DB usw an und schauen, das es lokal mit dem Stand des Backups läuft. Damit ich weiß, wie viele PN es überhaupt sind, verpasse ich in der Tabelle phpbb_users dem entsprechenden User ein anderes Passwort, logge mich mit seinem Account ein, schaue in seine Inbox und zähle die Nachrichten. Das dient auch zum Vergleich mit der Anzahl der gefundenen Nachrichten, die wir gleich in der Tabelle suchen. Ausserdem notieren wir die User-ID des Users aus der phpbb_users Tabelle.
Dann öffnen wir die phpbb_privmsgs Tabelle im phpmyadmin und suchen nach den entsprechenden Einträgen mit dem SQL-Befehl:
SELECT * FROM `phpbb_privmsgs` where privmsgs_to_userid = <user_id> AND privmsgs_type = 0
Damit finden wir alle Nachrichten (d.h. zunächst nur die Subjects, aber auch die benötigten privmsgs_id). Uns interessieren hier nur die Nachrichten mit privmsgs_type-Status Null, denn das sind die Nachrichten, die beim Empfänger in der Inbox liegen und gelesen sind. Und auch nur die, die als Ziel (privmsgs_to_userid) die entsprechende User-ID haben. Die Anzahl der gefundenen Datensätze muss nun mit der vorhin ermittelten Anzahl der PN übereinstimmen, dann haben wir das richtig gemacht.
Hier liegt nun der Vorteil des phpmyadmin, denn ich kann die ermittelten Datensätze gleich in eine SQL-Datei exportieren. Das machen wir auch und öffnen die Exportdatei im Editor. Es fängt mit Tabelleninfos an, dann folgt die Strukturanweisung für die Tabelle. Das brauchen wir alles nicht, uns interessiert nur ab:
INSERT INTO `phpbb_privmsgs` (`privmsgs_id`, `privmsgs_type`, `privmsgs_subject`, `privmsgs_from_userid`, `privmsgs_to_userid`, `privmsgs_date`, `privmsgs_ip`, `privmsgs_enable_bbcode`, `privmsgs_enable_html`, `privmsgs_enable_smilies`, `privmsgs_attach_sig`, `privmsgs_attachment`) VALUES
Das ist unsere SQL-Anweisung für das Einfügen. Unmittelbar darauf beginnt der Datenteil:
(16547, 0, 'Re: Bla1', 32, 40, 1166666615, '5xxxxxfc', 1, 0, 1, 1, 0),
(3787, 0, 'Re: Tach!', 74, 40, 1166666646, '5xxxxxba', 1, 0, 1, 0, 0),
(12001, 0, 'Re: Re: Re: Wetter', 14, 40, 1166666630, '5xxxxx85', 1, 0, 1, 0, 0);
Die erste Gruppe sind die gleich noch in der Tabelle phpbb_privmsgs_text zu findenden ID's.
Wichtig ist, dass alle Datensätze in der zweiten Gruppe eine Null haben, das sind die des Users. Die fünfte Gruppe markiert die ID des Users, auf den es hier ankommt, der ist also der Empfänger der Nachrichten. Jede Zeile ausser der ersten (Der eigentliche SQL-Befehl) muss mit einem Komma abschließen, die letzte Zeile mit einem Semikolon.
Diesen Bereich zwischen der INSERT INTO-Anweisung und der letzten Datensatzzeile bis zum Semikolon kopieren wir uns in eine Textdatei, das ist schon der fertige SQL-Befehl zum Einfügen in das Live-System.
Nun muss der Textteil, also der eigentliche Nachrichteninhalt, aus der Tabelle phpbb_privmsgs_text anhand den eben ermittelten Nachrichten-ID's herausgesucht werden. Das zum Suchen der ID's erforderliche SQL-Kommando habe ich mir mit einem spaltenmarkierungsfähigen Editor zusammengestellt.
Der Befehl lautet:
SELECT * FROM `phpbb_privmsgs_text` WHERE privmsgs_text_id = 16547
or privmsgs_text_id = 3787
or privmsgs_text_id = 12001
Spaltenmarkierungsfähig heisst den ersten Teil des sich immer wieder wiederholenden Teils "or privmsgs_text_id = " in der erforderlichen Zeilenanzahl zu kopieren, so dass dieser Teil untereinander steht. Dahinter werden auf gleiche Weise die benötigten ID's aus der oben erstellten Datei herauskopiert und eingefügt. Diesen so zusammengestellten Befehl in das Befehlsfenster des phpmyadmin kopieren und ausführen. Nun werden alle gesuchten Textdatensätze angezeigt, die Anzahl muss natürlich mit der oben ermittelten Anzahl übereinstimmen.
Wie oben schon beschrieben wird dieser Teil nun in eine SQL-Datei exportiert, auch diese wird wieder mit einem Texteditor geöffnet und nur der Teil zwischen INSERT INTO und dem letzten Datensatz wird wieder herauskopiert, das ist der zweite Befehl zum späteren Einfügen in das Live-System. Das sieht dann so aus:
INSERT INTO `phpbb_privmsgs_text` (`privmsgs_text_id`, `privmsgs_bbcode_uid`, `privmsgs_text`) VALUES
(16457, '76bb66ffb2', 'Hallöle, Gruß'),
(3787, '9def01aed1', 'Moin'),
(12001, '5874652f35', 'guckste hier');
Das waren die Vorbereitungen. Jetzt ist es natürlich sinnvoll, das zu testen. Also mit dem User in die lokale Installation einloggen und die PN-Inbox leeren, alle löschen, Inbox leer.
Jetzt die beiden ermittelten und zusammengestellten Befehle nacheinander (Nicht beide auf einmal!) in das Befehlsfenster des phpmyadmin hineinkopieren und ausführen. War alles richtig, kommt die Erfolgsmeldung.
Nun wieder in die Inbox des Users schauen und wenn alles richtig war, sind die PN wieder da.
Jetzt der Ernstfall, diese beiden Befehle nun im phpmyadmin des Livesystems ausführen und dann sollten die PN wieder in der Inbox des Users vorhanden sein.
Anmerkungen:
Natürlich ist es sehr empfehlenswert, vor SQL-Manipulationen an der Datenbank des Live-Systems ein komplettes Datenbankbackup zu erstellen. Denn wir arbeiten direkt an der Datenbank und wenn etwas schiefgeht, kann das Live-Forum beschädigt werden.
Auch ist es sehr sinnvoll, den DB Maintenance Mod vorher zu installieren (Wenn nicht schon drauf), denn der kann mit "Prüfe Private Nachrichten-Tabellen" die Konsistenz der Tabellen prüfen.
Es bleibt dabei nicht aus, dass man den Inhalt der PN sieht. Das sollte dem User klar sein, dessen PN man hiermit wieder zurückholt.
Ich habe vor dem Einfügen der PN in das Live-System stichprobenartig nach den hier ermittelten Nachrichten-ID gesucht um zu prüfen, ob diese nicht wieder vergeben wurden. Das war nicht der Fall, anscheinend vergibt die Software gelöschte Nachrichten-ID's nicht wieder neu.
Alles auf eigene Gefahr. Comments welcome.
Genau vor dem Problem stand ich vor ein paar Tagen, ein User hatte aus Versehen anstatt auf "Markierte löschen" auf "Alle löschen" geklickt und das geht schnell, denn die beiden Buttons liegen direkt nebeneinander. Einen Moment nicht aufgepasst und weg sind sie, ohne Chance für den User die wieder zurückzuholen.
Da mich das etliche Stunden gekostet hat, die Persönlichen Nachrichten aus dem letzten Backup herauszufischen und wieder in die Datenbank des Live-Forums einzuspielen, dachte ich mir, ich schreib das mal zusammen. Vielleicht hilfts ja dem einen oder anderen. Ich hatte zunächst keine Idee, wie da dranzugehen ist und hab einiges ausprobiert, bis ich auf den hier beschriebenen Lösungsweg kam.
Zunächst einmal: Wie jedes Wiederherstellen von Datensätzen in der Datenbank geht auch hier ohne Backup nichts. Und auch hier zeigt es sich wieder einmal, dass es schon sehr nützlich sein kann, wenn das letzte Backup der Datenbank nicht gerade 5 Monate alt ist. In meinem Fall hatte der User knapp 2 Stunden vor meinem letzten Backup gelöscht, also musste das vorletzte Backup ran und das war knapp 10 Tage alt. Damit sind halt schon ein paar Nachrichten weg, aber man kann nicht alles haben.

Was wir brauchen: Die Backupdatei (klar

Ich arbeite bei so einer Aktion immer mit einer lokalen Installation des Forums, denn dabei kann man sich nicht das Live-System zerschießen. Ausserdem müssen wir das Datenbankbackup einspielen, um die notwendigen Tabellen bearbeiten zu können. Das Live-System würden wir damit auf den Stand des Backups zurücksetzen, das ist eher nicht so wünschenswert.
Im Prinzip läuft das Ganze darauf hinaus, die entsprechenden SQL-Kommandos zusammenzustellen, mit denen die nun fehlenden Datensätze wieder in die Datenbank eingefügt werden. Denn sie sind tatsächlich weg. Möglicherweise geht das auch einfacher über ausgeklügelte SQL-Befehle, aber dafür fehlt mir das entsprechende Wissen. Aber so, wie ich das hier beschreibe, funktioniert es.
Uns interessieren hier 2 Tabellen aus der Datenbank, die Tabelle phpbb_privmsgs und die Tabelle phpbb_privmsgs_text. Aus der ersten erhalten wir die Infos über die ID's der Nachrichten, die dann in der zweiten gesucht werden müssen.
Wie ihr wisst, ist jede PN zwei Mal in der DB vorhanden, bis sie gelöscht werden. Einmal für den Absender und einmal für den Empfänger. Beide haben unterschiedliche ID's, also müssen wir wirklich jede Nachricht einzeln suchen.
Und so gehen wir vor:
Zunächst spielen wir in der lokalen Installation des Forums das Backup mit MySQLDumper ein, passen die Pfade zur DB usw an und schauen, das es lokal mit dem Stand des Backups läuft. Damit ich weiß, wie viele PN es überhaupt sind, verpasse ich in der Tabelle phpbb_users dem entsprechenden User ein anderes Passwort, logge mich mit seinem Account ein, schaue in seine Inbox und zähle die Nachrichten. Das dient auch zum Vergleich mit der Anzahl der gefundenen Nachrichten, die wir gleich in der Tabelle suchen. Ausserdem notieren wir die User-ID des Users aus der phpbb_users Tabelle.
Dann öffnen wir die phpbb_privmsgs Tabelle im phpmyadmin und suchen nach den entsprechenden Einträgen mit dem SQL-Befehl:
SELECT * FROM `phpbb_privmsgs` where privmsgs_to_userid = <user_id> AND privmsgs_type = 0
Damit finden wir alle Nachrichten (d.h. zunächst nur die Subjects, aber auch die benötigten privmsgs_id). Uns interessieren hier nur die Nachrichten mit privmsgs_type-Status Null, denn das sind die Nachrichten, die beim Empfänger in der Inbox liegen und gelesen sind. Und auch nur die, die als Ziel (privmsgs_to_userid) die entsprechende User-ID haben. Die Anzahl der gefundenen Datensätze muss nun mit der vorhin ermittelten Anzahl der PN übereinstimmen, dann haben wir das richtig gemacht.
Hier liegt nun der Vorteil des phpmyadmin, denn ich kann die ermittelten Datensätze gleich in eine SQL-Datei exportieren. Das machen wir auch und öffnen die Exportdatei im Editor. Es fängt mit Tabelleninfos an, dann folgt die Strukturanweisung für die Tabelle. Das brauchen wir alles nicht, uns interessiert nur ab:
INSERT INTO `phpbb_privmsgs` (`privmsgs_id`, `privmsgs_type`, `privmsgs_subject`, `privmsgs_from_userid`, `privmsgs_to_userid`, `privmsgs_date`, `privmsgs_ip`, `privmsgs_enable_bbcode`, `privmsgs_enable_html`, `privmsgs_enable_smilies`, `privmsgs_attach_sig`, `privmsgs_attachment`) VALUES
Das ist unsere SQL-Anweisung für das Einfügen. Unmittelbar darauf beginnt der Datenteil:
(16547, 0, 'Re: Bla1', 32, 40, 1166666615, '5xxxxxfc', 1, 0, 1, 1, 0),
(3787, 0, 'Re: Tach!', 74, 40, 1166666646, '5xxxxxba', 1, 0, 1, 0, 0),
(12001, 0, 'Re: Re: Re: Wetter', 14, 40, 1166666630, '5xxxxx85', 1, 0, 1, 0, 0);
Die erste Gruppe sind die gleich noch in der Tabelle phpbb_privmsgs_text zu findenden ID's.
Wichtig ist, dass alle Datensätze in der zweiten Gruppe eine Null haben, das sind die des Users. Die fünfte Gruppe markiert die ID des Users, auf den es hier ankommt, der ist also der Empfänger der Nachrichten. Jede Zeile ausser der ersten (Der eigentliche SQL-Befehl) muss mit einem Komma abschließen, die letzte Zeile mit einem Semikolon.
Diesen Bereich zwischen der INSERT INTO-Anweisung und der letzten Datensatzzeile bis zum Semikolon kopieren wir uns in eine Textdatei, das ist schon der fertige SQL-Befehl zum Einfügen in das Live-System.
Nun muss der Textteil, also der eigentliche Nachrichteninhalt, aus der Tabelle phpbb_privmsgs_text anhand den eben ermittelten Nachrichten-ID's herausgesucht werden. Das zum Suchen der ID's erforderliche SQL-Kommando habe ich mir mit einem spaltenmarkierungsfähigen Editor zusammengestellt.
Der Befehl lautet:
SELECT * FROM `phpbb_privmsgs_text` WHERE privmsgs_text_id = 16547
or privmsgs_text_id = 3787
or privmsgs_text_id = 12001
Spaltenmarkierungsfähig heisst den ersten Teil des sich immer wieder wiederholenden Teils "or privmsgs_text_id = " in der erforderlichen Zeilenanzahl zu kopieren, so dass dieser Teil untereinander steht. Dahinter werden auf gleiche Weise die benötigten ID's aus der oben erstellten Datei herauskopiert und eingefügt. Diesen so zusammengestellten Befehl in das Befehlsfenster des phpmyadmin kopieren und ausführen. Nun werden alle gesuchten Textdatensätze angezeigt, die Anzahl muss natürlich mit der oben ermittelten Anzahl übereinstimmen.
Wie oben schon beschrieben wird dieser Teil nun in eine SQL-Datei exportiert, auch diese wird wieder mit einem Texteditor geöffnet und nur der Teil zwischen INSERT INTO und dem letzten Datensatz wird wieder herauskopiert, das ist der zweite Befehl zum späteren Einfügen in das Live-System. Das sieht dann so aus:
INSERT INTO `phpbb_privmsgs_text` (`privmsgs_text_id`, `privmsgs_bbcode_uid`, `privmsgs_text`) VALUES
(16457, '76bb66ffb2', 'Hallöle, Gruß'),
(3787, '9def01aed1', 'Moin'),
(12001, '5874652f35', 'guckste hier');
Das waren die Vorbereitungen. Jetzt ist es natürlich sinnvoll, das zu testen. Also mit dem User in die lokale Installation einloggen und die PN-Inbox leeren, alle löschen, Inbox leer.
Jetzt die beiden ermittelten und zusammengestellten Befehle nacheinander (Nicht beide auf einmal!) in das Befehlsfenster des phpmyadmin hineinkopieren und ausführen. War alles richtig, kommt die Erfolgsmeldung.
Nun wieder in die Inbox des Users schauen und wenn alles richtig war, sind die PN wieder da.
Jetzt der Ernstfall, diese beiden Befehle nun im phpmyadmin des Livesystems ausführen und dann sollten die PN wieder in der Inbox des Users vorhanden sein.
Anmerkungen:
Natürlich ist es sehr empfehlenswert, vor SQL-Manipulationen an der Datenbank des Live-Systems ein komplettes Datenbankbackup zu erstellen. Denn wir arbeiten direkt an der Datenbank und wenn etwas schiefgeht, kann das Live-Forum beschädigt werden.
Auch ist es sehr sinnvoll, den DB Maintenance Mod vorher zu installieren (Wenn nicht schon drauf), denn der kann mit "Prüfe Private Nachrichten-Tabellen" die Konsistenz der Tabellen prüfen.
Es bleibt dabei nicht aus, dass man den Inhalt der PN sieht. Das sollte dem User klar sein, dessen PN man hiermit wieder zurückholt.
Ich habe vor dem Einfügen der PN in das Live-System stichprobenartig nach den hier ermittelten Nachrichten-ID gesucht um zu prüfen, ob diese nicht wieder vergeben wurden. Das war nicht der Fall, anscheinend vergibt die Software gelöschte Nachrichten-ID's nicht wieder neu.
Alles auf eigene Gefahr. Comments welcome.