Der WaschbärIrgendwie passt das bei mir nicht zusammen…
Eigentlich wollte ich mich um meine Bremsen am Fahrrad kümmern, nötig ist es allemal.- Aber erst schnell noch die MySql-Datenbank auf UTF-8 umstellen.
Tagsüber hatte ich ja zu diesem Thema schon auf ‚Toaoyfbiaoyfaoyf’s Couch‚ gelegen. Diverse Anleitungen findet man dazu auch im Internet – es sollte also schnell gehen.
Soweit die Theorie.
Irgendwann vor einem guten Jahr hatte ich dass allerdings schon mal versucht und aufgegeben. Damals funktionierten danach ein paar Plugins nicht mehr und ein auskommentieren der define(‚DB_CHARSET‘, ‚utf8‘);-Zeile und weiter benutzen der alten Datenbank half damals auch…

Heute wollte ich es also noch mal angehen. Schon weil mich diese ständige Es existiert eine automatische Speicherung dieses Artikels, die aktueller ist als die Version unten. Automatische Speicherung ansehen.-Zeile nervt. Wenn man dann nach sieht was er neues hat, sind es (fast) immer nur die Sonderzeichen, die auf der einen Seite lesbar und auf der anderen Seite als Fragezeichen vorhanden sind – Nerv –

Die passendste Anleitung fand ich übrigens in einem Typo3-Blog: Türchen 10: TYPO3-Installation auf UTF-8 umstellen im Adventskalender von Tobaoyfiasaoyfaoyf Liegl. Danke!

  • Als erstes sollte man dem Apache ’sagen‘, dass jetzt UTF-8 der Standard ist:
    AddDefaultCharset UTF-8
    #AddDefaultCharset ISO-8859-1
  • Für den Export der Datenbanken hatte ich mir dann schon einen Script geschrieben:
    • #!/bin/bash
      #suf="_"
      myUser="User"
      datum_kurz=$(date '+%Y-%m-%d')
      ff="wordpress${suf}-${datum_kurz}.dump"
    • Einen Dump der Datenbank machen :
      mysqldump --compatible=mysql40 --default-character-set=latin1 -B wordpress${suf} -u $myUser -p > $ff
    • Erstmal die Zeilen umbrechen:
      perl -pi -e 's%\),\(%),\n (%g;' $ff
    • Das ‚Charset‘ umstellen:
      perl -pi -e 's%CHARSET=latin1%CHARSET=utf8%g; \
      s%(\`)wordpress(\`)%$1wp_test$2%g; \
      s%DEFAULT CHARACTER SET latin1 COLLATE latin1_german1_ci%DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci%g;' $ff

      Außerdem wurde hier gerade jedes Vorkommen der Datenbank ‚wordpress‘ in ‚wp_test‘ geändert. Toaoyfbiaoyfaoyf hatte mich nämlich auf die Idee gebracht, doch einfach die Daten in eine neue Datenbank zu schreiben und den Eintrag in der ‚config.php‘ zu ändern.
    • Wahlweise oder besser in verschiedenen Konstellationen, habe ich das Dump-File dann noch umgewandelt. Man kann bei ‚recode‘ ja auch verschiedene Paare kombinieren, zum Beispiel ‚UTF-8..ISO-8859-1,HTML_4.0..ISO-8859-1‚:
      cat $ff | recode --force UTF-8..ISO-8859-1 >> $ff.latin1
      und tatsächlich stellt ‚file‘ auch Unterschiede fest:
      # file wordpress-2008-12-11.dump*
      wordpress-2008-12-11.dump: UTF-8 Unicode text, with very long lines
      wordpress-2008-12-11.dump.latin1: ISO-8859 text, with very long lines
    • Also wieder zurück damit in die Datenbank:
      # mysql --default-character-set=latin1 -h localhost -u User -p < wordpress-2008-12-11.dump.latin1
      Enter password:
      ERROR 1071 (42000) at line 12211: Specified key was too long; max key length is 1000 bytes
    • Der Fehler kam aus einer Tabelle von OpenID:
      # vi wordpress-2008-12-12.dump.latin1 +12211
      ....
      CREATE TABLE `wp_openid_associations` (
      `server_url` varchar(255) NOT NULL default '',
      `handle` varchar(255) NOT NULL default '',
      `secret` blob,
      `issued` int(11) default NULL,
      `lifetime` int(11) default NULL,
      `assoc_type` varchar(64) default NULL,
      PRIMARY KEY (`server_url`(235),`handle`)
      ) TYPE=MyISAM;
      ...

      Das OpenID-Plugin nutze ich sowieso nicht, also gar nicht weiter darüber nachgedacht und einfach das Plugin deaktiviert und die zugehörigen Tabellen entfernt. Zur Not kann man das Plugin ja hinterher wieder installieren.
      DROP TABLE wp_openid_associations, wp_openid_identities, wp_openid_nonces;
    • Und alles noch mal:
      ...
      mysql --default-character-set=latin1 -h localhost -u $myUser -p < $ff.latin1
    • Nun funktionierte zwar das Einlesen der Daten, aber das Blog war nicht mehr nutzbar:
      Warning: array_keys() [function.array-keys]: The first argument should be an array in /usr/share/wordpress/wp-includes/widgets.php on line 1044
    • Scheinbar werden die Optionen nicht mehr vernünftig aus der Tabelle ‚wp_options‘ bezogen.
  • Den restlichen Abend habe ich dann damit verbracht, alle möglich Varianten auszutesten:
    Nachtrag: Wer jetzt an einem Auszug der ganzen Irrwege interessieren ist, liest einfach unmittelbar weiter, alle Anderen können ganz geschmeidig bei der anderen Idee weiter lesen.

    • erster Versuch
      • Einlesen der nicht umgewandelten Dump-Datei
        mysql --default-character-set=utf8 -h localhost -u uwe -p < wordpress-2008-12-12.dump
        Danach endeten die Posts am ersten Umlaut
      • dasselbe ohne utf8:
        mysql -h localhost -u uwe -p < wordpress-2008-12-12.dump
        brachte eine erste Besserung, das Plugin myGallery fand plötzlich wieder die Fotos, die Artikel waren auch wieder vollständig, allerdings waren da jede Menge ragezeichen im Text…
      • Bei dem folgenden Befehl fehlten die Sonderzeichen gleich ganz:
        mysql -h localhost -u uwe -p < wordpress-2008-12-12.dump.latin1
    • Dann hatte ich noch eine andere Idee:
      • Offensichtlich ist ja nur die Tabelle ‚wp_options‘ das Problem. Also noch mal die gesamte Datenbank neu einlesen und dann kann ich ja die Tabelle ‚wp_options‘ per MySql-Befehl aus der alten Datenbank kopieren. Also Datenbank löschen und dann wieder neu füllen:
        mysql --default-character-set=utf8 -h localhost -u uwe -p < wordpress-2008-12-12.dump.latin1
      • Dann die Tabelle ‚wp_options‘ in Tabelle ‚wp_options_1‘ ‚umbenennen‘:
        CREATE TABLE `wp_test`.`wp_options_1` (
        `option_id` bigint( 20 ) NOT NULL AUTO_INCREMENT ,
        `blog_id` int( 11 ) NOT NULL default '0',
        `option_name` varchar( 64 ) COLLATE utf8_unicode_ci NOT NULL default '',
        `option_value` longtext COLLATE utf8_unicode_ci NOT NULL ,
        `autoload` varchar( 20 ) COLLATE utf8_unicode_ci NOT NULL default 'yes',
        PRIMARY KEY ( `option_id` , `blog_id` , `option_name` ) ,
        KEY `option_name` ( `option_name` )
        ) ENGINE = MYISAM DEFAULT CHARSET = utf8 COLLATE = utf8_unicode_ci AUTO_INCREMENT =107463;
        INSERT INTO `wp_test`.`wp_options_1`
        SELECT *
        FROM `wp_test`.`wp_options` ;
      • Versuche ich doch mal die Tabelle ‚wp_options‘ aus der noch originalen ‚wordpress‘-Datenbank in die Tabelle ‚wp_options‘ in der Datenbank ‚wp_test‘ zu kopieren:
        CREATE TABLE `wp_test`.`wp_options` (
        `option_id` bigint( 20 ) NOT NULL AUTO_INCREMENT ,
        `blog_id` int( 11 ) NOT NULL default '0',
        `option_name` varchar( 64 ) NOT NULL default '',
        `option_value` longtext NOT NULL ,
        `autoload` varchar( 20 ) NOT NULL default 'yes',
        PRIMARY KEY ( `option_id` , `blog_id` , `option_name` ) ,
        KEY `option_name` ( `option_name` )
        ) ENGINE = MYISAM DEFAULT CHARSET = latin1;
        INSERT INTO `wp_test`.`wp_options`
        SELECT *
        FROM `wordpress`.`wp_options` ;
      • Und dann das CharSet noch ändern:
        DROP TABLE `wp_test`.`wp_options` ;
        ALTER TABLE `wp_options` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
      • Im Test ging es dann damit.
        Produktiv werde ich damit wohl noch warten, bis ich etwas mehr Zeit habe.

Deutlich nach 23 Uhr hatte ich dann plötzlich keine Lust mehr, noch nach den Bremsen zu sehen – soviel zum mal schnell umstellen.

Mit dem Fahrrad war ich übrigens heute auch unterwegs. Erst zur Arbeit und dann auch wieder Heaaoyftheaoyfraoyfaoyf von der Kita abholen. Auf dem Rückweg nach Hause haben wir nun endlich mal den letzten Chip für das Karussell auf dem CentrO-Weihnachtsmarkt abgefahren.
Uwes Tachodaten

  • Gesamtstrecke: 18,43 km
  • reine Fahrzeit: 0:53:13 h
  • Durchschnitt: 20,78 km/h
  • Maximal: 38,3 km/h

Nachtrag:
Gerade (viel später) habe ich mal wieder ein anderes UTF8-Problem und stieß auf einen guten der Tipp, der mir half erst mal alles zu zerschießen, dann aber auch einen Schritt weiter zu kommen…