Wann können Sie alte Datenbankspalten sicher löschen? Die Contract-Phase des Expand-Contract-Patterns
Sie haben den gesamten Anwendungscode auf das neue Spaltenformat migriert. Das Deployment lief reibungslos. Keine Fehler in den Logs. Ihr Team ist bereit, das alte Schema aufzuräumen und zur nächsten Funktion überzugehen.
Aber sollten Sie diese Spalte jetzt sofort löschen?
Die Antwort ist fast immer nein. Das zu frühe Löschen alter Datenbankstrukturen ist eine der häufigsten Ursachen für Produktionsausfälle, die scheinbar aus dem Nichts kommen. Ein Batch-Job, der nur einmal im Monat läuft, eine Reporting-Abfrage, die jemand vor sechs Monaten geschrieben hat, oder ein Legacy-Service, der nur während der Quartalsabschlussverarbeitung aktiv wird – all das kann still scheitern, bis der Moment kommt, in dem es tatsächlich ausgeführt werden muss.
Die letzte Phase des Expand-Contract-Patterns wird Contract-Phase genannt. Der Name leitet sich von der Idee ab, nicht mehr genutzte Strukturen zu verkleinern oder zu entfernen. Aber um diese Phase zu erreichen, reicht es nicht aus, nur zu bestätigen, dass Ihre Hauptanwendung umgestellt hat.
Wer greift noch auf die alte Struktur zu?
Bevor Sie etwas löschen, müssen Sie eine Frage beantworten: Wer liest oder schreibt noch auf das alte Schema?
Ihre primäre Anwendung ist vielleicht schon umgestiegen. Aber es könnte andere Konsumenten geben, an die Sie nicht gedacht haben:
- Ein nächtlicher Batch-Job, der noch die alte Spalte referenziert
- Manuelle Abfragen des Data-Teams für Ad-hoc-Analysen
- Ein Reporting-System, das monatliche PDFs mit der alten Tabelle erstellt
- Ein internes Tool, das vor sechs Monaten deployed wurde und nicht aktualisiert wurde
- Eine Drittanbieter-Integration, die Daten im alten Format sendet
Diese Abhängigkeiten übersieht man leicht, weil sie nicht dem gleichen Deployment-Zyklus wie Ihre Hauptanwendung folgen. Sie sind vielleicht nicht einmal im selben Repository. Manche sind gar kein Code – es könnten SQL-Skripte sein, die auf dem Laptop eines Kollegen gespeichert sind.
Wie man versteckte Abhängigkeiten erkennt
Der einfachste Weg, diese Abhängigkeiten zu finden, ist ein Blick in Ihre Datenbank-Logs. Datenbanken wie PostgreSQL, MySQL und Oracle zeichnen alle ausgeführten Abfragen auf. Sie können nach Abfragen filtern, die die zu entfernende Spalte oder Tabelle referenzieren.
Das folgende Flussdiagramm fasst den Entscheidungsprozess zusammen, ob es sicher ist, eine alte Spalte zu löschen:
Wenn Ihre Datenbank standardmäßig keine Abfragen loggt, können Sie dies temporär aktivieren. PostgreSQL bietet pg_stat_statements zur Verfolgung von Abfragestatistiken. MySQL hat das Performance Schema. Beide können Ihnen zeigen, welche Abfragen noch auf die alte Struktur zugreifen.
Ein zweiter Ansatz ist die Überwachung von Fehlern nach dem Umstieg Ihrer Anwendung. Wenn etwas immer noch versucht, in die alte Spalte zu schreiben, werden Sie wahrscheinlich Fehler in den Anwendungslogs sehen. Aber das erfasst nur aktive Konsumenten. Ein Skript, das nur einmal im Quartal läuft, könnte monatelang keinen Fehler auslösen.
Deshalb ist die Wartezeit vor dem Löschen so wichtig. Manche Teams warten einen vollständigen Deployment-Zyklus – typischerweise zwei Wochen, nachdem alle Anwendungen umgestellt haben. Andere warten länger, besonders wenn es manuelle Abfragen oder Reports gibt, die von nicht-technischen Teams ausgeführt werden. Es gibt keine universelle Regel, aber je mehr unkontrollierte Abhängigkeiten Sie haben, desto länger sollten Sie warten.
Das eigentliche Löschen
Sobald Sie sicher sind, dass keine Abhängigkeiten mehr bestehen, können Sie mit dem Löschen fortfahren. Die SQL-Befehle sind unkompliziert:
Hier ist ein praktisches Beispiel für das SQL, das Sie ausführen würden, zusammen mit einer Abfrage, um zu überprüfen, dass keine anderen Datenbankobjekte mehr von der Spalte abhängen:
-- First, check for any views, functions, or triggers that reference the column
SELECT DISTINCT
OBJECT_SCHEMA,
OBJECT_NAME,
OBJECT_TYPE
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%old_column_name%'
UNION
SELECT
TABLE_SCHEMA,
TABLE_NAME,
'VIEW'
FROM INFORMATION_SCHEMA.VIEWS
WHERE VIEW_DEFINITION LIKE '%old_column_name%';
-- Once confirmed safe, drop the column
ALTER TABLE users DROP COLUMN old_legacy_status;
-- Clean up any indexes that only existed for the old column
DROP INDEX IF EXISTS idx_old_status ON users;
Führen Sie zuerst die Abhängigkeitsprüfung durch, dann fahren Sie mit dem Löschen fort. Wenn die Prüfung Zeilen zurückgibt, haben Sie einen versteckten Konsumenten gefunden, der aktualisiert werden muss, bevor Sie sicher löschen können.
- Für eine Spalte:
ALTER TABLE ... DROP COLUMN - Für eine Tabelle:
DROP TABLE - Für eine Einschränkung:
ALTER TABLE ... DROP CONSTRAINT
Aber die Reihenfolge ist wichtig. Löschen Sie zuerst die Spalten oder Tabellen, die am wahrscheinlichsten nicht mehr verwendet werden, und warten Sie dann ein paar Tage, bevor Sie den Rest löschen. Dieser gestaffelte Ansatz gibt Ihnen ein Sicherheitsnetz. Wenn nach der ersten Löschung etwas kaputtgeht, haben Sie noch Zeit zu reagieren, bevor die kritischeren Strukturen verschwunden sind.
Vergessen Sie nicht Indizes und Trigger
Eine Sache, die oft übersehen wird, ist die Bereinigung verwandter Datenbankobjekte. Indizes, die nur für die alte Spalte existierten, sollten gelöscht werden. Trigger, die die alte Tabelle referenzieren, sollten entfernt werden. Wenn Sie diese zurücklassen, sammelt Ihre Datenbank Ballast an, der Schreibvorgänge verlangsamen und zukünftige Migrationen erschweren kann.
Eine kurze Checkliste, bevor Sie die Contract-Phase abschließen:
- Bestätigen Sie, dass keine aktiven Abfragen die alte Struktur berühren (prüfen Sie Logs über mindestens einen vollständigen Zyklus)
- Verifizieren Sie, dass alle Batch-Jobs, Reports und manuellen Skripte aktualisiert wurden
- Löschen Sie Indizes, die nur der alten Spalte dienten
- Entfernen Sie Trigger, die die alte Tabelle referenzieren
- Löschen Sie in Stufen: zuerst das am wenigsten riskante, warten, dann weitermachen
- Überwachen Sie Anwendungsfehler für 24-48 Stunden nach jeder Löschung
Die eigentliche Erkenntnis
Bei der Contract-Phase geht es nicht um Geschwindigkeit. Es geht um Sicherheit. Das zu frühe Löschen alter Schemata birgt ein Risiko, das schwer zu erkennen ist, bis es zu spät ist. Die zusätzliche Wartezeit ist keine verschwendete Zeit – sie ist Ihr Sicherheitspuffer gegen versteckte Abhängigkeiten, von denen Sie nicht wussten, dass sie existieren.
Sobald das alte Schema weg ist, ist das Expand-Contract-Pattern abgeschlossen. Sie haben die neue Struktur hinzugefügt, alle Konsumenten migriert und die alte sicher entfernt, ohne einen Produktionsausfall zu verursachen. Das ist der ganze Sinn des Patterns: Datenbankänderungen so sicher zu machen, dass Ihr Team keine Angst vor ihnen hat.