Datenbankmigrationen mit PHP und SQLite kontrolliert ausführen
Zwei künstliche Aufgaben erhalten einen Prüfstatus. Der vollständige Runner und 38 echte Prüfbedingungen machen den Übergang und seine Grenzen nachvollziehbar.

Ein neues Feld lässt sich in einer Testdatenbank schnell ergänzen. Anspruchsvoller wird die Änderung, wenn bereits Datensätze existieren, mehrere Programmstände beteiligt sind und ein fehlgeschlagener Schritt nachvollziehbar zurückgenommen werden muss. Eine Migration beschreibt deshalb einen überprüfbaren Übergang: welcher Ausgangsstand erwartet wird, welche Änderung erlaubt ist und woran ihr vollständiger Abschluss erkennbar ist.
Dieser Leitfaden entwickelt dafür ein vollständiges PHP-Beispiel mit SQLite. Zwei künstliche Aufgaben erhalten einen zusätzlichen Prüfstatus. Ihre Kennungen und vorhandenen Texte bleiben erhalten. Ein Versionsregister speichert die ausgeführten Schritte mit Prüfsummen. Das Programm wurde mit PHP 8.4.27 und SQLite 3.53.4 tatsächlich ausgeführt. Die Dokumentation wurde am 9. November 2026 geprüft. Die Ergebnisse betreffen die beschriebenen isolierten Datenbankdateien.
Den fachlichen Übergang zuerst beschreiben
Die Ausgangstabelle enthält eine Kennung und einen Aufgabentitel. Künftig soll ein zusätzlicher Prüfstatus unterscheiden, ob eine Aufgabe noch ungeprüft oder bereits freigegeben ist. Für bestehende Zeilen ist die korrekte Ausgangsaussage unreviewed. Ein vorhandener Datensatz wird dadurch nicht nachträglich als fachlich geprüft eingeordnet. Diese Entscheidung muss vor dem SQL feststehen, weil ein technisch bequemes Standardfeld sonst eine unbelegte Geschäftsaussage erzeugen könnte.
Zur Abnahme gehören mehrere Bedingungen: Alle bisherigen Kennungen bleiben gleich. Sonderzeichen in Titeln werden erhalten. Jede bestehende Aufgabe besitzt anschließend einen gültigen Status. Unbekannte Statuswerte werden von der Datenbank zurückgewiesen. Der Nachweis der Migration passt zum tatsächlich ausgeführten SQL. Diese Bedingungen bilden die gemeinsame Grundlage für Entwicklung, fachliche Prüfung und Betrieb. Eine Aussage wie „Spalte erfolgreich hinzugefügt“ würde lediglich einen kleinen Teil davon abdecken.
Schema, Daten und laufenden Programmstand gemeinsam prüfen
Eine Datenbank kann technisch erreichbar sein und trotzdem nicht zum gestarteten Programm passen. Der neue Code erwartet vielleicht einen Prüfstatus, während die Tabelle ihn noch nicht besitzt. Umgekehrt kann ein älterer Export alle Spalten ungeprüft übernehmen und durch eine zusätzliche Spalte sein Ausgabeschema verändern. Prüfen Sie deshalb die tatsächlichen Leser und Schreiber: Webanwendung, Hintergrundaufgaben, Importprogramme, Berichte und manuell gestartete Werkzeuge.
Für unser kleines Beispiel bleibt eine Abfrage mit ausdrücklich genannten Spalten id und title nach der Erweiterung sinnvoll verwendbar. Daraus folgt noch keine Zusage für eine unbekannte Anwendung. Insbesondere positionsabhängige Auswertungen von SELECT *, feste CSV-Spalten und eigene Serialisierungen verdienen einen gesonderten Test. Die Kompatibilitätsprüfung betrachtet konkrete Aufrufe und erwartete Ergebnisse. Sie erschöpft sich nicht in der Versionsnummer einer Bibliothek.
Einen unveränderlichen Versionsnachweis führen
Die Tabelle schema_migrations protokolliert Kennung, SHA-256-Prüfsumme und Ausführungszeit jedes Schritts. Die Kennung beantwortet, welcher Schritt vorgesehen ist. Die Prüfsumme zeigt, ob der aktuell mitgelieferte SQL-Text zum bereits protokollierten Inhalt passt. Ein Fehler an dieser Stelle beendet den Lauf vor weiteren Änderungen. So kann eine ältere Veröffentlichung nicht stillschweigend einen neueren Datenbankstand ignorieren.
Bereits angewendete Dateien bleiben unverändert. Eine spätere Korrektur bekommt eine weitere Kennung. Auch eine scheinbar harmlose Bearbeitung an Leerzeichen oder Zeilenenden verändert bei der hier gewählten Byteprüfung den Hash. Das ist ein bewusst strenger Vertrag für veröffentlichte Artefakte. Legen Sie einheitliche Zeilenenden im Projekt fest und prüfen Sie das fertige Veröffentlichungspaket. Ein Hash ist dabei ein Konsistenznachweis. Er ersetzt weder berechtigte Codefreigaben noch eine Signatur gegen einen Angreifer, der Programm und Datenbank gemeinsam verändern könnte.
Transaktionsverhalten für die konkrete Datenbank festlegen
Das Beispiel verwendet ausdrücklich SQLite. Der Ablauf startet seine Schreibtransaktion mit BEGIN IMMEDIATE. Laut SQLite-Transaktionsdokumentation kann dieser Start an einem bereits aktiven Schreiber scheitern. Der Runner beginnt dann keine zweite parallele Änderung. Für den Aufruf ist eine begrenzte Wartezeit eingestellt, damit ein blockiertes Wartungsfenster einen erkennbaren Ausgang erhält.
Eine vergleichbare PHP-Oberfläche macht Datenbankprodukte nicht transaktional gleich. Die PDO-Dokumentation und die MySQL-Dokumentation zu impliziten Commits erläutern entsprechende DDL-Grenzen. Übertragen Sie die hier geprüfte gemeinsame Rücknahme von Schemaänderung und Registereintrag daher nicht ungeprüft auf MySQL. Ermitteln Sie für das tatsächliche System, welche Operationen eine Transaktion beenden und welche Wiederanlaufstrategie dafür vorgesehen ist.
Das vollständige ausführbare Beispiel
Die folgende Datei heißt migrate.php. Sie enthält den Migrationsbestand und die Ausführungsfunktion. Der direkte Aufruf ist als Kommandozeilenwerkzeug vorgesehen. Ein fehlender Datenbankpfad wird abgelehnt, damit ein Tippfehler nicht versehentlich eine leere SQLite-Datei erzeugt. Die SQL-Texte stammen aus dem freigegebenen Projektbestand. Das Werkzeug ist kein Endpunkt zur Ausführung von SQL aus Formularen oder fremden Dateien.
<?php
declare(strict_types=1);
function projectMigrations(): array {
return [
'001_tasks' => <<<'SQL'
CREATE TABLE tasks (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL CHECK(length(trim(title)) > 0)
);
SQL,
'002_review_state' => <<<'SQL'
ALTER TABLE tasks ADD COLUMN review_state TEXT NOT NULL
DEFAULT 'unreviewed'
CHECK(review_state IN ('unreviewed', 'approved'));
CREATE INDEX tasks_review_state_id ON tasks(review_state, id);
SQL,
];
}
function migrate(PDO $db, array $migrations): array {
if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) !== 'sqlite') {
throw new InvalidArgumentException('Dieses Beispiel benötigt SQLite.');
}
foreach ($migrations as $id => $sql) {
if (!is_string($id) || !preg_match('/^[0-9]{3}_[a-z0-9_]+$/D', $id)
|| !is_string($sql) || trim($sql) === '') {
throw new InvalidArgumentException('Ungültige Migrationsdefinition.');
}
}
ksort($migrations, SORT_STRING);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec('BEGIN IMMEDIATE');
try {
$db->exec('CREATE TABLE IF NOT EXISTS schema_migrations (
id TEXT PRIMARY KEY,
checksum TEXT NOT NULL CHECK(length(checksum) = 64),
applied_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
)');
$applied = $db->query('SELECT id, checksum FROM schema_migrations')
->fetchAll(PDO::FETCH_KEY_PAIR);
foreach ($applied as $id => $checksum) {
if (!array_key_exists($id, $migrations)
|| !hash_equals($checksum, hash('sha256', $migrations[$id]))) {
throw new RuntimeException('Unbekannter oder veränderter Stand: ' . $id);
}
}
$record = $db->prepare('INSERT INTO schema_migrations (id, checksum)
VALUES (:id, :checksum)');
$executed = [];
foreach ($migrations as $id => $sql) {
if (array_key_exists($id, $applied)) continue;
$db->exec($sql);
$record->execute(['id' => $id, 'checksum' => hash('sha256', $sql)]);
$executed[] = $id;
}
$db->exec('COMMIT');
return $executed;
} catch (Throwable $failure) {
try {
$db->exec('ROLLBACK');
} catch (Throwable $rollbackFailure) {
error_log('SQLite-Rücknahme prüfen: ' . $rollbackFailure->getMessage());
}
throw $failure;
}
}
if (realpath($_SERVER['SCRIPT_FILENAME'] ?? '') === __FILE__) {
if (PHP_SAPI !== 'cli') {
http_response_code(404);
exit;
}
if ($argc !== 2 || !is_file($argv[1])) {
fwrite(STDERR, "Aufruf: php migrate.php /pfad/zur/vorhandenen.sqlite\n");
exit(64);
}
try {
$db = new PDO('sqlite:' . realpath($argv[1]));
$db->exec('PRAGMA busy_timeout = 3000');
$ids = migrate($db, projectMigrations());
echo json_encode(['ausgeführt' => $ids], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR), "\n";
} catch (Throwable $failure) {
fwrite(STDERR, 'Migration fehlgeschlagen: ' . $failure->getMessage() . "\n");
exit(1);
}
}
Ein Aufruf nach abgeschlossener Vorbereitung sieht beispielsweise so aus:
php migrate.php /pfad/zur/vorhandenen.sqlite
Das Ergebnis nennt ausschließlich die in diesem Lauf ausgeführten Kennungen. Eine leere Liste ist bei einer korrekten Wiederholung erwartbar. Prüfen Sie zusätzlich den Prozessstatus: Ein abgewiesener Lauf liefert einen Fehlerstatus und darf in einer Veröffentlichungskette keinen anschließenden Start des neuen Programms auslösen. Das Beispiel aktiviert keinen automatischen Zugriff auf eine Kundendatenbank.
Die Vorprüfung vollständig vor neue Schritte setzen
Der Runner vergleicht zuerst alle bereits protokollierten Kennungen mit dem mitgelieferten Bestand. Fehlt eine bekannte Kennung oder stimmt ihr Hash nicht mehr, endet die Transaktion. Erst danach werden noch offene Schritte ausgeführt. Diese Reihenfolge verhindert einen ungünstigen Zwischenzustand: Eine neue Migration darf nicht bereits angewendet werden, bevor eine später überprüfte alte Datei als verändert auffällt.
Die Reihenfolge des PHP-Arrays ist für das Ergebnis unerheblich, weil die geprüften Kennungen sortiert werden. Die dreistellige Nummerierung ist eine Projektkonvention dieses kleinen Beispiels. Bei größeren Beständen benötigen Sie einen dauerhaft eindeutigen Ordnungsvertrag und ein Verfahren für parallel entwickelte Änderungen. Ein automatisches Umsortieren veröffentlichter Schritte wäre dafür ungeeignet. Prüfen Sie Konflikte vor dem Zusammenführen des Pakets und übernehmen Sie anschließend genau dieses geprüfte Artefakt.
Bestehende Zeilen durch eine Erweiterung erhalten
Der zweite Schritt ergänzt review_state mit einem konkreten Standardwert und einer begrenzten Wertemenge. Die Dokumentation zu ALTER TABLE beschreibt die Regeln für neue Spalten und deren Einschränkungen. Im ausgeführten Beispiel besitzen danach beide vorhandenen Zeilen den Wert unreviewed. Ihre ursprünglichen Kennungen und Titel wurden durch eine unabhängige Abfrage vollständig verglichen.
Der zusätzliche Index gehört zum selben Schritt. Seine fachliche Funktion ist hier die vorbereitete Suche nach Prüfstatus. Ob er bei einer bestimmten Datenverteilung tatsächlich nützt, muss separat gemessen werden. Die Migration belegt seine Existenz und die erfolgreiche gemeinsame Anlage. Sie belegt keinen Leistungsgewinn. Damit bleiben strukturelle Abnahme und eine spätere Untersuchung des Abfrageverhaltens nachvollziehbar getrennt.
Fehler nach einer Schemaänderung tatsächlich erproben
Der wichtigste Negativfall enthält zwei Anweisungen. Zuerst wird eine zusätzliche Testspalte angelegt. Danach versucht der Schritt, eine bereits vorhandene Kennung erneut einzufügen. Die zweite Anweisung scheitert tatsächlich. Nach der Rücknahme wurde die Tabelle erneut untersucht: Die Testspalte ist nicht vorhanden, beide Ursprungsdatensätze sind unverändert und das Versionsregister enthält keinen Eintrag für den fehlgeschlagenen Schritt.
Dieser Versuch prüft mehr als das Auftreten irgendeiner Fehlermeldung. Er vergleicht den fachlich relevanten Zustand nach dem Fehler mit dem erwarteten Ausgang. Für eigene Migrationen sollten Sie entsprechend passende Fehlerpunkte auswählen: eine verletzte Bedingung nach einer ersten Änderung, einen unzulässigen Altwert bei einer Konvertierung oder einen Konflikt beim Erzeugen eines eindeutigen Index. Verwenden Sie dafür eine geschützte Testkopie mit kontrollierten Daten und dokumentieren Sie, welche Invarianten erhalten bleiben müssen.

Die Sicherung über ihre Wiederherstellung abnehmen
Vor der Erweiterung erzeugt die Prüfung mit VACUUM INTO eine Sicherungsdatei. Die SQLite-Dokumentation erläutert den konsistenten logischen Stand dieser Kopie und die Anforderungen an das Ziel. Anschließend wird eine weitere Kopie als Wiederherstellungsziel geöffnet. Dort werden Integrität, Ausgangsspalten und sämtliche Testwerte überprüft. Erst diese Wiederherstellungskopie wird erneut migriert. Die eigentliche Sicherung bleibt im alten Stand erhalten.
Ein vorhandener Dateiname allein ist kein Wiederherstellungsnachweis. Zur Betriebsplanung gehören Aufbewahrungsort, Zugriffsmöglichkeit im Fehlerfall und ein klarer Verantwortlicher. Ebenso muss bekannt sein, welche neueren Schreibvorgänge bei einem Rücksprung verloren gingen. Die Sicherung eines Datenbankstands beantwortet keine Fragen zu nachfolgend erzeugten Dateien, externen Nachrichten oder späteren Änderungen anderer Systeme. Stimmen Sie den Wiederanlauf über diese Grenzen hinweg ausdrücklich ab.
Die tatsächlich geprüften Ergebnisse einordnen
Das Prüfprogramm führte 38 Bedingungen aus. Es verwendete eigene SQLite-Dateien mit zwei künstlichen Bestandszeilen. Neben erfolgreichen Übergängen wurden Hashkonflikte, ein älterer Programmstand, ein DDL-Fehler, ein zweiter Schreibzugriff und echte Kommandozeilenaufrufe geprüft. Die Ergebnisse betreffen Datenkonsistenz und Ablaufregeln. Daraus lässt sich keine zugesicherte Sperrdauer für einen großen produktiven Bestand ableiten.
| Geprüfter Fall | Beobachtetes Ergebnis | Folge für den Ablauf |
|---|---|---|
| Erweiterung bestehender Aufgaben | Zwei Zeilen erhalten; neuer Status ungeprüft | Schema und fachlichen Ausgang gemeinsam abnehmen |
| Unveränderte Wiederholung | Keine weitere Kennung ausgeführt | Erfolgreiche Wiederaufnahme ist erkennbar |
| Geänderte alte Migration | Abbruch vor einer neuen Testtabelle | Veröffentlichungsartefakt untersuchen |
| Fehler nach ALTER TABLE | Testspalte und Registereintrag fehlen | Ausgangszustand nach Rücknahme prüfen |
| Zweiter aktiver Schreiber | Sperrfehler vor Migrationsbeginn | Wartungsfenster und andere Prozesse klären |
| Fehlender CLI-Pfad | Fehlerstatus; keine neue Datei | Ziel explizit berichtigen |
Ein Veröffentlichungsfenster als vollständigen Ablauf planen
Legen Sie vor dem Start fest, wann Schreibzugriffe beendet oder kontrolliert begrenzt werden. Ein einzelner Migrationsprozess koordiniert nicht automatisch alle Hintergrundaufgaben. Die SQLite-Erläuterung zur Isolation hilft dabei, Verbindungen und ihre Sichten zu verstehen. Die konkrete Anwendung muss trotzdem ihren eigenen Umgang mit offenen Anfragen, aktiven Lesern und Wartungszuständen festlegen.
Nach der Migration prüfen Sie die wichtigsten tatsächlichen Nutzungswege. Ein erfolgreicher DDL-Befehl sagt beispielsweise noch nicht, ob ein altes Importprogramm weiterhin passende Werte schreibt oder ein neuer Filter ungeprüfte Aufgaben korrekt findet. Halten Sie die erwarteten Ergebnisse vorher fest. Die zuständige Person kann dann anhand begrenzter, konkreter Abnahmeschritte entscheiden, ob die Veröffentlichung fortgesetzt wird. Ein ungünstiges Ergebnis führt zu einer definierten Reaktion und nicht zu improvisierten manuellen SQL-Korrekturen.
Erweitern und späteres Entfernen zeitlich trennen
Eine verträgliche Erweiterung lässt sich häufig in mehrere Veröffentlichungen aufteilen. Zunächst erhält das Schema die zusätzliche Struktur. Danach verwendet ein passender Programmstand sie. Erst wenn alle relevanten Leser und Schreiber nachweislich umgestellt sind, wird eine frühere Struktur entfernt. Diese Reihenfolge macht Abhängigkeiten sichtbar und gibt der Prüfung einen geeigneten Beobachtungsraum. Sie garantiert nicht automatisch einen unterbrechungsfreien Betrieb.
Auch das Zurückspielen älterer Programmdateien verlangt eine Entscheidung. Nach unserem zusätzlichen Statusfeld kann eine ausdrücklich begrenzte alte Leseabfrage weiterhin funktionieren. Nach einer späteren Entfernung oder Umbenennung kann derselbe Rücksprung scheitern. Dokumentieren Sie deshalb für jedes Paket, welche Programmstände zum resultierenden Schema passen. Ein pauschaler Knopf „zurück“ kann diese fachliche und technische Prüfung nicht übernehmen.
| Phase | Zu prüfender Vertrag | Abnahmebeispiel |
|---|---|---|
| Schema erweitern | Bestand bleibt lesbar; neuer Zustand ist fachlich vertretbar | Alte Titel und Kennungen stimmen vollständig überein |
| Neuen Programmstand aktivieren | Leser und Schreiber kennen die Erweiterung | Neue Aufgaben starten tatsächlich ungeprüft |
| Ältere Struktur entfernen | Kein verbleibender Prozess benötigt sie | Exporte, Aufgaben und Wartungswerkzeuge sind geprüft |
Die Identität des Ziels unabhängig bestätigen
Die Prüfung auf einen vorhandenen Dateipfad schützt im Beispiel vor einer bestimmten Verwechslung: Ein falscher neuer Name erzeugt keine leere Datenbank. Eine bereits vorhandene fremde SQLite-Datei kann damit allein nicht zuverlässig erkannt werden. Der Runner ist bewusst kein allgemeines Verfahren zur Identifizierung einer Anwendung. Für die tatsächliche Veröffentlichung brauchen Sie einen zusätzlichen überprüfbaren Zielvertrag, etwa eine eindeutig zugeordnete Projektkonfiguration und einen bekannten erwarteten Ausgangsstand.
Vergleichen Sie diese Angaben vor dem Wartungsfenster mit einem unabhängigen Nachweis. Dazu können eine bestehende Anwendungskennung, die erlaubte Umgebung und ein bekanntes Schema gehören. Ein plausibel klingender Dateiname reicht dafür kaum aus. Auch die Berechtigung zum Öffnen einer Datei beweist noch nicht, dass sie für diesen Auftrag das richtige Ziel ist. Erfassen Sie den geprüften Zielbezug im Ablaufprotokoll und sorgen Sie dafür, dass ein neu gestarteter Prozess dieselbe verbindliche Konfiguration verwendet.
Änderungen der Bedeutung von einer Spaltenergänzung unterscheiden
Unser Übergang weist alten Aufgaben einen ausdrücklich ungeprüften Status zu. Andere Projekte verändern dagegen die Bedeutung eines vorhandenen Werts: Aus einer frei eingegebenen Kategorie wird eine begrenzte Auswahl oder aus einer Textangabe ein normiertes Datum. Dafür genügt der Nachweis einer passenden Spalte nicht. Vorab muss sichtbar sein, welche Altwerte bereits gültig sind, welche eindeutig überführt werden können und welche eine Entscheidung benötigen.
Behandeln Sie mehrdeutige Werte als eigenen Arbeitsbestand. Eine automatische Umwandlung von „03/04“ in ein bestimmtes Datum würde ohne bekannten Eingabevertrag eine Information erfinden. Für solche Fälle ist ein dokumentierter Prüfstatus häufig brauchbarer als ein technisch bequemer Ersatzwert. Planen Sie außerdem, wie die fachliche Stelle diese offenen Fälle findet und korrigiert. Ein erfolgreich ausgeführtes UPDATE beweist nur die technische Änderung. Die Tragfähigkeit ihrer Bedeutung benötigt eine davon passende Abnahme.
Parallel entwickelte Migrationspakete vor dem Betrieb zusammenführen
Wenn zwei Arbeitszweige gleichzeitig eine nächste Kennung vergeben, kann jeder für sich funktionieren und gemeinsam trotzdem einen Konflikt erzeugen. Prüfen Sie beim Zusammenführen den vollständigen Bestand: Sind Kennungen eindeutig, hängt ein Schritt vom Ergebnis eines anderen ab und wurde eine veröffentlichte Datei verändert? Die endgültige Reihenfolge gehört zum getesteten Paket. Sie sollte nicht erst auf dem Zielsystem anhand zufälliger Dateizeiten entstehen.
Ein sinnvoller Integrationsfall beginnt mit dem letzten gemeinsamen Datenbankstand und führt genau den zusammengeführten Bestand aus. Zusätzlich wird ein schon weiter entwickelter Stand geöffnet, um die Vorprüfung eines älteren Pakets zu beobachten. In unserem kleinen Versuch wird diese zweite Richtung tatsächlich abgewiesen. Für ein Team schafft das einen klaren Anlass zur Klärung. Es ist geeigneter, den Konflikt vor der Veröffentlichung aufzulösen, als auf dem Server neue Prüfsummen in das Register einzutragen und dadurch die Abweichung unsichtbar zu machen.
Den begrenzten Runner in einen überprüften Betriebsweg einbetten
Das Register beschreibt bereits ausgeführtes SQL. Es enthält keinen universellen Vergleich aller tatsächlichen Tabellen mit einem Sollschema. Wer anschließend außerhalb des Verfahrens eine Spalte verändert, kann deshalb eine Abweichung erzeugen, obwohl die gespeicherten Hashes weiterhin passen. Ergänzen Sie für ein vorhandenes System passende Schema- und Datenprüfungen. Beschränken Sie direkte Änderungen organisatorisch und halten Sie einen nachvollziehbaren Weg für notwendige Sonderfälle bereit.
Die Migrationstexte sind außerdem vertrauenswürdiger Projektcode. Der Runner untersucht sie nicht mit einem SQL-Parser auf eigene Transaktionsbefehle oder fachlich gefährliche Löschungen. Solche Befehle gehören in die Codeprüfung vor dem Lauf. Nach einer Ausnahme wird die Verbindung für den fehlgeschlagenen Vorgang verworfen und der Zustand geprüft. Eine automatisch erzeugte Reparatur oder ein blindes Weiterlaufen wäre aus dem Beispiel nicht begründbar. Der Nutzen liegt in dem engen, tatsächlich geprüften Vertrag und seiner bewussten Einbettung in den Projektablauf.
Einen großen Datenumbau gesondert entwerfen
Die kleine Statusergänzung benötigt im Beispiel keine lang laufende fachliche Bereinigung. Ein umfangreicher Umbau kann andere Grenzen haben. Ermitteln Sie deshalb vor einer Übertragung auf große Bestände, wie viel Arbeit tatsächlich in einer Transaktion liegt und welche anderen Prozesse warten müssten. Die 38 Bedingungen dieser Demonstration sind keine Lastprüfung. Eine zusätzliche Prüfung mit einer geeigneten Datenverteilung und realistischen konkurrierenden Abläufen gehört zu einer solchen Erweiterung.
Falls eine Bereinigung absichtlich in Portionen aufgeteilt wird, benötigt auch ihr Fortschritt einen verlässlichen Vertrag. Ein fortgesetzter Lauf muss erkennen, welche Datensätze erfolgreich behandelt wurden und welche noch offen sind. Besonders wichtig ist die gemeinsame Absicherung von Datenänderung und Fortschrittsnachweis. Wird nur einer dieser beiden Stände gespeichert, kann ein Wiederanlauf Arbeit überspringen oder wiederholen. Eine stabile Kennung, verständliche Wiederholungsregeln und eine nachprüfbare Zahl offener Fälle helfen beim Entwurf. Ein bloßer Prozentbalken ohne diesen Bezug wäre dafür ungeeignet.
Checkliste für einen nachvollziehbaren Migrationslauf
- Fachlichen Ausgang und erlaubten Zielzustand schriftlich festlegen.
- Aktuelle Datenbank, Bibliotheksversion und Veröffentlichungsartefakt eindeutig zuordnen.
- Sicherung erzeugen und ihre Wiederherstellung an einer unabhängigen Kopie prüfen.
- Bestehende Datenwerte und alle relevanten Leser sowie Schreiber inventarisieren.
- Bereits ausgeführte Kennungen und Prüfsummen vor neuen Änderungen vollständig vergleichen.
- Mindestens einen Fehler nach einer ersten wirksamen Änderung kontrolliert erproben.
- Ausgang nach Rücknahme anhand von Schema, Daten und Versionsregister abnehmen.
- Sperrverhalten, Wartezeit und konkurrierende Prozesse für das Wartungsfenster klären.
- Prozessstatus und tatsächlich ausgeführte Kennungen in der Veröffentlichungskette auswerten.
- Nachprüfung, Abbruchentscheidung und verantwortete Wiederaufnahme vorher vereinbaren.
Mit einer echten Bestandsfrage beginnen
Der nächste sinnvolle Schritt besteht darin, eine konkrete kommende Änderung als überprüfbaren Übergang zu beschreiben. Wählen Sie dafür ein kleines Feld, einen begrenzten Index oder eine eindeutig definierte Datenbereinigung. Erstellen Sie eine Kopie mit passenden Randfällen und formulieren Sie die erhaltenen Eigenschaften zuerst. Anschließend können Code, Sicherung und Fehlerbehandlung genau gegen diese Bedingungen geprüft werden.
Der ausführbare Runner ist dafür ein überschaubares Lernwerkzeug. Für ein vorhandenes Projekt sind außerdem dessen Datenbankprodukt, Migrationstechnik und Freigabewege maßgeblich. Entscheidend bleibt die belastbare Verbindung zwischen nachvollziehbarer Änderung und geprüftem Datenzustand. Sie ermöglicht eine fachlich begründete Veröffentlichung und eine Wiederaufnahme, deren Auswirkungen vor dem ersten produktiven Schreibzugriff verstanden sind.








