TeamSpeak Server Migration von SQLite auf MySQL/MariaDB

    • Official Post

    Hallo,


    in diesem Tutorial möchte ich euch gerne zeigen, wie ihr euren TeamSpeak Server schnell, einfach und ohne Probleme von einer SQLite Datenbank auf eine MySQL bzw. MariaDB Datenbank migrieren könnt. Beachtet bitte, dass die Migration eine gewisse Downtime der virtuellen TeamSpeak Server in Anspruch nimmt.


    Inhaltsverzeichnis

    • Vorbereitungen
    • Migration

    Bevor wir die Migration starten, bereiten wir die neue Datenbank erstmal soweit vor, dass die Migration selbst dann nicht so lange dauert und wir die Downtime möglichst gering halten können.


    Ich habe zu Test-Zwecken einen TeamSpeak Server auf Basis von SQLite installiert und ein paar Channel erstellt, sowie Dateien hochgeladen:



    • Vorbereitungen
      Aktuell nutzen wir die SQLite Datenbank und mussten hierfür auch nichts installieren. Für die neue Datenbank müssen wir jedoch eine installieren. Je nachdem, welche ihr nutzen wollt, müsst ihr bei allen folgenden Schritten entsprechend "mysql" oder "mariadb" nutzen. Ich werde das ganze auf Basis der MariaDB zeigen, da die neuen TeamSpeak Server Versionen ab Version 3.0.11 darauf aufsetzen werden.


      Zu erst installieren wir die Datenbank und alle dazugehörigen Softwarepakete:

      Code
      aptitude install mariadb-server-5.5


      Hinweis: Hierfür benötigt ihr - jedenfalls unter Debian Wheezy 7.6 - den SID Repository: deb Index of /debian sid main (Wenn ihr den Repository nachträglich hinzufügt, solltet ihr jetzt erstmal euer System upgraden, da es sonst zu ein paar Problemen führen kann.)


      Während der Installation werdet ihr auch nach einem "root" Passwort gefragt. Das ist NICHT das root Passwort für euren Server, sondern das für die Datenbank!


      Sobald das fertig ist, sollte man sich auf die Datenbank verbinden können. Das prüfen wir einfach mal:

      Code
      mysql -u root -p


      Nach der Passwort-Eingabe sollten wir dann etwas sehen, was dem hier ähnelt:


      Als nächstes legen wir uns eine leere Datenbank an und weisen ihm einen Benutzer zu:

      Code
      CREATE DATABASE teamspeak;


      Hinweis: Neue Datenbank heißt "teamspeak".

      Code
      GRANT ALL PRIVILEGES ON teamspeak.* TO 'teamspeak'@'%' IDENTIFIED BY 'geheimes$Passwort123';


      Hinweis: "teamspeak.*" heißt "Datenbankname.ALLE_TABELLEN". Wir geben alle Rechte dem User "teamspeak", welcher sich von überall aus einloggen darf (%) - sollte er nur von der lokalen Maschine sich einloggen dürfen, muss hier "localhost" anstatts des %-Zeichens stehen. "geheimes$Passwor123" ist das Passwort, welches dann für den Benutzer gilt.

      Code
      FLUSH PRIVILEGES;


      Hinweis: Wir müssen danach die Rechte nochmal laden, damit diese wirklich wirksam werden.


      Jetzt gehen wir mit Hilfe des Befehls "exit" oder der Tastenkombination "Strg" und "D" aus der MySQL bzw. MariaDB Shell raus und versuchen uns als der neu angelegte Benutzer auf die Datenbank ein zu loggen:

      Code
      mysql -u teamspeak -p teamspeak


      Hinweis: "-u teamspeak" ist der Benutzername und das letzte "teamspeak" ist der Datenbankname.


      Bei der MariaDB sieht man das gut, ob es geklappt hat oder nicht:


      Gut. Das hat geklappt. Als nächstes erstellen wir - falls noch nicht vorhanden - unsere Konfigurationsdateien für unseren TeamSpeak Server, sodass er beim nächsten Start die MySQL bzw. MariaDB nutzen kann. Logge dich hierfür als der System-Benutzer ein, der den TeamSpeak Server verwaltet. Bei mir heißt der "teamspeak":

      Code
      su - teamspeak


      Zu erst erstellen wir unsere ts3server.ini im root-Verzeichnis des TeamSpeak 3 Servers, welche wie folgt aussieht:

      Code
      $ cat ts3server.inimachine_id=1default_voice_port=9987voice_ip=192.168.178.212licensepath=filetransfer_port=30033filetransfer_ip=0.0.0.0query_port=10011query_ip=192.168.178.212query_ip_whitelist=query_ip_whitelist.txtquery_ip_blacklist=query_ip_blacklist.txtdbplugin=ts3db_mariadbdbpluginparameter=ts3db_mariadb.inidbsqlpath=sql/dbsqlcreatepath=create_mariadb/dblogkeepdays=90logpath=logslogquerycommands=0dbclientkeepdays=30


      Dann benötigen wir noch die Konfigurationsdatei für die SQL-Verbindung:

      Code
      $ cat ts3db_mariadb.ini[config]host=127.0.0.1port=3306username=teamspeakpassword=geheimes$Passwort123database=teamspeaksocket=


      Jetzt müssen wir noch überprüfen, ob die benötigte Bibliothek vorhanden ist:

      Code
      ldd libts3db_mariadb.so


      bzw.

      Code
      ldd libts3db_mysql.so


      Für detaillierte Informationen hierzu solltet ihr euch diese Themen bzw. Beiträge anschauen:


      Perfekt. Jetzt haben wir unsere Konfigurationsdateien fertig und eine leere Datenbank angelegt. Der nächste Schritt wird etwas schwieriger. Wir müssen jetzt irgendwie die Daten aus der SQLite Datenbank in die neue MySQL bzw. MariaDB Datenbank kriegen. Laut dem englisch-sprachigen TeamSpeak Forum ist das nicht möglich: howto convert database SQLITE to MySQL?
      Ich zeige euch, wie das aber trotzdem geht. ;)


      PS: Wer das Paket "sqlite3" noch nicht installiert hat, muss das jetzt tun, denn das wird zum exportieren der Daten benötigt:

      Code
      aptitude install sqlite3


    • Migration
      ACHTUNG: Ab jetzt wird es Downtime geben! Wie lange hängt davon ab, wie der Migrationsprozess verläuft.


      Zu erst bringen wir die aktuelle Datenbank in einen konsistenten Zustand. Hierfür müssen wir einfach nur die TeamSpeak Instanz stoppen:

      Code
      ./ts3server_startscript.sh stop


      Als nächstes generieren wir uns einen Dump unserer aktuellen Datenbank, um diese dann in die neue Datenbank importieren zu können:

      Code
      sqlite3 ts3server.sqlitedb .dump > db_dump


      Da SQLite andere Syntaxe verwendet, müssen wir den Dump erst noch anpassen. Hierfür habe ich mal zwei Befehle gebastelt, welche das ganze sehr schnell erledigen:

      Code
      sed 's/\PRAGMA foreign_keys=OFF;//g' db_dump | sed 's/\BEGIN TRANSACTION;//g' | sed 's/\COMMIT;//g' | sed '/sqlite_sequence/d' | sed 's/AUTOINCREMENT/AUTO_INCREMENT/' | tr -d '"' > temp_dump


      Code
      tail -n +3 temp_dump > db_dump_converted


      Jetzt müssen wir nur noch eine einzige Zeile anpassen, damit diese auch funktioniert. Es gibt eine Zeile, die die Tabelle "tokens" erstellt. Hier fehlt die Größe für das Feld "token_customset". Das setzen wir einfach manuell. :)


      Wenn man den TS mit einer MySQL/MariaDB Datenbank aufgesetzt hat, wird man feststellen, dass der Wert auf 255 gesetzt ist, daher werden auch wir den einfach nutzen:

      Code
      mysql> DESCRIBE tokens;+-------------------+------------------+------+-----+---------+-------+| Field             | Type             | Null | Key | Default | Extra |+-------------------+------------------+------+-----+---------+-------+| server_id         | int(10) unsigned | YES  |     | NULL    |       || token_key         | varchar(50)      | NO   |     | NULL    |       || token_type        | int(11)          | YES  |     | NULL    |       || token_id1         | int(10) unsigned | YES  |     | NULL    |       || token_id2         | int(10) unsigned | YES  |     | NULL    |       || token_created     | int(10) unsigned | YES  |     | NULL    |       || token_description | varchar(255)     | YES  |     | NULL    |       || token_customset   | varchar(255)     | YES  |     | NULL    |       |+-------------------+------------------+------+-----+---------+-------+8 rows in set (0.01 sec)


      Öffnet einfach den konvertierten Dump mit einem Editor eurer Wahl - am besten vi oder vim - und passt die Zeile an:

      Code
      vim db_dump_converted


      Bei vi/vim könnt ihr mit Hilfe von folgender Eingabe direkt zur entsprechenden Zeile springen:

      Code
      /CREATE TABLE token


      Ihr solltet dann folgende Zeile sehen:

      Quote

      CREATE TABLE tokens ( server_id integer unsigned, token_key varchar(50) NOT NULL, token_type integer, token_id1 integer unsigned, token_id2 integer unsigned, token_created integer unsigned, token_description varchar(255), token_customset varchar);


      Diese ändern wir wie folgt ab:

      Quote

      CREATE TABLE tokens ( server_id integer unsigned, token_key varchar(50) NOT NULL, token_type integer, token_id1 integer unsigned, token_id2 integer unsigned, token_created integer unsigned, token_description varchar(255), token_customset varchar(255));


      Wir müssen nur das rot markierte hinzufügen. :)


      Diesen konvertierten Dump spielen wir jetzt in die neue Datenbank ein:

      Code
      mysql -u teamspeak -p teamspeak < db_dump_converted


      Hinweis: Das verlangte Passwort ist das für den Datenbank-Benutzer "teamspeak" in diesem Fall!


      Nun verifizieren wir das ganze:

      Code
      mysql -u teamspeak -p teamspeak


      Code
      SHOW TABLES;


      Und siehe da: Unsere Tabellen sind alle vorhanden:


      Aber sind auch die Inhalte übernommen worden? Suchen wir einfach mal nach einem Eintrag, der drin stehen muss: Ihr selber. ;)

      SQL
      SELECT client_nickname,client_id,server_id,client_lastconnected,client_lastip FROM clients WHERE client_nickname="Sebbo";


      Sollte sowas hier zurück liefern:

      Code
      +-----------------+-----------+-----------+----------------------+-----------------+| client_nickname | client_id | server_id | client_lastconnected | client_lastip   |+-----------------+-----------+-----------+----------------------+-----------------+| Sebbo           |         2 |         1 |           1411300550 | 192.168.178.201 |+-----------------+-----------+-----------+----------------------+-----------------+1 row in set (0.00 sec)


      Ebenso suchen wir mal unseren virtuellen Server:

      SQL
      SELECT * FROM server_properties WHERE ident="virtualserver_name" AND value="Test Server";


      Sieht dann zum Beispiel so aus:

      Code
      +-----------+------+--------------------+-------------+| server_id | id   | ident              | value       |+-----------+------+--------------------+-------------+|         1 |    1 | virtualserver_name | Test Server |+-----------+------+--------------------+-------------+1 row in set (0.00 sec)


      Wenn man diese zwei Sachen findet, sollte alles andere eigentlich auch passen. Zudem haben wir beim importieren auch keinen Fehler erhalten. :)


      Jetzt können wir die Dumps auch wieder löschen:

      Code
      rm db_dump temp_dump db_dump_converted


      Bevor wir jetzt allerdings den Server starten, müssen wir noch ein paar Eigenschaften der virtuellen Server anpassen, sonst werden existierende Server ignoriert und ein neuer Standard-Server eingerichtet. Ändert man das nicht, sieht die Datenbank danach so aus, wenn man einen virtuellen Server davor hatte:

      Code
      MariaDB [teamspeak]> SELECT * FROM servers;+-----------+-------------+------------------+-------------------+---------------------+-----------------------+---------------------+-----------------------+| server_id | server_port | server_autostart | server_machine_id | server_month_upload | server_month_download | server_total_upload | server_total_download |+-----------+-------------+------------------+-------------------+---------------------+-----------------------+---------------------+-----------------------+|         1 |        9987 |                1 |                   |              976430 |                     0 |              976430 |                     0 ||         2 |        9987 |                1 | 1                 |                   0 |                     0 |                   0 |                     0 |+-----------+-------------+------------------+-------------------+---------------------+-----------------------+---------------------+-----------------------+2 rows in set (0.00 sec)


      Wir wollen aber keinen neuen, sondern nur unsere(n) bereits existierende(n), daher passen wir die Werte einfach an. :)


      In unserer "ts3server.ini" steht eine Variable namens "machine_id" mit dem Wert 1. Diesen Wert tragen wir jetzt bei allen virtuellen Servern nachträglich ein:

      SQL
      UPDATE servers SET server_machine_id='1' WHERE server_machine_id="";


      Der Befehl sucht quasi alle virtuellen Server, wo keine machine_id gesetzt ist und setzt dann dort überall den Wert 1.


      Gut. Jetzt passen wir noch unser Start-Skript an, sodass es die Konfigurationsdateien verwendet. Hierfür editieren wir das "ts3server_startscript.sh" und ersetzen folgende Zeile...

      Code
      COMMANDLINE_PARAMETERS="${2}" #add any command line parameters you want to pass here


      ...durch diese:

      Code
      COMMANDLINE_PARAMETERS="inifile=ts3server.ini" #add any command line parameters you want to pass here


      WICHTIG: Wenn ihr jetzt von der Version 3.0.10.3 auf die Version 3.0.11 zusätzlich wechselt, müsst ihr noch die SQL-Fixes einspielen, die der Version 3.0.11 beiliegen. Hierfür nutzt ihr die beiden nachfolgenden Befehle:

      Code
      mysql --user=<DB_BENUTZERNAME> --password=<DB_PASSWORT> <DB_NAME> < <TEAMSPEAK_VERZEICHNIS>/sql/updates_and_fixes/convert_mysql_to_mariadb.sqlmysql --user=<DB_BENUTZERNAME> --password=<DB_PASSWORT> <DB_NAME> < <TEAMSPEAK_VERZEICHNIS>/sql/updates_and_fixes/mariadb_fix_latin_utf8.sql


      Sieht dann zum Beispiel so aus:

      Code
      mysql --user=teamspeak --password=sehrGeheimes$Passwort!2014 teamspeak_db < /home/teamspeak/sql/updates_and_fixes/convert_mysql_to_mariadb.sqlmysql --user=teamspeak --password=sehrGeheimes$Passwort!2014 teamspeak_db < /home/teamspeak/sql/updates_and_fixes/mariadb_fix_latin_utf8.sql


      Nach diesem Schritt starten wir unseren TeamSpeak Server wieder:

      Code
      ./ts3server_startscript.sh start


      Nach einem Blick in die Log-Datei der Instanz, sollte er jetzt auch mit dem entsprechend richtigen Plugin hochgekommen sein:

      Quote

      $ cat logs/ts3server_2014-09-21__14_46_58.442879_0.log
      [...]
      2014-09-21 14:46:58.444390|INFO |DatabaseQuery | | dbPlugin name: MariaDB plugin, (c)TeamSpeak Systems GmbH
      [...]


      Wenn wir uns jetzt auf unseren TeamSpeak Server wieder verbinden, sollte auch alles wieder so erscheinen und vor zu finden sein, wie vorher:

      Auch unsere Dateien finden sich wieder dort ein, wo wir sie vorher abgelegt hatten. :)

    Joa, so viel zur Migration von SQLite auf MySQL bzw. MariaDB: Es geht! ;)


    Sollte es Fragen geben, helfe ich gerne. Einfach hier als neuen Beitrag schreiben. Über Feedbacks freue ich mich natürlich auch. :)

  • HrHr hab mich zu früh gefreut - da muss beim Konvertieren was schiefgelaufen sein. Mein Server besteht nur noch teilweise -und das hauptsächlich- aus kryptischen Zeichen. Kann es bei bestimmten Channel-Namen aufgrund der Zeichensatz-Umstellung zu Komplikationen kommen?


    Ich halte euch auf dem Laufenden.

  • This threads contains 4 more posts that have been hidden for guests, please register yourself or log-in to continue reading.