WordPress-Blog mit Themes in eine neue Domäne auf einem anderen Apache-Server umziehen

Gestern hat mich ein Problem meiner Frau etwas Nerven gekostet:
Sie erstellt gerade eine Webseite für eine Firma auf Basis von WordPress [WP] unter Einschluss des Pinnacle Themes. Ich selbst bin ehrlich gesagt kein Freund solcher viel zu komplexen und deshalb wenig performanten Themes. Aber ich hatte da nichts zu entscheiden.

Jedenfalls stand am gestrigen Morgen der Transfer der WP-Installation von einer gehosteten Testdomäne bei "1&1" zur endgültigen Zieldomäne des Auftraggebers an. Letztere wird auch gehostet - allerdings beim Provider "Strato". Unter "Hosting" verstehe ich dabei klassisches Web-Hosting: Man erhält auf einem Server einen per "chroot" abgesicherten Web-Space. Man teilt sich aber die Ressourcen des Webservers mit anderen Usern und hat keinerlei Kontrolle über die Serverkonfiguration selbst.

Schritte für einen WP-Umzug zu einer anderen Domäne und auf einen anderen Webserver

Zu bewältigen war also ein WordPress-Umzug zwischen zwei Domänen bei zwei klassischen deutschen Web-Hosting-Providern. Beide Provider nutzen Apache- und MySQL-Server. Man stellt sich den Umzugsprozess deshalb als gut beherrschbar vor. Als notwendige Teilschritte fallen einem sofort die folgenden ein:

  • Datenbank-Export vom Datenbankserver des alten Hosters (hier 1&1) auf ein eigenes Linux-System; den Export kann man mit PhpMyAdmin vornehmen. Wir erhalten dadurch ein Text-File mit den erforderlichen SQL-Statements für einen späteren Import und natürlich mit den Inhalten der Datenbankfelder selbst.
  • Änderung der Domain-Adresse [URL] und ggf. auch absoluter Server-Pfade in der SQL-Datei. Diesen Schritt kann man z.B. mittels eines schrittweisen "Search und Replace" unter "kate" oder einem anderen Linux-Editor vornehmen.
  • Datenbankimport des modifizierten SQL-Files in die Zieldatenbank eines MySQL-Servers beim neuen Provider; wieder mit PhpMyAdmin.
  • Kopieren der WordPress-Verzeichnisse und WP-Dateien per SFTP vom alten Web-Server (Webspace) auf einen Linux-Desktop und von dort weiter auf den Ziel-Webserver (Strato). Hierzu verwendet man ein FTP-Tool wie etwa Filezilla.
  • Änderung der Einträge in der "wp-config.php" (u.a. der Datenbank Access Daten) und Transfer der modifizierten Datei auf den Zielserver.

Leider ist ein WP-Umzug manchmal nicht ganz so einfach. Gestern stolperte ich in 2 typische Fallen. Die zweite davon war mir schon mal begegnet; ich hatte sie aber schlicht vergessen.

Problem 1: Erfordert der Zielserver bestimmte Gruppenrechte für den Zugriff auf Dateien?

Der Standard-Rechtekamm auf Web-Servern, die per FTP erreichbar sind, kann sich durchaus unterscheiden. Und manchmal sind gezielte Rechtesetzungen erforderlich, damit eine Web-Anwendung anstandslos läuft.

Interessant ist in diesem Zusammenhang u.a. eine Unterscheidung des Owners der zugänglichen Web-Verzeichnisse/Dateien von demjenigen User unter dem die Apache-Prozesse laufen. Von Bedeutung ist etwa die Gruppenzugehörigkeit des letzteren Users. Ich selbst lege eigene Apache2-Server oft so an, dass die Apache-Prozesse unter einem User laufen, der Mitglied einer Standard-Gruppe ist, welche wiederum den Webserver-Verzeichnissen zugeordnet wird. Für neu anzulegende Verzeichnisse/Dateien unterhalb des chroot-Pfades werden die Rechte dann über SGID und/oder ACLs gesteuert.

Nun gibt es aber leider keine allgemeingültigen Regeln, was die erforderlichen Zugriffsrechte auf verschiedene Dateitypen anbelangt, damit komplexe Web-Anwendungen funktionstüchtig laufen.

So kann man etwa die PHP-Ausführung sowohl in FastCGI- als Apache-Modul-Installationen so einrichten, dass der Apache-Prozess dabei die Rechte des PHP-File-Owners annimmt und mit diesen Rechten auf weiteren Dateien operiert ("suexec"-Varianten). Anders mag es aber aussehen, wenn ein Webserver oder andere Prozesse unabhängig von PHP direkt auf Dateien zugreifen müssen. Beispiel: PHP erstellt auf Anforderung eines Browsers auf dem Server eine HTML-Datei; diese lädt im Browser JS-Programme nach und letztere wiederum fordern Bilder zur Darstellung im Browser an. Nehmen wir an, der Apache-Prozess gehöre zu der Gruppe von Nutzern, die auf die hochgeladenen Dateien des Webservers zugreifen darf. Dann muss die Gruppe ggf. zwar nicht unbedingt ein "read"-Recht haben, um PHP-Dateien ausführen zu können, wenn das über suexec-Mechanismen geregelt wird. Aber wenn ein nachgelagertes Javascript-Programm eine Bilddatei lesen muss, gibt es womöglich doch ein Problem, falls diese Bild-Datei auf dem Webserver nicht mit dem erforderlichen Gruppenrecht versehen wurde.

Warum werden Rechte im Kontext eines WP-Umzugs u.U. wichtig?
Installiert man WP, so analysiert WP selbst, unter welchen Rechten (bzw. welcher UID) ein PHP-Programm läuft - unter denen des Apache-Prozesses oder denen des File-Owners? Daran richtet sich dann die Installation aus. Was aber, wenn das Analyseergebnis auf einer Test-Umgebung nicht zur Ziel-Umgebung des späteren Produktivservers passt?

Genau eine solche Situation trat gestern in unserem Fall auf und führte gleich zwei Teil-Probleme mit sich.

Problem 1.1: Kann die ".htaccess"-Datei von relevanten Prozessen gelesen werden?
Ich beschreibe mal, was mir im Zuge unseres geplanten Umzugs passierte:
Auf dem Zielsystem bei Strato schien die von WP ursprünglich auf dem 1&1-Server angelegte und von uns kopierte ".htaccess"-Datei nicht zu wirken. Die ".htaccess" ist aber für den gesamten WordPress-Prozess entscheidend: Sie aktiviert die "Rewrite Engine" des Apache-Servers und verweist alle URL-Anfragen zu nicht existierenden Dateien und Verzeichnissen zur Auflösung an die zentrale "index.php" der WP-Installation.

Beim Aufruf bestimmter Dateien im Browser kam auf unserem Zielsystem laufend die Meldung, dass ich auf diese Dateien "nicht zugreifen dürfe". Das geschah etwa, wenn ich den Zugriff auf HTML-Dateien versuchte. Löschte ich dagegen die ".htaccess" auf dem Zielserver und transferierte eine eigens neu angelegte HTML-Datei in das Domain-Verzeichnis auf dem Zielserver, so war alles OK. Die HTML-Datei wurde auf Anforderung anstandslos im Browser dargestellt.

Zunächst dachte ich an einen seltsamen Fehler in der ".htaccess"-Datei. Der Grund war aber ein anderer:

Mein FTP-Programm hatte die auf dem 1&1-Server geltenden Berechtigungen 1:1 auf mein lokales Linux-System abgebildet und diese Berechtigungen danach auch auf den Zielserver transportiert. (Die meisten FTP-Programme haben heute Parameter, die das Erzeugung des Rechtekamms auf dem Zielsystem steuern, soweit dieses die Rechtevergabe gem. eigener Regeln/ACLs überhaupt zulässt). Der Rechtekamm für die ".htaccess"-Datei war auf dem 1&1-Server ursprünglich aber "604" gewesen.
Auf dem Zielsystem bei Strato hing die Lese- (und auch die Schreib-) Berechtigung bestimmter Webserver-Prozesse dagegen offenbar an den Gruppen-Rechten! Mindestens mal für das Auslesen der ".htaccess"-Datei!

[In diesem Zusammenhang ist es übrigens bemerkenswert, dass bei Strato schon das Anlegen eines Dateischutzes per ".htaccess" irgendwelche besonderen Programme zu involvieren scheint ...]

Bei 1&1 hingegen musste die Gruppe hingegen keine Zugriffsrechte auf die ".htaccess"-Datei haben; dort genügte vielmehr das Leserecht von "Others". Offenbar weichen die Server-Installationen der beiden Provider für Web-Hosting deutlich voneinander ab!

Lesson learned:

Das Leserecht für die Gruppe ist auf manchen Serverinstallationen zwingend erforderlich, damit eine ".htaccess"-Datei ordnungsgemäß ausgewertet werden kann.

Ich kam in unserem Fall bei Strato zufällig drauf, als ich das ".htaccess"-File auf meinem Desktop händisch neu anlegte, mit wachsendem Inhalt versah und immer wieder auf den Zielserver hochlud. Das führte erst zur Vergabe von Standardrechten für den Gruppenzugriff auf meinem Linux-Desktop (644); diese Rechte wurden nach dem SFTP-Transfer auch auf dem Server wirksam. Mit positiven Folgen! Die ".htaccess" griff nun endlich.

Problem 1.2: Können auch andere Dateien ohne Gruppenrechte gelesen werden?
Tja, meine einleitenden Sätze deuteten ja schon an, dass die Politik von Providern hier nicht zwingend einheitlich aussehen muss. Der ursprüngliche, von 1&1 vielfach kopierte Rechtekamm "604" erwies sich auf dem Zielserver jedenfalls auch bzgl. anderer Dateien als der ".htaccess" als problematisch: U.a. konnten vorhandene Bild- und Medien-Dateien nicht ausgelesen werden.

Das erklärt sich etwa wie folgt: Laufen bestimmte Server-Prozesse über User, die Mitglied der Gruppe, aber nicht der Owner der zu verarbeitenden Datei sind, so können diese Prozesse (ohne weitere besondere Massnahmen wie suexec) im Falle eines Rechtekamms "604" die Datei trotz des Leserechts von "Others" in keinem Fall lesen! [Off Topic: Das ist unter Linux nützlich, um bestimmte Gruppen von Usern definitiv vom Zugang zu bestimmten Dateien auszusperren, zu denen aber alle anderen Nutzer ungehinderten Lese-Zugang haben sollen.]

Selbst als die ".htaccess" wieder griff, kam es deshalb nach unserem WP-Umzug zu weiteren Fehlern - nämlich immer dann, wenn der Webserver Dateien lesen und bereitstellen sollte, für die die Gruppenrechte nicht hinreichend waren.

Ein pauschales Setzen der "644"-Berechtigung für relevante Zieldateien (bzw. "755" für Verzeichnisse) war per FTP-Programm dann aber schnell durchgeführt. Danach konnten auf dem Zielserver alle Webseiten angesprochen werden.

Wichtiger Hinweis: Die wp-config.php sollte natürlich nie für "Others" lesbar sein - also für diese Datei bitte einen Rechtekamm "600" oder "640" wählen!

Problem 1.3: Laufen PHP-Dateien evtl. auch ohne Gruppenrechte?
Der obige Befund deutet zunächst mal an, dass der Apache-Web-Prozess unter einem User läuft, der Mitglied der Gruppe ist, die beim Hoster Strato den Webspace-Dateien zugeordnet werden. Weitere Tests ergaben aber, dass der Webserver sehr wohl auf PHP-Dateien zugreifen und die ohne Gruppenrechte ausführen konnte. (Strato bietet die PHP-Ausführung im rahmen aktuellen Web-Hostings übrigens über eine FastCGI-Implementierung an.)

Ich zeige mal den Rechtekamm für verschiedene Dateien:

Man erkennt, dass die ".htaccess"-Datei nun das Gruppenrecht zum Lesen aufweist. Hingegen sind der Gruppe alle Zugriffsrechte auf die PHP-Dateien entzogen. Dennoch läuft WordPress inkl. Pinnacle Theme einwandfrei; auch andere, selbst angelegte PHP-Dateien lassen sich mit dem Rechtekamm "600" anstandslos ausführen. Probleme gab und gibt es jedoch bzgl. des Lesens von Dateien mit Rechten wie der "readme.html" auf dem Bild; der Abruf dieser Datei über einen Browser führt zu einer Fehlermeldung

Forbidden
You don't have permission to access /readme.html on this server.

Also sind - wie oben angedeutet - spezielle "suexec"-Mechanismen für die Ausführung von PHP-Dateien mit den Rechten des Owners zu vermuten. Das lässt sich mit bestimmten Apache-Modulen bewerkstelligen.

Bei 1&1 sah ein funktionierender Kamm dagegen wie folgt aus:

Hier erfordert das Lesen und Bereitstellen von anderen als PHP-Dateien offenbar das "read"-Recht von "others". Das mag nun jeder selbst bewerten.

Fazit:

Auf unserem gehosteten Strato-Webspace benötigt man für die Ausführung und das Lesen von PHP-Dateien nur einen Rechtekamm der Form "600". Der Abruf und die Bereitstellung von anderen Dateien durch den Webserver verlangen aber mindestens einen Kamm der Form "640".

Was bedeutet das für Leute, die eine WP-Installation nach einem Umzug besonders härten wollen und sich nicht mit pauschalen Rechte-Kämmen zufrieden geben wollen? Leider muss man sich auf dem gehosteten Web-Space mancher Provider - wie etwa Strato - selbst um eine unterschiedliche Rechtevergabe für PHP-Dateien im Gegensatz zu anderen Dateien kümmern. (Wohl dem, der dafür einen SSH-Zugang hat und zur Abänderung der Rechte mit Linux-Shell-Kommandos arbeiten kann!)

Lesson learned:

Web-Server-Konfigurationen sehen bei verschiedenen Web-Hosting-Providern unterschiedlich aus. Man sollte schon vor einem WP-Umzug von einem Provider zu einem anderen genauer studieren, welche Zugriffsrechte für eine volle Funktionalität erforderlich sind. Dabei sind vor allem Gruppenrechte interessant. PHP-Dateien können ggf. allein mit den Rechten des File-Owners ausgeführt werden. Der Zugriff auf andere Dateien kann dagegen aber zwingend Gruppenrechte erfordern. Ggf. müssen die Datei-Rechte beim Umzug also an die Erfordernisse auf dem Zielserver angepasst werden. Das Leserecht für die Gruppe kann speziell für den Zugriff auf die ".htaccess"-Datei relevant sein.

Nach dem Umzug und einer Vergabe der minimal erforderlichen Rechtekämme für die unterschiedlichen Dateitypen in den WP-Verzeichnissen sollte man übrigens unbedingt auch mal testen, ob sich WP selbst und auch alle Plugins noch über entsprechende WP-Funktionalitäten upgraden lassen!


Problem 2: Serialisierte Information in den Datenbanktabellen verträgt eine Änderung der Länge des Domain-Strings nicht!

Nach der Bereinigung der Rechte-Probleme funktionierte in unserem Fall zwar das Apache-Rewriting wieder - und auch alle erstellten WP-Seiten wurden im Browser wieder samt eingebundenen Bilddateien angezeigt. Aber leider nicht im gewünschten Layout!

Sämtliche im Usprungssystem vorgenommenen Theme-Einstellungen und eigene CSS-Einstellungen (und das waren viele!) funktionierten nicht mehr! Es schien zunächst so, als ob sämtliche Theme- und CSS-Einstellungen beim Umzug des WP-Blogs verloren gegangen wären! Es gab also noch ein Problem, das zu lösen war.

Es ist ein wenig unübersichtlich, wie WP-Themes modifizierte CSS-Anweisungen behandeln und wo sie sie hinterlegen. Ein Teil fließt in reguläre CSS-Dateien ein. Ein anderer Teil aber - wie z.B. CSS-Einstellungen durch den User - werden (je nach Theme) auch in Datenbanktabellen hinterlegt. Das ist etwa beim Pinnacle-Theme der Fall. Ich begab mich bei der Analyse des Problems also zunächst einmal in die Niederungen der WP-Datenbank-Einträge.

Betrachtet man das exportierte SQL-File einer WP/Pinnacle-Installation und sucht dort ein wenig, so findet man tatsächlich die spezifischen CSS-Vorgaben, die man als User/Admin vorgenommen hat, als Datenbankeintrag der "Options"-Tabelle wieder. Warum also zogen z.B. diese Anweisungen auf dem Zielsystem nicht?

Beim genaueren Hinsehen entdeckt man weiter, dass der betreffende String-Eintrag wie auch viele andere Feldeinträge in den WP-Tabellen die Form sog. serialisierter Arrays haben. Unter der Serialisierung eines Arrays einer Programmmiersprache (hier eines PHP-Arrays) versteht man die Transformation der (PHP-) Array-Information (indizierte Elemente und deren Inhalte) in einen nach vorgegebenen Regeln codierten String (mit definierten Trennzeichen und Hinweisen zum Array-Aufbau). Im Rahmen von WP und WP-Themes erfolgt eine Array-Serialisierung i.d.R. durch die PHP-Funktion "serialize()". (Oder für die Deserialisierung später durch das Pendant "unserialize()").

Das Entscheidende dabei ist, dass die Länge der Sub-String-Information zu einem bestimmten Array-Element im serialisierten String über eine vorgestellte Zahl des entsprechenden String-Abschnitts kodiert wird. Bsp: s:5"Ralph". Gemeint ist hier, dass die Information "Ralph" 5 Zeichen lang ist.

Siehe hierzu etwa https://stackoverflow.com/questions/8641889/how-to-use-php-serialize-and-unserialize oder die PHP-Doku!

Array-Serialisierung vereinfacht die persistente Hinterlegung komplex strukturierter Information in Datenbank-Feldern (z.T. zu Lasten der Performance). Leider machen sich viele der Entwickler dabei das Leben leicht: Unter WP bzw. WP-Themes taucht in etlichen Datenbankeinträgen innerhalb serialisierter Arrays leider auch die URL für die Blog-Domäne auf.

Ändert man nun, unbedarft wie ich, pauschal die Domänen-URL im SQL-File auf die neue Zieldomänen-URL durch "Search und Replace"-Funktionalität ab, so wird das nicht in allen Fällen ohne Nebenwirkungen bleiben. In allen Fällen, in denen sich die Domänen-Bezeichnung innerhalb eines Serialisierungs-Strings wiederfindet, wird es i.d.R. ein Problem geben:

Die Länge des URL-Strings zu einer Testdomäne wird ja nur sehr selten mit der Länge der URL der Zieldomäne übereinstimmen! Versuchen PHP-Programme von WP oder WP-Themes nach dem Umzug, die serialisierte Information wieder in PHP-Arrays umzuwandeln, geht das natürlich schief - mit katastrophalen Folgen. Da Grenzen überschritten werden, lässt sich die Information nicht korrekt aus dem String extrahieren. Dies führt dann u.U. dazu, dass unserialize() leere oder fehlerhafte Strings in den aufzubauenden Arrays zurückliefert. Ein Ergebnis: Wichtige Formatierungsinformationen von Themes stehen gar nicht oder nur fehlerhaft zur Verfügung.

Lesson learned:

Man muss die Ersetzung von Domänen-Strings in der SQL-Datei mit Bedacht vornehmen - und eben, wo nötig, auch die vorgeschaltete Längeninformation in Strings mit serialisierter Information abändern!

Nutze für den Datenbank-Export ein WP-Plugin!

Die Modifikation der Domän-URL mit gleichzeitiger Anpassung der Serialisierungs-Information kann man zwar händisch oder unter Linux auch mit Hilfe von kleinen Scripts (awk, sed mit Regex) durchführen. Aber netterweise gibt es auch ein WordPress-Plugin, das einem zur Seite steht - nämlich "WP Migrate DB" (von Delicious Brains):

Das Plugin erzeugt einem bei Bedarf ein Datenbank-Export-File, das die notwendigen Korrekturen der Serialisierungsstrings bereits beinhaltet!

Als Input muss man dem Plugin die zu ändernde Domänen-URL sowie den absoluten (!) Serverpfad des Blogs auf dem Ziel-Webserver mitgeben. Ja, auch letztere Information taucht tatsächlich, je nach WP-Theme, in einigen wenigen Datenbankeinträgen auf! Wie kommt man nun an die Info zum absoluten Serverpath? Am einfachsten über ein PHP-File mit dem Inhalt:

<?php
  echo getcwd();
?>

Das transferiert man per SFTP in sein Domän-Verzeichnis auf den Web-Server, ruft es anschließend im Browser auf und kopiert dann die ausgegebene Info in den Plugin-Dialog. Das SQL-Exportfile das Plugins (im UTF-8-Format) kann man schließlich wie gewohnt per PhpMyAdmin in die MySQL-Datenbank auf dem Zielserver laden.

Funktionierte bei mir anstandslos! Danach waren standen sämtliche Theme-Einstellungen wieder zur Verfügung und auch die privaten CSS-Anpassungen meiner Frau wurden korrekt gelesen und im Layout der Webseiten erwartungsgemäß umgesetzt.

Nebeneffekt: Wenigstens einmal konnte ich meine Frau mit Linux und ein wenig PHP-Kenntnissen glücklich machen!

Fasching, Webhosting bei 1&1 und mein Tränenbecken – I

1&1 war und ist einer der Platzhirsche in Deutschland, was Web-Hosting angeht. Durch den Zukauf von Strato durch den Mutterkonzern hat sich die Marktdominanz noch erhöht. Auch dieser Blog läuft im Rahmen eines Web-Hosting-Pakets bei 1&1. Das PC-Magazin hat diesen Provider als Hoster im Jahr 2016 ausgezeichnet. 1&1 wirbt selbst viel mit einem guten Kundenservice.

Da ist es doch schön, wenn man die Wirklichkeit, wie sie ein Endkunde erlebt, auch mal mit dem werbewirksamen Anspruch des Unternehmens vergleichen kann. Hierzu bot sich mir in den letzten Tagen eine praxisnahe Gelegenheit - im Auftrag einer Kundin "K" von 1&1, die wir in Web-Angelegenheiten immer wieder betreuen.

Die Geschichte ist einfach zu gut, um sie für sich zu behalten. Sie hinterließ bei mir trotz des munteren Faschingstreibens in den letzten Tagen sehr gemischte Gefühle. Immer wieder fühlte ich mich in eine Art Tragik-Komödie versetzt - auch wenn 1&1 nun endlich eine Lösung für besagte Kundin gefunden zu haben scheint. Die Fastenzeit hat offenbar auch ihr Gutes ...

Ich konzentriere mich in diesem Erfahrungsbericht zunächst auf das erlebte Kernproblem meiner Kundin - nämlich die unzureichende Webseiten-Performance - und faktische Ergebnisse von 8 Eskalationsversuchen meiner Wenigkeit.

Das Problem

Kundin "K" hat im letzten Herbst ihre Webseite von uns auf WordPress samt Kadence/Pinnacle-Theme umstellen lassen. Wir haben diese PHP-basierte Technologie verschiedentlich für Kunden im Einsatz. U.a. bei einem weiteren Webhosting-Kunden von 1&1, aber nicht nur dort. Getestet haben wir die erreichbare Performance ursprünglich auf eigenen Webservern unter Stressbedingungen, unter einem 12 Jahre alten Hosting-Vertrag bei Strato und unserem eigenen, ähnlich alten Vertrag bei 1&1. Bislang alles problemfrei.

Nach der Installation lief die Web-Site der Kundin zunächst auch wie erwartet. Antwortzeiten zum Abnahmezeitpunkt zwischen 1.2 und 3 Sek pro Seite - je nach Tageszeit.

Seit dem Jahreswechsel stellte besagte Kundin - nach Beschwerden ihrer eigenen Kundenklientel - jedoch fest, dass die Performance ihrer Site seit Januar immer schlechter wurde und zeitweise "unter aller Sau" war (Zitat; ein später konsultierter 1&1 Berater fand diesen Ausdruck durchaus angemessen).

Punktuelle Zugriffe Mitte/Ende Januar und Mitte Februar aus dem Ausland bestätigten den subjektiven Befund der Kundin. Auf Anforderung der Kundin haben wir das letzte Woche dann genauer überprüft. Während typischer Hauptlastzeiten mussten wir tatsächlich zeitweise Antwortzeiten im deutschen Internet zwischen 10 Sek und 30 Sek pro Webseite feststellen.

Eigene Tests unter einer 1&1-Testdomäne - um Faktoren bessere Antwortzeiten

Wir haben dann selbstverständlich die Site der Kundin für Tests mit identischen PHP-Programmen und (bis auf Links) identische Datenbanktabellen in einen anderen alten 1&1-(!)-Vertrag und auf damit assoziierte Web- und Datenbankserver bei 1&1 gespiegelt. Die Tests ergaben völlig andere Ergebnissen und eine um Faktoren bessere Performance!

Die Kundin hat dieses Ergebnis leider mit großer Verbitterung zur Kenntnis genommen. Sie wollte ihren Vertrag mit 1&1 daraufhin umgehend kündigen und den Anbieter wechseln. Was wegen Mindestvertragslaufzeiten aber zu keiner kurzfristigen Lösung geführt hätte.

Wir selbst vermuteten zunächst eine zu hohe Last auf den 1&1-Datenbankservern. Weitere Tests, die wir im Laufe der Zeit systematisch anstellten, haben diese These jedoch klar widerlegt.

Blieb eigentlich nur eine Überlastung der Webserver oder eine massive Benachteiligung der Kundin im Kampf um die Hosting-Ressourcen bei 1&1 als Erklärungsansatz übrig ...

Dazu muss man wissen, dass die Kundin seit 14 Jahren bei 1&1 knapp 12 Euro/Monat für 3 Domänen ohne SSL-Zertifikat abdrückt und sich durchaus als Stammkundin fühlt. In ihrer Jugend war das noch was wert.

Kontakt zum 24/7-Service von 1&1

Ich wandte mich letzte Woche dann im Auftrag unserer Kundin an 1&1 und hatte seitdem 8 mal Kontakt (zur Hotline und Hosting-Beratern) - mit steigender Eskalationstendenz meinerseits und wachsender Hilflosigkeit der Ansprechpartner (bis auf den letzten). Alle Ansprechpartner konzidierten immerhin ein größeres Problem - der eine oder andere schien geradezu geschockt von den schlechten Antwortzeiten zu sein; erst recht, wenn er dann als Kontrast die Zeiten der gleichen Anwendung auf unserer ebenfalls bei 1&1 gehosteten Testdomäne sah.

Besonders berührt hat das einen 1&1-Mitarbeiter, den wir am Faschingsdienstag um ca 23:00 Uhr konsultierten. Zu diesem Zeitpunkt hatten wir zähneknirschend und ohne jeden Erfolg bereits alle vorhergehenden Ratschläge von 1&1-Mitarbeitern (inkl. einer Vertragsumstellung) befolgt - ohne Erfolg. Der Support-Mitarbeiter hätte angesichts der Fakten gerne die "Techniker" involviert. Leider war trotz 24/7-Service bei der Technik um 23:00 Uhr niemand mehr erreichbar. Alaaf ...

Meine Frau vergnügte sich zu diesem Zeitpunkt zu Recht vor dem TV und auf Facebook. Ich musste mir deshalb mein Tränenbecken aus dem Glasschrank selber holen. In weiser Voraussicht ließ ich es auf meinem Schreibtisch stehen.

1&1 empfiehlt der Kundin stereotyp eine Vertragsumstellung - aber dadurch wird zunächst nichts besser

Als Ursache des Dramas wurde von den ersten 5 Ansprechpartnern vor dem 28.02. ein zu alter Vertrag (mit Speicher- und Performance-Einschränkungen) vermutet bzw. unterstellt. Das ist für das erste Gespräch am 23.02. mit einem 1&1-Vertretern eine außerordentlich freundliche Darstellung des Gesprächsverlaufs! Hier half auch mein Freund - das Tränenbecken - nicht mehr; vielmehr musste im Anschluss der "porcelain god" selbst angerufen werden, um mich wieder in Faschingslaune zu versetzen.

Alle nachfolgenden Berater waren dagegen sehr freundlich und ausgesprochen service-minded. Auch wenn das bis heute Mittag keine Wendung zum Besseren zeitigte, möchte ich bei dieser Gelegenheit doch die Ruhe und Besonnenheit der meisten Ansprechpartner (alles Männer) ausdrücklich loben! Die hatten es angesichts der Fakten ja nun wirklich nicht leicht und stießen regelmäßig an ihre Grenzen.

Geredet haben die Mitarbeiter aus dem Support und auch die Hosting-Berater dann viel über Hauptspeicheranforderungen moderner Web-Anwendungen, tolle SSDs in den aktuellen Datenbankservern und die schlimmen Begrenzungen alter 1&1-Verträge. Ich will das hier gar nicht weiter kommentieren. Ich kenne den relativ geringen Hauptspeicherbedarf der PHP-Applikation WordPress mit diversen Plaugins ganz gut; und der Nutzen von SSDs auf einem gut gepufferten und parametrierten MySQL-Datenbankserver entfaltet sich auch erst unter ganz bestimmten Anforderungen. Ich arbeite da zeitweise mit ganz anderen Kalibern an PHP-Anwendungen.

Die technischen Limits zur Ausführung von PHP-Anwendungen, die für den alten Vertrag der Kundin angeblich angewendet würden, konnte aber keiner der Berater zitieren oder belegen. Natürlich konnte auch nicht bestätigt werden, dass die aktuelle Anwendung die gesetzten Limits überschreiten würde. Ein Berater gab auf Rückfrage vielmehr zu, dass er nicht mal Zugriff auf die alten Vertragskonditionen hätte (interne Serverstörung!).

Vielleicht wäre ja aber ein konfigurierbarer Cloud-Server für unsere Kundin das Richtige?? Na, super! Geringfügige Mehrkosten ... Ach so ... Und wer kümmert sich dann um den Cloudserver und dessen Sicherheit? Und was kostet das dann? ..."Oh - ja, Ihre Kosten hatte ich gerade nicht auf dem Radar ..." Tja... und bevor ich es angesichts der Vielfalt aktueller 1&1-Angebote vergesse : Wieso genau lief und läuft dieselbe Applikation gehostet unter einem anderen aber ebenso alten Vertrag nochmal so viel besser? Weil ich drei Euronen pro Monat mehr zahle, die allein von den 4,99 Euro für ein SSL-Zertifikat aufgefressen werden?

Jeder der 1&1-Berater wurde von uns über die unterschiedlichen Laufzeitergebnisse zwischen der Domäne der Kundin und einer Testdomäne unter einem anderen ebenso alten Vertrag informiert. Die letzten 4 Berater wurden ferner über die Ergebnisse von Cross-Tests zwischen den verschiedenen Vertragsdomänen und und über Datenbanktests unterrichtet, die den Datenbankserver der Kundin als Ursache ausschlossen. Wir haben die 1&1-Berater ferner darauf hingewiesen, dass in Perioden geringer Last (Faschingssonntag, morgens) auch Antwortzeiten < 2 Sek angeboten wurden - und das die festgestellten schlechten Antwortzeiten offenbar an Zeiten hoher Grundlast für die Webserver gekoppelt waren. Und wir stellten immer wieder die Frage, ob es denn nicht sein könne, dass irgendwo bei 1&1 eine zu hohe Last vorläge und ob denn nicht ein Umzug auf einen anderen ihrer (Web-) Server etwas bringen könne ... ?

Mein Tränenbecken füllte sich dann interessanterweise auf magische Weise regelmäßig von selbst, wann immer ich das Stichwort "Stammkundin seit 14 Jahren" in Gesprächen mit dem 1&1-Support anzubringen versuchte. Besonders schnell geschah das, als ein 1&1-Gesprächspartner alte 1&1-Webhosting-Verträge mit alten Telekom-Verträgen verglich. Da würde man für schlechtere Leistung ja auch mehr zahlen als bei einem neuen Vertrag! Gott sei Dank war ein Blumentopf in der Nähe, als mein Freund - das Becken - überquoll. Ach, Deutschland, mein geliebte Servicewüste! Es ist Fasching und ich weiß - ich bin wieder daheim.

Kommentar der 1&1-Technik

Auch die 1&1-"Technik" ( 2nd-level Support ???) wurde dann mal eingeschaltet; das lapidare Resultat entsprechender Anstrengungen kam dann am Faschings-Sonntag per Mail:

Als mir diese Mail von "K" übermittelt wurde, dachte ich spontan an das Land der "alternativen Fakten". Wie schnell das doch über den großen Teich schwappt.... Meine Gattin muss wohl mein Gesicht gesehen haben - sie reichte mir das Tränenbecken unaufgefordert. Die vorhergehenden Spekulationen um Verträge und die prägnante, wie tiefgehenden Problemanalyse durch die 1&1-Technik taten das ihre ...

Umstellung des Vertrags der Kundin

Nach etlichem Hin und Her (dazu mehr in einem anderen Blog-Beitrag) wurde der Vertrag der Kundin dann tatsächlich (bei Mehrkosten) auf ein aktuelles Paket "Unlimited Plus" umgestellt; dies geschah am 28.02. nach einem Sponsoringversuch durch eine geringfügige Gutschrift für bislang durch "K" in 2 Monaten erduldeten Qualen.

Zu den Erlebnissen während der praktischen Vertragsumstellung im nächsten Beitrag mehr; ich habe mir erneut mehrfach die Auffangschale unter tropfende Augen halten lassen. Eigentlich wollte sich unsere Kundin auf eine Vertragsänderung gar nicht mehr einlassen. Wir haben sie mühsam dazu motivieren müssen. "Alternative Chancen für die Schaffung neuer alternativer Fakten" würden heutzutage ja selbst Präsidenten eingeräumt - und den deutschen Verbraucherschutz könne sie ja immer noch einschalten.

Das traurige Ergebnis der Tarifumstellung war leider:
Von einer Verbesserung konnte weder am 28.02. noch am 01.03. die Rede sein. Am 01.03. wurde auf Anraten eines 1&1-Beraters dan zusätzlich die Datenbank auf einen neuen Datenbankserver des aktualisierten Vertrages verlagert. Effekt: Die Antwortzeiten wurden noch schlechter! Zufall oder System? Oder Faschings-Kater der 1&1-Server?

Das Tränenbecken musste erneut mehrfach ausgekippt werden. Erst recht nach dem darauf folgenden Telefonat mit "K".

Performance am heutigen Vormittag (02.03.)

Ich stelle nachfolgend den Stand der Performance am heutigen Vormittag in mehreren Tabellen dar. Diese Zeitreihen verdeutlichen das grundsätzliche Problem, das die Kundin seit Januar hatte, sehr gut; auch wenn hier nur die Spitze des Eisberges schlaglichtartig sichtbar wird.

Die obere Zeile in den nachfolgenden Tabellen entspricht jeweils der Web-Domäne aus dem aktuellen Vertrag "Unlimited Plus" der Kundin [K], die unter einer identisch konfigurierten "Testdomaine" [T] unter einem alten "Business 5.0"-Vertrag.

In beiden Fällen lief zunächst PHP 5.6 und dann (nach einer gezielten Umstellung) PHP 7 auf den gehosteten Web-Servern. Um die Dinge besser vergleichbar zu machen, erfolgte aus der Testdomäne heraus ein Zugriff auf einen Datenbankserver, der dem aktuellen Vertrag der Kundin zugeordnet ist.

Aufgerufen wurde dabei immer dieselben 3 Seiten in 2 Zyklen - abwechselnd für K und T.
Alle Werte in Sekunden !

Zeit 02.03.2017, 11:00 Uhr

K 7,0 3,2 4,4 7,6 3,0 2,7
T 1,1 0,8 0,6 0,9 0,6 0,5

Zeit 02.03.2017, 11:10 Uhr

K 5,9 4,5 6,3 5,9 11,0 6,3
T 0,9 1,9 2,1 2,0 1,1 0,6

Zeit 02.03.2017, 11:14 Uhr

K 11,3 11,3 4,8 7,6 8,9 10,5
T 1,6 1,0 0,7 0,7 0,9 1,3

Zeit 02.03.2017, 11:15 Uhr

K 5,3 9,3 12,8 11,8 8,4 5,4
T 4,3 0,9 1,1 1,0 1,0 1,2

Zeit 02.03.2017, 11:20 Uhr

K 16,0 5,8 9,4 10,2 13,6 14,6
T 0,9 0,9 0,6 0,9 0,8 0,7

Zeit 02.03.2017, 11:25 Uhr

K 15,0 15,5 23,5 21,3 21,4 12,3
T 1,6 1,7 1,0 0,8 0,5 5,6

Zeit 02.03.2017, 11:30 Uhr

K 6,5 8,0 6,6 10,0 8,0 12,1
T 1,5 0,7 2,1 0,9 0,8 0,6

Zeit 02.03.2017, 11:50 Uhr

K 8,5 8,1 7,6 7,8 5,4 5,6
T 0,6 1,2 0,9 0,7 0,6 0,8

Zeit 02.03.2017, 12:00 Uhr

K 15,2 13,3 16,6 11,4 9,2 15,2
T 0,6 1,2 1,2 0,9 0,8 1,0

Ein Kommentar ist eigentlich überflüssig. Antwortzeiten zwischen 6 und 23 Sekunden pro Webseite sind aus Kundensicht unakzeptabel. Erst recht, wenn man zu einer Vertragsumstellung mit Mehrkosten geradezu genötigt wurde.

Und auch "K" kam sich angesichts der Daten natürlich veralbert vor und fand das einen Tag nach Aschermittwoch ziemlich unangemessen. Ich habe ihr angeboten, ihr zeitweise meine Tränenschale auszuleihen.

Fastenzeit und Licht am Ende des Tunnels

Gestern - am Aschermittwoch - gegen Mittag habe ich dann nochmal bei 1&1 angerufen. Der Mitarbeiter der Hotline verstand das Problem sofort und verglich die 20 Sekunden Antwortzeit auch brav mit der entsprechenden Zeit unserer Testdomäne bei 1&1. Dann gab es ein paar (sehr intelligente) Fragen zur Querverbindung auf die Datenbank der Kundin. Nebenbei studierte er die Kommentare seiner Vorgänger - und bat mich irgendwann, ihm Kommentare dazu zu ersparen. Dann fiel das Wort "Überlast". Er kam dann mit einem Lösungsvorschlag, für den wir ihm aber 24 Stunden einräumen müssten. Es gab auch eine wenig transparente Bezeichnung des kostenfreien Lösungsansatzes - irgendwas mit "...-Flat" - im Effekt sollte das zu einer "echten" Verschiebung auf andere Server führen. Ach ne .... Der vorhergehende Vertragswechsel hatte einen solchen grundlegenden Wechsel dann wohl nicht bewirkt??? ... Hm, und komischerweise sei diese Option bei dem Test-Domänen-Vertrag gar nicht aktiviert ...

Es ist Aschermittwoch - und auch ohne die Berichte aus Passau gesehen zu haben, beginne ich zu beten ....

Erlösung

Heute zw. 12.00 und 13:00 Uhr scheint 1&1 dann gerochen zu haben, dass ich an diesem Blog-Artikel schrieb. Jedenfalls flog ich plötzlich aus der FTP-Verbindung zum 1&1-Webspace unserer Kundin raus und kam auch erst wieder rein, nachdem ich eine dynamische IP-Adressbestimmung des 1&1-FTP-Servers in unserer Firewall zuließ. Ein Hinweis auf eine substanzielle Änderung? Erhörung meiner Gebete vom Vortag? Also: neuer Test nach dem obigen Muster. Und plötzlich erhalten wir bereits den ganzen Nachmittag geradezu traumhafte Antwortzeiten. Aktueller Stand:

Zeit 02.03.2017, 17:15 Uhr

K 0,4 0,6 0,6 0,6 0,8 0,4
T 1,0 0,7 1,1 0,6 0,6 0,7

Ich bin jetzt so gerührt, dass ich wieder mein Tränenbecken bemühen muss. Mehr zu einer Bewertung des Vorgang aus ITSM-Sicht daher morgen.

WordPress Dashboard weiß und unbenutzbar

Ich habe einige weitere Blogs, um die ich mich leider viel zu selten kümmere. Als ich neulich einen dieser anderen Blogs als Administrator öffnen wollte, war das Dashboard komplett weiss und nicht bedienbar - nur die linke Menüleiste wurde angezeigt. Der HTML-Quelltext zur Seite zeigte ganz unten einen PHP-Fehler an:

Fatal error: Access to undeclared static property: WP_Screen::$this in blog/wp-admin/includes/screen.php on line 706

Ein Blick in die entsprechende Datei zeigt tatsächlich die wirklich seltsame und bemängelte Konstruktion (aus statischer Klassenreferenz mit $this), die zumindest mit PHP 5.4 nicht mehr kompatibel ist. (Nebenbei: Eine Redefinition und Nutzung von $this als statische Variable einer Klasse war schon vor PHP 5.4 falsch bis gefährlich. Dass PHP 5.3 umgekehrt die Verwendung von $this mit statischen Variablen in der Form $this::$var erlaubt, hat damit nichts zu tun. Na ja - auch WordPress-Entwickler machen wohl ab zu Fehler, bei denen man sich fragt, wie man überhaupt auf so ein Statement kommen konnte ... )

Bei meinem Web-Hosting-Provider hatte ich tatsächlich vor einiger Zeit tatsächlich die Nutzung von PHP 5.4 als Standard eingestellt. Meine WordPress-Version war zudem auch schon ein wenig alt - eine 3.3.x-Version. Im Internet findet man aber die Beschreibung eines unbrauchbaren Dashboards aber auch für 3.8 Upgrades. Dort war das Statement in der screen.php strukturell ähnlich verbockt:

Fatal error: Access to undeclared static property: self::$this in blog/wp-admin/includes/screen.php on line 706

Wir kommt man nun wieder zu einem benutzbaren WordPress?

Die eine Variante ist, alle WordPress Dateien auf dem Server manuell upzudaten. Dabei muss man aber einige Konfigurationsdateien unbedingt unangetastet lassen. Ferner läuft man Gefahr, dass auch ein Datenbank-Update erforderlich wird, das nach einem reinen Austausch der Dateien aber nicht unbedingt automatisch angestoßen wird. (Vor einem manuellen Update in jedem Fall Backups aller Dateien UND der Datenbank machen!)

Will man sich - wie ich - solchen Risiken nicht aussetzen, muss man das fehlerhafte PHP Statement selbst korrigieren. [Bestätigt darin haben mich zwei Forumsbeiträge, deren Links ich weiter unten angebe.] Also die Datei "wpadmin/includes/screen.php" per FTP vom Server herunterladen und in Zeile 706 (oder für welche Zeile der Fehler sonst gemeldet wurde) editieren und in den Statements

"WP_screen::$this->_help_sidebar"
bzw.
"self::$this->_help_sidebar"

die Kassenreferenz vor dem "$this" entfernen, so dass nur

$this->_help_sidebar

übrigbleibt. Unmittelbar nachfolgende Strichpunkte oder anderen Code unverändert lassen. Danach die Datei wieder auf den Server laden.

Im Anschluss wurde bei mir das Dashboard wieder nutzbar und ich konnte das Upgrade auf Version 4 wie gewohnt durchführen. Danach funktionierte alles wieder normal. Viel Spass weiterhin mit euren WordPress-Blogs!

Links zu dem WordPress-Fehler:
http://wordpress.stackexchange.com/questions/127427/how-to-fix-empty-dashboard-issue-in-wordpress
https://wordpress.org/support/topic/38-update-now-all-dashboard-pages-blank

Links zu $this, self:: und statischen Variablen in PHP:
http://de.wikibooks.org/wiki/Websiteentwicklung:_PHP:_Statische_Eigenschaften_und_Methoden
http://stackoverflow.com/questions/151969/when-to-use-self-vs-this
http://www.programmerinterview.com/index.php/php-questions/php-self-vs-this/
http://www.diffen.com/difference/self_%28PHP%29_vs_this_%28PHP%29
http://php.net/manual/de/language.oop5.static.php
und komplexer mit dynamischen Klassennamen:
http://stackoverflow.com/questions/675676/access-a-static-variable-by-varreference