URLs in der WordPress-Datenbank beim Domainumzug aktualisieren

URLs in der WordPress-Datenbank beim Domainumzug aktualisieren

Zuletzt überprüft: 14. Oktober 2026
22 Min. Lesezeit
Tutorial
Serverarchitektur

Der Umzug einer WordPress-Website von der Entwicklungsumgebung auf die Produktionsdomain, ein Markenwechsel oder die Einführung eines SSL-Zertifikats (Wechsel von HTTP auf HTTPS) gehören zum Alltag jedes Administrators und Entwicklers. Auf den ersten Blick wirkt die Aufgabe trivial: Datenbank als .sql-Datei exportieren, im Code-Editor “Suchen und Ersetzen” ausführen und die Datei wieder importieren. Oder schnell eine SQL-Abfrage in phpMyAdmin absetzen.

Auf einer produktiven WordPress-Datenbank endet genau das mit einem sofortigen Ausfall. Widgets in Footer und Seitenleisten verschwinden, Farb- und Typografie-Einstellungen des Themes werden zurückgesetzt, erweiterte Felder (ACF) liefern leere Werte, und die Konfiguration von E-Commerce-Plugins ist plötzlich leer.

Der Grund liegt in der Art, wie WordPress und Plugins komplexe Datenstrukturen in der relationalen Datenbank MySQL und MariaDB ablegen. Die WordPress-Dokumentation warnt ausdrücklich: Ein einfaches Suchen und Ersetzen über die gesamte Datenbank kann die Serialisierung beschädigen, weil manche Themes und Widgets eine Adresse zusammen mit ihrer Länge speichern (Migrating WordPress, developer.wordpress.org). Wer die PHP-Serialisierung versteht und die richtigen Werkzeuge beherrscht, allen voran die Kommandozeile WP-CLI, hat die Grundlage für eine sichere Verwaltung von WordPress-Websites.


#Was serialisierte Daten in der WordPress-Datenbank sind

Relationale SQL-Datenbanken sind für skalare Werte gebaut: Zahlen, kurze Zeichenketten, Datumswerte. WordPress muss aber oft eine komplexe, mehrdimensionale Struktur in einer einzigen Tabellenzeile speichern, zum Beispiel ein Array mit der Liste aktiver Widgets, ihrer Reihenfolge, zugeordneten Icons und Konfigurationsparametern.

Statt für jedes Plugin Dutzende normalisierte Zusatztabellen anzulegen, nutzt WordPress eine native PHP-Funktion: serialize().

// Beispiel: Konfigurations-Array eines Themes in PHP
$theme_settings = array(
    'site_name'    => 'Mein WordPress Shop',
    'logo_url'     => 'https://alte-domain.de/logo.png',
    'contact_mail' => '[email protected]'
);

// Ergebnis von serialize($theme_settings)
// Wird direkt in der Spalte option_value der Tabelle wp_options gespeichert:
a:3:{s:9:"site_name";s:19:"Mein WordPress Shop";s:8:"logo_url";s:31:"https://alte-domain.de/logo.png";s:12:"contact_mail";s:20:"[email protected]";}

#Wie man einen serialisierten String liest

Sehen wir uns den Teil mit der Logo-Adresse genauer an:

s:31:"https://alte-domain.de/logo.png";

Jedes Element im serialisierten PHP-Format hat eine feste Struktur:

  • s steht für den Datentyp: string (Zeichenkette).
  • 31 ist die deklarierte Länge der Zeichenkette (genaue Anzahl Bytes).
  • "https://alte-domain.de/logo.png" ist der eigentliche Wert in Anführungszeichen.

Der entscheidende Teil ist die Zahl 31. Beim Lesen aus der Datenbank ruft PHP die Funktion unserialize() auf. Der Parser sucht das schließende Anführungszeichen nicht blind, sondern zählt genau 31 Bytes ab der angegebenen Stelle ab.

#Warum SQL REPLACE serialisierte Daten beschädigt

Angenommen, die Website zieht auf eine neue, längere Domain um: https://neue-deutlich-laengere-firmendomain.de. Die neue Logo-Adresse https://neue-deutlich-laengere-firmendomain.de/logo.png ist 55 Zeichen lang.

Führen wir die klassische SQL-Abfrage aus:

-- KRITISCHER FEHLER: Diese Abfrage zerstört die Serialisierung!
UPDATE wp_options
SET option_value = REPLACE(option_value, 'https://alte-domain.de', 'https://neue-deutlich-laengere-firmendomain.de');

In der Datenbank entsteht dann diese Zeichenkette:

s:31:"https://neue-deutlich-laengere-firmendomain.de/logo.png";

Was passiert, wenn ein Besucher die Seite aufruft?

  1. WordPress holt die Zeile aus der Datenbank und übergibt sie an unserialize().
  2. Die Funktion liest den Kopf s:31 und erwartet genau 31 Zeichen.
  3. PHP schneidet die ersten 31 Zeichen der neuen Adresse ab und trifft mitten im String auf beliebige Buchstaben statt auf das erwartete schließende Anführungszeichen mit Semikolon.
  4. Der Parser meldet PHP Notice: unserialize(): Error at offset... und gibt false zurück.
  5. Theme oder Plugin erhalten statt des erwarteten Options-Arrays den Wert false.
  6. WordPress geht davon aus, dass keine Daten existieren, stellt die Standardeinstellungen des Themes wieder her oder entfernt die Widgets.

#Wo WordPress URLs in der Datenbank speichert

URLs liegen in einer WordPress-Installation nicht an einer Stelle. Sie sind über viele Systemtabellen und über Tabellen externer Module verteilt:

graph TD
    A["WordPress-Datenbank"] --> B["wp_options"]
    A --> C["wp_posts"]
    A --> D["wp_postmeta"]
    A --> E["wp_comments / wp_commentmeta"]
    A --> F["wp_usermeta"]
    A --> G["Plugin-Tabellen (WooCommerce, Formulare, SEO)"]

    B --> B1["siteurl und home (Hauptadressen)"]
    B --> B2["sidebars_widgets (serialisiert)"]
    B --> B3["theme_mods (serialisiert)"]

    C --> C1["post_content (Links, Bilder)"]
    C --> C2["post_excerpt"]
    C --> C3["guid (bei veröffentlichten Beiträgen NICHT ändern!)"]

    D --> D1["_elementor_data (JSON / escaped)"]
    D --> D2["_wp_attached_file (Medienpfade)"]
    D --> D3["ACF-Felder (serialisiert)"]

#1. Tabelle wp_options

Die wichtigste Konfigurationstabelle. Sie enthält zwei kritische Einträge, die über das Funktionieren der Website entscheiden:

  • siteurl: zeigt, wo die WordPress-Dateien physisch liegen (Pfad zum Core).
  • home: die Hauptadresse der Website, die Besucher im Browser eingeben.

Daneben speichert die Tabelle in serialisierter Form:

  • sidebars_widgets: die Anordnung der Widgets in Seitenleisten und Footern.
  • theme_mods_[themename]: Farben, Header-Layout, Typografie und Logo aus dem Customizer.
  • Einstellungen von SEO-Plugins (Rank Math, Yoast), Sicherheits- und Cache-Plugins.

#2. Tabelle wp_posts

Speichert den Inhalt von Beiträgen, Seiten, WooCommerce-Produkten und Mediathek-Elementen.

  • Spalte post_content: enthält absolute Links auf andere Unterseiten, eingebettete img-Tags, Links auf PDF-Dateien und die Blockkommentare von Gutenberg.
  • Spalte guid (Globally Unique Identifier): die eindeutige Kennung eines Beitrags. Wichtige Regel: Die WordPress-Dokumentation sagt: “Ändern Sie niemals, unter keinen Umständen, den Inhalt der GUID-Spalte” (Migrating WordPress, developer.wordpress.org, eigene Übersetzung). Die Spalte guid darf nicht geändert werden, weil RSS-Reader sie nutzen, um neue Artikel zu erkennen. Eine Änderung führt dazu, dass Feedreader alle älteren Beiträge als neu behandeln und Abonnenten erneut benachrichtigen.

#3. Tabelle wp_postmeta

Enthält zusätzliche Attribute von Beiträgen und Seiten. Hier landen die serialisierten Arrays der Felder aus Advanced Custom Fields (ACF), die Metadaten von Anhängen (_wp_attachment_metadata) und die Konfiguration von Page Buildern wie Elementor oder Divi.

#4. Tabellen wp_usermeta und wp_comments

Enthalten die Website-Adressen von Kommentarautoren und Metadaten der Benutzerprofile.


#Domain in WordPress mit WP-CLI search-replace ändern

Die WordPress-Kommandozeile (WP-CLI) ist das schnellste, zuverlässigste und vollständig automatisierbare Werkzeug für den URL-Umzug. Sie läuft per SSH direkt auf dem Server und arbeitet mit den PHP-Strukturen im Arbeitsspeicher.

Falls WP-CLI auf dem Server noch fehlt, beschreibt wp-cli.org die Installation über die Phar-Datei:

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
php wp-cli.phar --info
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info

#Schritt 1: Backup erstellen

Bevor Sie irgendetwas an der Produktionsdatenbank ändern, erstellen Sie einen Dump als SQL-Datei:

# Datenbank-Dump mit DROP-TABLE-Anweisungen
wp db export backup-vor-migration-$(date +%Y%m%d_%H%M%S).sql --add-drop-table

Geht etwas schief, stellen Sie den ursprünglichen Zustand in Sekunden wieder her:

wp db import backup-vor-migration-*.sql

#Schritt 2: Testlauf mit —dry-run

Mit dem Flag --dry-run sehen Sie, wie viele Zeilen in welchen Tabellen geändert würden, ohne dass sich an der Datenbank etwas ändert:

wp search-replace 'https://alte-domain.de' 'https://neue-domain.de' --all-tables --dry-run

Das Ergebnis ist eine Tabelle mit den Spalten Table, Column, Replacements und Type sowie einer Zusammenfassung mit der Gesamtzahl der Ersetzungen. Die Spalte Type zeigt, ob eine Spalte in SQL oder in PHP verarbeitet wurde. Ist die Zahl der Ersetzungen null, unterscheidet sich die alte Adresse meist im Protokoll, im Präfix www oder im abschließenden Schrägstrich von dem, was in der Datenbank steht.

#Schritt 3: Die eigentliche Ersetzung ausführen

Für die endgültige Ersetzung empfehlen wir diese Kombination von Flags:

wp search-replace 'https://alte-domain.de' 'https://neue-domain.de' \
  --all-tables \
  --precise \
  --recurse-objects \
  --skip-columns=guid \
  --report-changed-only

Die Parameter im Einzelnen:

  • --all-tables: durchsucht alle Tabellen der Datenbank, einschließlich eigener Tabellen von Shop-, Formular- und Log-Plugins.
  • --precise: erzwingt PHP statt SQL für alle Spalten. Die WP-CLI-Dokumentation beschreibt das als langsamer, aber zuverlässiger bei komplexen serialisierten Daten.
  • --recurse-objects: geht rekursiv in serialisierte Objekte. Das ist standardmäßig aktiv und lässt sich mit --no-recurse-objects abschalten, die explizite Angabe dokumentiert also nur die Absicht.
  • --skip-columns=guid: überspringt die Spalte guid in wp_posts und schützt RSS-Reader vor doppelten Einträgen.
  • --report-changed-only: zeigt in der Zusammenfassung nur Tabellen, in denen tatsächlich etwas geändert wurde.

Für Groß- und Kleinschreibung gilt: wp search-replace unterscheidet sie. Eine Suche ohne Beachtung der Schreibweise geht nur mit --regex und --regex-flags='i', und laut Dokumentation ist der Regex-Modus deutlich langsamer.

#Domain in einem WordPress-Multisite-Netzwerk ändern

In Multisite-Installationen (Netzwerk mehrerer Websites) haben die Systemtabellen eigene Präfixe (z. B. wp_2_posts, wp_3_options), und die Domains der einzelnen Unterseiten stehen in den Tabellen wp_blogs und wp_site.

Hier verwenden Sie das Flag --network, das alle in $wpdb registrierten Tabellen des ganzen Netzwerks erfasst, oder --all-tables-with-prefix, das zusätzlich Tabellen mit dem Präfix einbezieht, die nicht in $wpdb registriert sind:

wp search-replace 'https://altes-netz.de' 'https://neues-netz.de' --network --all-tables-with-prefix

Die WordPress-Dokumentation räumt ein, dass sich dieser Schritt beim Domainwechsel eines Multisite-Netzwerks “noch nicht einfach automatisieren lässt” (Migrating WordPress, developer.wordpress.org, eigene Übersetzung). Prüfen Sie nach der Ersetzung von Hand:

  • die Tabellen wp_site und wp_blogs, in denen Domain und Pfad des Netzwerks und jeder Unterseite gespeichert sind,
  • die Optionen home, siteurl und fileupload_url in der Optionstabelle jeder Website (wp_options, wp_2_options und so weiter),
  • beim Wechsel von Subdomains auf Unterverzeichnisse oder umgekehrt: die Datei .htaccess und die Konstante SUBDOMAIN_INSTALL in wp-config.php.

#Datenbank mit neuen URLs als SQL-Datei exportieren

Wenn Sie eine Datenbankmigration für einen Kunden lokal vorbereiten und eine fertige SQL-Datei mit ersetzten Domains erzeugen möchten, ohne die lokale Arbeitsdatenbank anzufassen:

wp search-replace 'https://localhost/projekt' 'https://kundendomain.de' \
  --all-tables \
  --export=datenbank-bereit-zum-import.sql

#Von www auf die Domain ohne www wechseln

Ändert sich nur das Präfix, ersetzen Sie die vollständige Adresse mit Protokoll, damit keine fremden Zeichenketten getroffen werden:

wp search-replace 'https://www.beispiel.de' 'https://beispiel.de' --all-tables --precise --skip-columns=guid --dry-run

#URLs mit dem Plugin Better Search Replace ändern

Wenn Sie eine Website auf Shared Hosting ohne SSH-Zugang betreuen oder lieber im WordPress-Dashboard arbeiten, ist das Plugin Better Search Replace von WP Engine (früher Delicious Brains) die sicherste Lösung.

Schritt für Schritt im WordPress-Dashboard:
1. Plugins > Plugin hinzufügen öffnen und nach "Better Search Replace" suchen.
2. Plugin installieren und aktivieren.
3. Werkzeuge > Better Search Replace öffnen.
4. Im Feld "Search for" die alte URL eintragen (z. B. https://alte-domain.de).
5. Im Feld "Replace with" die neue URL eintragen (z. B. https://neue-domain.de).
6. Alle Tabellen in der Liste markieren (Strg+A unter Windows, Cmd+A unter macOS).
7. Sicherstellen, dass "Run as dry run?" AKTIVIERT ist.
8. "Run Search/Replace" klicken und den Bericht prüfen.
9. "Run as dry run?" deaktivieren und den Vorgang erneut starten, um die Änderungen zu speichern.

#Fehler in Better Search Replace beheben

  • Fehler 504 Gateway Timeout oder überschrittenes Skript-Zeitlimit (max_execution_time): Bei großen Datenbanken kann der Webserver die HTTP-Anfrage abbrechen. Verringern Sie im Tab Settings des Plugins den Wert Max Page Size. Der Standardwert liegt bei 20000 Zeilen pro Durchgang, wie der Quellcode des Plugins zeigt (class-bsr-admin.php); ein kleinerer Wert bedeutet mehr, aber kürzere Anfragen.

#siteurl und home in WordPress ändern

Zwei Optionen aus der Tabelle wp_options entscheiden, ob Sie sich unter der neuen Adresse überhaupt anmelden können. Die WordPress-Dokumentation (Changing The Site URL) unterscheidet sie so: home ist die “Website-Adresse (URL)”, also die Adresse, die Besucher im Browser eingeben, und siteurl ist die “WordPress-Adresse (URL)”, also der Ort, an dem die Core-Dateien liegen. Beide Felder unter Einstellungen > Allgemein sollten https:// enthalten und nicht mit einem Schrägstrich enden.

Die Dokumentation beschreibt mehrere Wege, diese Werte zu ändern. Jeder passt zu einer anderen Situation:

MethodeWann sinnvollWorauf achten
wp option update in WP-CLISSH vorhanden, Dashboard funktioniert nichtÄndert nur zwei Optionen, den Rest erledigt wp search-replace
Konstanten WP_HOME und WP_SITEURL in wp-config.phpWebsite muss schnell wieder laufenWerte sind fest eingetragen, die Felder unter Einstellungen > Allgemein lassen sich nicht bearbeiten
update_option() in der functions.php des ThemesNur FTP-ZugangCode direkt nach dem ersten Laden des Dashboards entfernen
Konstante RELOCATEWebsite in ein anderes Verzeichnis oder auf einen anderen Server verschobenKorrigiert nur die Adressen des Admin-Bereichs und ist unsicher, wenn sie in der Datei bleibt
wp_options in phpMyAdmin bearbeitenNur Zugang zum Hosting-PanelZuerst Backup; das Tabellenpräfix muss nicht wp_ sein

#siteurl und home mit WP-CLI ändern

Die Dokumentation nennt zwei Befehle und danach die Ersetzung der Adressen im Inhalt unter Auslassung der Spalte guid:

wp option update home 'https://neue-domain.de'
wp option update siteurl 'https://neue-domain.de'
wp search-replace 'https://alte-domain.de' 'https://neue-domain.de' --skip-columns=guid

#Adresse über functions.php ändern

Wenn Sie nur per FTP zugreifen können, empfiehlt die Dokumentation, in der functions.php des aktiven Themes direkt nach dem öffnenden <?php zwei Zeilen einzufügen:

update_option( 'siteurl', 'https://neue-domain.de' );
update_option( 'home', 'https://neue-domain.de' );

Laden Sie nach dem Hochladen der Datei den Login-Bildschirm oder das Dashboard einige Male und entfernen Sie die Zeilen dann wieder. Die Dokumentation schreibt unmissverständlich: “Lassen Sie diesen Code nicht in der Datei functions.php” (Migrating WordPress, developer.wordpress.org, eigene Übersetzung). Der Code würde bei jeder Anfrage laufen und Optionen überschreiben, die Sie später im Dashboard ändern möchten.

#Konstante RELOCATE nach dem Verschieben des Verzeichnisses

Die Konstante define( 'RELOCATE', true );, in wp-config.php vor dem Kommentar That's all, stop editing! eingetragen, sorgt dafür, dass WordPress nach dem Login über wp-login.php auf dem neuen Server die aktuelle Adresse übernimmt. Laut Dokumentation korrigiert sie nur die Adressen des Admin-Bereichs, nicht den Rest der Konfiguration, und es ist unsicher, sie stehen zu lassen: “Entfernen Sie die RELOCATE-Zeile immer aus wp-config.php, wenn Sie fertig sind” (Migrating WordPress, developer.wordpress.org, eigene Übersetzung).

#Transients in der umgezogenen Datenbank

Die Dokumentation weist auf Transients hin, also temporäre Werte in wp_options. Sie können alte Adressen enthalten, und weil WordPress sie selbst neu erzeugt, lassen sie sich in der umgezogenen Kopie der Datenbank gefahrlos löschen. Mit WP-CLI erledigt das wp transient delete --all, die Dokumentation nennt außerdem eine Abfrage für phpMyAdmin, ebenfalls erst nach einem Backup:

DELETE FROM `wp_options` WHERE `option_name` LIKE '%\_transient\_%';

#URLs ändern, wenn das WordPress-Dashboard nicht funktioniert

Für Notfälle, wenn kein SSH-Zugang besteht und das Dashboard wegen einer Weiterleitungsschleife oder beschädigter Dateien nicht lädt, ist seit über einem Jahrzehnt das Skript Search-Replace-DB (kurz SRDB) der Agentur Interconnect/it bewährt.

Vorgehen mit dem SRDB-Skript:
1. Das offizielle ZIP-Archiv von interconnectit.com herunterladen.
2. Dateien entpacken und den Ordner in eine eindeutige, schwer zu erratende Zeichenkette umbenennen (z. B. srdb-sec-8f7a9d/).
3. Den Ordner per FTP / SFTP in das Hauptverzeichnis der WordPress-Installation hochladen (dorthin, wo wp-config.php liegt).
4. Im Browser die Adresse https://ihre-domain.de/srdb-sec-8f7a9d/ öffnen.
5. Das Skript liest die Datenbank-Zugangsdaten automatisch aus wp-config.php.
6. Die Felder "replace" (alter Wert) und "with" (neuer Wert) ausfüllen.
7. "dry run" klicken und nach der Prüfung "live run".
8. KRITISCH: Nach Abschluss den roten Button "delete me" klicken, damit sich das Skript vom Server löscht.

[!CAUTION] Ein auf einem laufenden Server zurückgelassenes Search-Replace-DB ist eine kritische Sicherheitslücke. Wer den Pfad errät, kann die Datenbank ohne Passwort lesen und verändern. Prüfen Sie nach der Arbeit immer, ob der Ordner wirklich gelöscht ist!


#URLs in Elementor, Divi und Gutenberg ändern

Moderne Page Builder und der Blockeditor Gutenberg bringen zusätzliche Kodierungsebenen mit, an die Sie beim Aktualisieren der URLs denken müssen.

graph LR
    subgraph WP_CLI_Execution["Schritt 1: Datenbank"]
        A["wp search-replace"] --> B["Tabellen wp_posts, wp_postmeta, wp_options"]
    end

    subgraph Builder_Sync["Schritt 2: Page Builder"]
        B --> C["Elementor: Tools > Replace URL"]
        B --> D["Elementor: CSS-Dateien neu erzeugen"]
    end

    subgraph Edge_Purge["Schritt 3: Cache und Edge"]
        C & D --> F["wp cache flush (Redis/Memcached)"]
        F --> G["CDN leeren (Cloudflare)"]
    end

#1. URLs in den JSON-Daten von Elementor

Elementor speichert das Seitenlayout im Metafeld _elementor_data als JSON, in dem die Schrägstriche in URLs oft maskiert sind (escaped slashes):

{\"url\":\"https:\/\/alte-domain.de\/wp-content\/uploads\/2026\/08\/banner.jpg\"}

Eine normale Suche nach https://alte-domain.de findet die maskierte Form https:\/\/alte-domain.de unter Umständen nicht. Außerdem kompiliert Elementor Stilregeln in statische CSS-Dateien im Verzeichnis wp-content/uploads/elementor/css/.

Richtiges Vorgehen nach dem Umzug einer Elementor-Website:

  1. Führen Sie das normale wp search-replace in der Datenbank aus.
  2. Melden Sie sich im WordPress-Dashboard an und öffnen Sie Elementor > Tools > Replace URL.
  3. Tragen Sie alte und neue URL ein und klicken Sie auf Replace URL.
  4. Klicken Sie im Tab General auf Regenerate Files & Data.

#2. URLs in Gutenberg-Blöcken

Gutenberg-Blöcke speichern Medienattribute direkt in HTML-Kommentaren innerhalb von post_content:

<!-- wp:image {"id":412,"sizeSlug":"full","linkDestination":"custom"} -->
<figure class="wp-block-image size-full"><a href="https://alte-domain.de/angebot/"><img src="https://alte-domain.de/wp-content/uploads/2026/08/grafik.png" alt="Angebot"/></a></figure>
<!-- /wp:image -->

Sowohl wp search-replace als auch Better Search Replace kommen damit problemlos zurecht, solange die Spalte post_content der Tabelle wp_posts durchsucht wird.

#3. Fest eingetragene URLs in Theme-Dateien

Manche Themes und Plugins enthalten Adressen direkt in PHP-, CSS- oder JavaScript-Dateien. Diese erreicht keine Datenbank-Ersetzung, sie lassen sich aber auf dem Server finden:

grep -rn "alte-domain.de" wp-content/themes/ihr-theme/

#Domainwechsel in einem WooCommerce-Shop

Beim Domainwechsel eines WooCommerce-Shops verdienen die Module besondere Aufmerksamkeit, die mit externen Zahlungs-, Versand- und ERP-Systemen kommunizieren:

  1. Payment-Gateways:
    • Die meisten Zahlungsanbieter hinterlegen in ihrem Entwicklerbereich Adressen für Rückmeldungen (Webhooks / IPN). Wechseln Sie von alt.de auf neu.de, landen Meldungen über bezahlte Bestellungen weiter auf der alten Adresse und erzeugen Transaktionsfehler.
    • Nach wp search-replace müssen Sie sich bei jedem Zahlungsanbieter anmelden und die Webhook-Adresse aktualisieren.
  2. Schlüssel und Webhooks der WooCommerce REST API:
    • Prüfen Sie unter WooCommerce > Settings > Advanced > Webhooks, ob die Zieladressen (Delivery URL) aktualisiert wurden. Synchronisieren Webhooks Lagerbestände mit einem ERP-System, aktualisieren Sie die Endpunkte auch in der Integrationssoftware.
  3. Sitzungen und Warenkörbe der Kunden:
    • Die Tabelle wp_woocommerce_sessions enthält temporäre Warenkorbdaten. Nach dem Domainwechsel lohnt es sich, unter WooCommerce > Status > Tools die Funktion Clear customer sessions auszuführen, um Fehler mit Sitzungstokens nach dem Wechsel der Domain-Cookies zu vermeiden.

#Search-replace auf einer großen Datenbank und einem MySQL-Cluster

Bei sehr großen Datenbanken dauert ein einzelner Durchlauf von wp search-replace über alle Tabellen lange und schreibt die ganze Zeit in Tabellen, die die laufende Website nutzt. Die WP-CLI-Dokumentation nennt zwei wichtige Einschränkungen: Tabellen ohne Primärschlüssel werden übersprungen, und die Optionen --regex und --log verlangsamen die Arbeit deutlich.

#1. Search-replace in kleinere Teile aufteilen

Der Befehl wp search-replace hat weder --batch-size noch --limit; die Optionsliste in der WP-CLI-Dokumentation enthält sie nicht, und Anleitungen, die sie nennen, funktionieren nicht. Die Arbeit wird anders aufgeteilt: indem man Tabellennamen als Argumente übergibt (Platzhalter sind erlaubt) oder Tabellen mit --skip-tables ausschließt:

# Erst Inhalte, dann Metadaten, in getrennten Durchläufen
wp search-replace 'https://alt.de' 'https://neu.de' wp_posts --precise --skip-columns=guid
wp search-replace 'https://alt.de' 'https://neu.de' wp_postmeta --precise

# Alles außer einer großen Log-Tabelle eines Plugins
wp search-replace 'https://alt.de' 'https://neu.de' --all-tables --skip-tables='wp_*_log' --precise --skip-columns=guid

Die Option --include-columns beschränkt die Ersetzung auf bestimmte Spalten, und bei --export legt --export_insert_size fest, wie viele Zeilen in einer INSERT-Anweisung stehen (Standard 50).

#2. Search-replace bei Replikation (Amazon Aurora, MySQL Galera)

Läuft die Datenbank in einer Master-Slave-Architektur oder einem Galera-Cluster, erzeugt das massenhafte Ändern von Datensätzen einen großen Datenstrom im Binärlog (binlog). Das kann zu deutlicher Replikationsverzögerung (Replication Lag) auf den Leseknoten führen.

Empfohlene Strategie für Hochverfügbarkeitsumgebungen:

  • Den Vorgang in einem Wartungsfenster mit möglichst wenig Traffic ausführen.
  • Replikationsknoten für die Dauer des Massenschreibens vorübergehend abkoppeln.
  • Mit --export eine verarbeitete SQL-Datei auf einer separaten Arbeitsmaschine erzeugen und im Wartungsfenster importieren.

#3. Wartungsmodus während der Migration

WP-CLI kann den Wartungsmodus von WordPress direkt steuern, sodass Besucher während der Ersetzung keine halb umgestellte Website sehen:

wp maintenance-mode activate
wp search-replace 'https://alt.de' 'https://neu.de' --all-tables --precise --skip-columns=guid
wp maintenance-mode deactivate

#Von HTTP auf HTTPS wechseln und Webserver konfigurieren

Wenn Sie nicht die Domain ändern, sondern ein SSL-Zertifikat einführen und vom unverschlüsselten auf das verschlüsselte Protokoll wechseln:

wp search-replace 'http://ihredomain.de' 'https://ihredomain.de' \
  --all-tables \
  --precise \
  --skip-columns=guid

Ersetzen Sie dabei immer die vollständige Adresse Ihrer eigenen Domain und nie nur http://, sonst ändern Sie auch Links auf fremde Websites, die gar kein HTTPS anbieten. So beseitigen Sie das Problem Mixed Content (gemischte Inhalte), bei dem der Browser Skripte, Schriften oder Bilder blockiert, die noch über das alte http:// ausgeliefert werden.

#301-Weiterleitungen auf Server-Ebene in Nginx und Apache

Nach dem Domainwechsel in der Datenbank ist aus SEO-Sicht die Weiterleitung des gesamten Traffics von der alten auf die neue Adresse mit HTTP-Statuscode 301 (Moved Permanently) entscheidend.

Nginx-Konfiguration (/etc/nginx/sites-available/alte-domain.conf):

server {
    listen 80;
    listen 443 ssl http2;
    server_name alte-domain.de www.alte-domain.de;

    ssl_certificate /etc/letsencrypt/live/alte-domain.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/alte-domain.de/privkey.pem;

    return 301 https://neue-domain.de$request_uri;
}

Apache-Konfiguration (.htaccess auf dem alten Server):

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^(?:www\.)?alte-domain\.de$ [NC]
    RewriteRule ^(.*)$ https://neue-domain.de/$1 [L,R=301]
</IfModule>

Ob die Weiterleitung greift, zeigt der Statuscode der alten Adresse:

curl -s -o /dev/null -w "%{http_code}\n" https://alte-domain.de/

#Konstanten in wp-config.php und Werte in der Datenbank

Im Notfall werden URLs oft in wp-config.php erzwungen:

define('WP_HOME', 'https://neue-domain.de');
define('WP_SITEURL', 'https://neue-domain.de');

So wirken diese Konstanten in der Praxis:

  • In wp-config.php definierte Konstanten überschreiben die von WordPress gelesenen Werte siteurl und home, ändern aber nicht die Einträge in der Datenbank. Die Dokumentation nennt das ausdrücklich ein festes Eintragen der Werte und betont, dass es nicht unbedingt die beste Lösung ist.
  • Die Adressfelder unter Einstellungen > Allgemein lassen sich dann nicht bearbeiten.
  • Links in Beitragsinhalten, Anhängen und Widgets zeigen weiterhin auf die alte Adresse.
  • Betrachten Sie die Konstanten in wp-config.php als Übergangslösung; dauerhaft sollte die Datenbank immer mit wp search-replace aktualisiert werden.

#Checkliste für den Domainwechsel in WordPress

Arbeiten Sie vor dem Start nach einem festen Plan:

PhaseAufgabeWerkzeug / Befehl
Vor der MigrationVollständiger Datenbank-Dumpwp db export backup-$(date +%s).sql --add-drop-table
Vor der MigrationKopie von wp-content/uploads und .htaccessrsync / tar -czf uploads.tar.gz
Vor der MigrationCache- und Minify-Plugins deaktivierenDashboard / wp plugin deactivate
WährendTestlauf der Ersetzungsparameterwp search-replace 'old' 'new' --all-tables --dry-run
WährendEigentliche Ersetzung in der Datenbankwp search-replace 'old' 'new' --all-tables --precise --skip-columns=guid
WährendDomains in Page Buildern ersetzen (Elementor)Dashboard > Elementor > Tools > Replace URL
Nach der MigrationObject Cache und Transients leerenwp cache flush und wp transient delete --all
Nach der MigrationPermalinks neu schreibenwp rewrite flush --hard

#Bash-Skript zum Synchronisieren der WordPress-Datenbank zwischen Umgebungen

In modernen Workflows mit Docker-Containern oder Staging-Umgebungen (DDEV, Lando, LocalWP) ist das manuelle Eintippen von Befehlen zeitaufwendig und fehleranfällig. In Entwicklerteams ist ein Bash-Skript üblich, das die Produktionsdatenbank holt, lokal importiert und die Domains ersetzt.

#!/usr/bin/env bash
# Skript zur automatischen Datenbank-Synchronisierung: sync-db.sh
set -eo pipefail

PROD_HOST="ihr-produktionsserver.de"
PROD_USER="deploy"
PROD_PATH="/var/www/html"
PROD_URL="https://ihrefirma.de"
LOCAL_URL="https://projekt.local"
BACKUP_DIR="./backups"

mkdir -p "${BACKUP_DIR}"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
DUMP_FILE="${BACKUP_DIR}/dump_prod_${TIMESTAMP}.sql"

echo "==> 1/4 Produktionsdatenbank per SSH holen..."
ssh "${PROD_USER}@${PROD_HOST}" "cd ${PROD_PATH} && wp db export - --add-drop-table" > "${DUMP_FILE}"

echo "==> 2/4 Datenbank in die lokale Umgebung importieren..."
wp db import "${DUMP_FILE}"

echo "==> 3/4 Domains sicher und serialisierungsfest ersetzen..."
wp search-replace "${PROD_URL}" "${LOCAL_URL}" \
  --all-tables \
  --precise \
  --recurse-objects \
  --skip-columns=guid \
  --report-changed-only

echo "==> 4/4 Cache leeren und Permalinks neu schreiben..."
wp cache flush
wp rewrite flush --hard

echo "==> Fertig! Die lokale Umgebung ist unter ${LOCAL_URL} synchronisiert."

#Serialisierung nach der Arbeit prüfen

Wenn Sie sicher sein wollen, dass während der Migration kein Feld beschädigt wurde, prüft dieses kurze PHP-Skript in WP-CLI alle serialisierten Einträge der Tabelle wp_options:

wp eval '
global $wpdb;
$options = $wpdb->get_results("SELECT option_name, option_value FROM {$wpdb->options} WHERE option_value LIKE \"a:%\" OR option_value LIKE \"O:%\"");
$broken = 0;
foreach ($options as $opt) {
    if (is_serialized($opt->option_value) && @unserialize($opt->option_value) === false) {
        echo "Beschaedigte Option: " . $opt->option_name . PHP_EOL;
        $broken++;
    }
}
if ($broken === 0) {
    echo "Alle serialisierten Optionen in wp_options sind korrekt." . PHP_EOL;
} else {
    echo $broken . " beschaedigte Eintraege gefunden!" . PHP_EOL;
}
'

Ob noch alte Adressen übrig sind, zeigt ein Testlauf mit der alten Domain: Meldet wp search-replace 'alte-domain.de' 'neue-domain.de' --all-tables --dry-run null Ersetzungen, ist die Datenbank sauber.


#Fehler nach dem Domainwechsel in WordPress beheben

#1. Weiterleitungsschleife nach dem Domainwechsel (ERR_TOO_MANY_REDIRECTS)

Wenn die Website nach dem Domainwechsel in einer endlosen Weiterleitungsschleife hängt:

  • Prüfen Sie, ob siteurl und home in wp_options genau dasselbe Protokoll (https://) und Präfix (www oder ohne) haben wie auf dem Webserver oder in Cloudflare konfiguriert.
  • Prüfen Sie die SSL-Konfiguration in Cloudflare (der SSL/TLS-Modus sollte Full (Strict) sein, nicht Flexible).
  • Setzen Sie die Datei .htaccess mit diesem Befehl auf die WordPress-Standardform zurück:
    wp rewrite flush --hard

#2. CSS-Stile und Icons fehlen nach der Migration

  • Lädt die Website als roher Text ohne Stile, sind die häufigsten Ursachen Stylesheets und Skripte, die noch auf die alte Adresse zeigen, gemischte Inhalte (Mixed Content) beim Wechsel auf HTTPS oder eine Blockade durch die CORS-Richtlinie.
  • Öffnen Sie die Entwicklerkonsole des Browsers (F12 > Tab Console), um Dateien zu finden, die noch über das alte http:// geladen werden.

#3. Beschädigte Widgets oder ACF-Felder

  • Wurden die Regeln der Serialisierung ignoriert und ein rohes SQL REPLACE ausgeführt, ist der einzige sichere Weg, die Datenbank aus dem vorher erstellten Dump wiederherzustellen (wp db import backup.sql) und den Vorgang mit wp search-replace --precise zu wiederholen.

#4. Fehler Allowed memory size exhausted in WP-CLI

Bei search-replace auf Tabellen mit sehr vielen Textdaten (etwa umfangreiche Log-Tabellen oder Beitragsrevisionen) kann der PHP-Prozess im Terminal sein Speicherlimit ausschöpfen:

  • Um das Speicherlimit für einen einzelnen WP-CLI-Befehl vorübergehend zu erhöhen, starten Sie ihn mit einer PHP-Einstellung:
    php -d memory_limit=1024M /usr/local/bin/wp search-replace 'https://alt.de' 'https://neu.de' --all-tables
  • Löschen Sie vor der Migration außerdem überflüssige Revisionen und abgelaufene Transients:
    wp transient delete --all && wp post delete $(wp post list --post_type='revision' --format=ids) --force

#5. Abweichende Zeichensätze und Kollation (Collation)

Wenn Sie einen Datenbank-Dump auf einen älteren oder anderen Datenbankserver übertragen, kennt der Zielserver die im Dump verwendete Kollation unter Umständen nicht, zum Beispiel utf8mb4_unicode_520_ci:

  • Erscheint beim Import der .sql-Datei der Fehler #1273 - Unknown collation: 'utf8mb4_unicode_520_ci', ersetzen Sie die Zeichenkette vor dem Import in der SQL-Datei:
    sed -i 's/utf8mb4_unicode_520_ci/utf8mb4_unicode_ci/g' backup.sql
  • Beide Kollationen speichern utf8mb4, Umlaute und ß bleiben also erhalten; es ändert sich nur die Regel für Sortieren und Vergleichen von Text.

#Zusammenfassung

Die korrekte Aktualisierung von URLs in der WordPress-Datenbank setzt Verständnis dafür voraus, wie PHP und relationale Datenbanken arbeiten. Rohe SQL-Abfragen oder das Bearbeiten von Dumps im Texteditor sind der kürzeste Weg zu einer instabilen Website und verlorenen Einstellungen.

WP-CLI mit den Flags --all-tables --precise --skip-columns=guid, vorher abgesichert durch ein Backup und einen Durchlauf mit --dry-run, lässt serialisierte Daten und die Spalte guid unversehrt.

Planen Sie eine umfassende Modernisierung, eine Headless-Architektur oder den Umstieg auf eine Plattform der nächsten Generation? Sehen Sie sich unsere Leistungen zur Migration von WordPress zu Astro und Next.js und das Core-Web-Vitals-Audit an.

Nächster Schritt

Machen Sie aus dem Artikel eine echte Umsetzung

Dieser Block stärkt die interne Verlinkung und führt Nutzer gezielt zum nächsten sinnvollen Schritt im Service- und Content-System.

Soll das Thema auf Ihrer Website umgesetzt werden?

Wenn Sie aus dem Artikel konkrete Maßnahmen für Website, Relaunch oder Weiterentwicklung ableiten wollen, definiere ich den Scope und setze ihn um.

Relevanter Cluster

Weitere WordPress-Dienste und Wissensbasis entdecken

Stärken Sie Ihr Unternehmen mit professionellem technischen Support in den Kernbereichen des WordPress-Ökosystems.

Warum SQL UPDATE mit REPLACE die WordPress-Datenbank beschädigt#
WordPress speichert Konfigurationen, Widgets, Theme-Einstellungen und ACF-Felder als serialisierte PHP-Arrays (z. B. s:16:"https://alt.de/x"). SQL REPLACE tauscht den Text, aktualisiert aber nicht die Längenangabe. Beim Lesen erkennt PHP die abweichende Länge und verwirft die gesamte Struktur als beschädigt.
Welches Werkzeug für den Domainwechsel in der WordPress-Datenbank am sichersten ist#
Empfohlen ist das offizielle WP-CLI mit dem Befehl wp search-replace. Laut WP-CLI-Dokumentation behandelt der Befehl serialisierte PHP-Daten korrekt: Er deserialisiert sie, ersetzt den Text, berechnet die Längen neu und schreibt die Daten zurück.
Ob man die Spalte guid in wp_posts ändern soll#
Nein. Die Spalte guid dient Feedreadern als dauerhafte, eindeutige Kennung eines Beitrags. Die WordPress-Dokumentation schreibt vor, sie niemals zu ändern, deshalb nutzt man in WP-CLI das Flag --skip-columns=guid.
URLs auf Shared Hosting ohne SSH-Zugang aktualisieren#
Ohne SSH nennt die WordPress-Dokumentation das Plugin Better Search Replace (von WP Engine) oder das Skript Search and Replace for WordPress Databases von Interconnect/it. Das Skript muss direkt nach der Arbeit vom Server gelöscht werden.
Was tun, wenn nach der Migration Widgets verschwinden#
Verschwundene Widgets bedeuten beschädigte serialisierte Daten. Spielen Sie Ihr Backup mit wp db import backup.sql zurück und führen Sie die Migration erneut mit einem serialisierungsfähigen Werkzeug wie WP-CLI oder Better Search Replace durch.

Sie brauchen ein FAQ für Branche und Zielmarkt? Wir erstellen eine Version passend zu Ihren Business-Zielen.

Kontakt aufnehmen

Ähnliche Artikel

WordPress-Hosting-Benchmarks 2026 erklärt

Kevin Ohashis Review-Signal-Tests sind 2026 nach drei Jahren Pause zurückgekehrt, getragen von einer brandneuen Open-Source-Lasttest-Plattform. Wir zerlegen die fünf Preisstufen plus WooCommerce, benennen die Sieger, benennen die Hoster, die nicht angetreten sind, und übersetzen die Daten für europäische Agenturen.