Bibliothek zum Einlesen von MediaWiki-Dump-Dateien

Für ein Projekt war ich auf der Suche nach einer Java-Bibliothek um die Dumps einer MediaWiki-Installation auszuwerten. Fündig geworden bin ich bei der Bibliothek WikiXMLJ, welche allerdings mittlerweile einige Jahre auf dem Buckel hat. Auf Basis dieser Bibliothek habe ich die Bibliothek mediawikixml erstellt. Um die Bibliothek zu nutzen, muss im ersten Schritt eine neue Paketquelle in der pom.xml definiert werden.

<repositories>
 <repository>
 	<id>github</id>
 	<url>https://maven.pkg.github.com/seeseekey/mediawikixml</url>
 </repository>
</repositories>

Anschließend kann die Abhängigkeit eingebunden werden:

<dependency>
    <groupId>net.seeseekey</groupId>
    <artifactId>mediawikixml</artifactId>
    <version>1.0.1</version>
</dependency>

Damit kann die Bibliothek zur Auswertung von MediaWiki-Dumps genutzt werden:

WikiXMLParser wikiXMLParser = WikiXMLParserFactory.getParser("dump-current.xml");

try {

    wikiXMLParser.setPageCallback(new PageCallbackHandler() {
        public void process(WikiPage page) {
            System.out.println(page.getId());
            System.out.println(page.getRevisionId());
            System.out.println(page.getTimestamp());
            System.out.println(page.getTitle());
            System.out.println(page.getWikiText());
        }
    });

    wikiXMLParser.parse();
} catch (Exception e) {
    e.printStackTrace();
}

Für jede MediaWiki-Seite wird unter anderem die ID, die Revision, der Timestamp, der Titel und der eigentliche Inhalt der Seite geparst. Die Bibliothek setzt mindestens Java 8 voraus. Zu finden ist das Repository mit der Bibliothek auf GitHub. Die Bibliothek ist unter der Apache License in Version 2 lizenziert und damit freie Software.

Dump einer MediaWiki-Installation erstellen

Wer eine Wiki mit der freien Software MediaWiki betreibt und einen Dump derselben erstellen möchte, kann hierfür eines der Werkzeuge nutzen, welches bereits mit der MediaWiki-Installation mitgeliefert wird. Im Ordner maintenance findet sich für diese Zwecke das PHP-Skript dumpBackup.php:

php dumpBackup.php --full > dump.xml

Mit dem Befehl wird die komplette Wiki, inklusive der Historie jeder Seite, gesichert und in den Dump geschrieben. Soll nur der aktuelle Stand der Wiki gesichert werden, so kann hierfür der Parameter current genutzt werden:

php dumpBackup.php --current > dump.xml

Für eine komplette Sicherung der Wiki sollte nicht nur der Dump, sondern auch der Ordner images gesichert werden.

MySQL Datenbanken einzeln sichern

Möchte man mittels “mysqldump” die einzelnen Datenbanken einer MySQL-Installation sicheren, so sähe das so für eine Datenbank in etwa so aus:

mysqldump -u root -p<passwort> --result-file=example.sql --databases example

Packt man das nun ein Skript, muss jede Tabelle von Hand in dieses Skript eintragen werden. Allerdings könnte man das ganze auch über den SQL Befehl “SHOW DATABASES” lösen und das ganze in ein automatisches Skript gießen. Auf der Webseite dev.mensfeld.pl findet man ein solches Skript. Ich habe das ganze kleineren Modifikationen unterzogen (so wird z.B. die “performance_schema” Tabelle nicht mitgesichert) und auf GitHub zur Verfügung gestellt.

Probleme beim MySQL Dump mit nicht existierenden Nutzern

Unter Linux kann man mittels

mysqldump -u root -p<Passwort> --all-databases --result-file=dump.sql

alle MySQL Datenbanken in eine SQL Datei sichern. Allerdings kann es unter Umständen passieren, das man folgende Meldung bekommt:

mysqldump: Got error: 1449: The user specified as a definer ('u123456789'@'%') does not exist when using LOCK TABLES

Ein Workarround wäre es das ganze mit dem Parameter “–lock-tables=false” aufzurufen:

mysqldump -u root -p<Passwort> --all-databases --result-file=dump.sql

Allerdings behandelt dies nur die Symptome. Um das Problem zu lösen wird im ersten Schritt der fehlende Nutzer angelegt.

GRANT ALL ON *.* TO 'u123456789'@'%' IDENTIFIED BY 'passwort';

Meist ist ein View oder eine Storaged Procedure in welcher der nicht existierende Nutzer definiert wurde, wie in diesem Beispiel:

ALTER ALGORITHM=UNDEFINED DEFINER=`u123456789`@`%` SQL SECURITY DEFINER VIEW `mana_v_online_chars` AS select `l`.`char_id` AS `char_id`,`l`.`login_date` AS `login_date`,`c`.`user_id` AS `user_id`,`c`.`name` AS `name`,`c`.`gender` AS `gender`,`c`.`level` AS `level`,`c`.`map_id` AS `map_id` from (`mana_online_list` `l` join `mana_characters` `c` on((`l`.`char_id` = `c`.`id`)))

Nachdem der View korrigiert wurde, in dem dort ein gültiger Nutzer angegeben wurde, kann der temporär angelegte Nutzer entfernt werden.

MySQL Dump auf der Konsole einspielen

Wenn man auf einem Server eine bestehende MySQL Datenbank einspielen möchte, so kann man natürlich auf Softwarepakete wie phpMyAdmin zurückgreifen. Problematisch wird das ganze immer dann, wenn die einzuspielende Datenbank größer ist oder auf dem Server kein Webserver mit installiertem PHP vorhanden ist.

Für solche Fälle gibt es die MySQL Kommandozeile (“mysql”). Existiert die Datenbank noch nicht, so sollte im ersten Schritt mittels “mysql” eine Datenbank und ein Nutzer erstellt werden:

mysql> CREATE DATABASE datenbankname;
mysql> GRANT ALL PRIVILEGES ON datenbankname.* TO nutzername@localhost IDENTIFIED BY 'geheim';
mysql> quit

Anschließend kann der Dump in die neu angelegte Datenbank eingespielt werden:

mysql -u root -p<Passwort> datenbankname < dump.sql

Alternativ kann die Datenbank anstatt mit “root” auch mit dem neu angelegten Nutzer importiert werden.