Tabelle in Live-Produktionsdatenbanken ändern


24

Wie gehen die meisten "populären" (MySQL, Postgres ...) Datenbanksysteme damit um, Tabellen in Live-Produktionsdatenbanken zu ändern (wie das Hinzufügen, Löschen oder Ändern des Spaltentyps)?

Ich weiß, dass der richtige Weg ist, alle geplanten Ausfallzeiten zu sichern und dann die Änderungen vorzunehmen.

Aber ... unterstützt ein aktuelles Datenbanksystem diese Aktionen "online", ohne irgendetwas zu stoppen? (Möglicherweise werden nur die Abfragen verzögert, die auf eine Spalte verweisen, die gerade geändert / gelöscht wird.)

Und was passiert, wenn ich gerade ALTER TABLE...eine laufende Datenbank aufrufe? Hört alles auf, wenn dies passiert? Können Daten beschädigt werden? etc.

Auch hier beziehe ich mich hauptsächlich auf Postgres oder MySQL, da dies das ist, was mir begegnet.

(Und ja, wann immer ich das tun musste, bevor ich es "richtig" gemacht habe, Dinge sichern, Stillstand einplanen usw. ... aber ich möchte nur wissen, ob es möglich ist, diese und ähnliche Dinge "schnell und schnell" zu tun dirty "oder wenn es ein DB-System gibt, das tatsächlich" quick, live and dirty "-Schemaänderungen unterstützt)


Jemand hat gerade eine Online-Schemaänderung für MySQL aus dem Facebook-Skript vorgeschlagen (mit einem Tutorial hier und einer Quelle hier ) ... scheint ein guter Weg zu sein, um eine Reihe von "hackigen" Methoden zu automatisieren ... hat es jemals jemand verwendet etwas ähnliches produktion?


3
Hinweis: Der angegebene "richtige Weg" bezieht sich auf MySQL und nicht auf PostgreSQL. Der "richtige Weg" in PostgreSQL ist in der Regel sehr einfach, obwohl er involviert sein kann. Verwendung von pg_reorgkann bei den schwierigeren Szenarien helfen.
Sean

Ich hätte gerne ein detailliertes Video dazu gemacht, in dem jemand so viele Strategien wie möglich erklärt.
Sandeepan Nath

Antworten:


22

Wenn Sie ALTER TABLEin PostgreSQL ein ausstellen , wird eine ACCESS EXCLUSIVESperre verwendet, die alles blockiert, einschließlichSELECT . Jedoch kann diese Sperre kurz sein recht , wenn die Tabelle nicht neu zu schreiben erfordert, keine neue UNIQUE, CHECKoder FOREIGN KEYEinschränkungen müssen teure Voll Tabellen - Scans , um zu überprüfen, usw.

Im Zweifelsfall können Sie es in der Regel einfach ausprobieren! Alle DDLs in PostgreSQL sind transaktionell, daher ist es in Ordnung, eine abzubrechen, ALTER TABLEwenn sie zu lange dauert und andere Abfragen zu halten beginnt. Die für verschiedene Befehle erforderlichen Sperrstufen sind auf der Sperrseite dokumentiert .

Einige normalerweise langsame Vorgänge können beschleunigt werden, um eine sichere Ausführung ohne Ausfallzeiten zu gewährleisten. Zum Beispiel, wenn Sie Tabelle haben tund Sie möchten Spalte ändern customercode integer NOT NULLzu , textweil der Kunde alle Kundencodes nun mit einem entschieden hat , beginnen müssen X, könnten Sie schreiben:

ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );

... aber das würde die ganze Tabelle für das Neuschreiben sperren. Das gleiche gilt für das Hinzufügen einer Spalte mit einem DEFAULT. Es kann in ein paar Schritten durchgeführt werden, um die lange Sperre zu vermeiden, aber Anwendungen müssen in der Lage sein, mit der vorübergehenden Duplizierung umzugehen:

ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;

Dies wird nur verhindern , schreibt an twährend des Prozesses; Der Name der Sperre EXCLUSIVEtäuscht insofern, als er alles außer ausschließtSELECT . Der ACCESS EXCLUSIVEModus ist der einzige, der absolut alles ausschließt. Siehe Sperrmodi . Es besteht das Risiko, dass dieser Vorgang aufgrund des von der erforderlichen Sperrenaktualisierung ein Deadlock-Rollback verursachen kann. Im ALTER TABLEschlimmsten Fall müssen Sie ihn jedoch erneut ausführen .

Sie können sogar , dass Schloss und machen die ganze Sache leben , indem Sie eine Triggerfunktion auf verhindern , tdass immer dann , wenn ein INSERToder UPDATEkommt, automatisch bevölkert customercode_newvon customercode.

Es gibt auch integrierte Tools wie CREATE INDEX CONCURRENTLYund, mit denen ALTER TABLE ... ADD table_constraint_using_indexDatenbankadministratoren die Dauer exklusiver Sperren reduzieren können, indem sie langsamer und paralleler arbeiten.

Das pg_reorgTool oder sein Nachfolger pg_repackkann auch für einige Tabellenumstrukturierungsvorgänge verwendet werden.


1
Der Schlüssel zu dem, was @Craig sagte, war: "Wenn es nicht notwendig ist, es neu zu schreiben." Die Verwendung von ALTER TABLE t ADD COLUMN i INTist eine schnelle Operation (in der Regel <1 ms), sobald die Sperre aktiviert wurde. Durch das Erlangen der Sperre können jedoch Verbindungen in die Warteschlange gestellt werden, daher ist es nicht "kostenlos" ... obwohl es weltweit besser ist als das, was Sie in MySQL tun müssen. Das Hinzufügen einer NOT NULLEinschränkung ist schwieriger und nichts für schwache Nerven.
Sean

Es scheint Konsens zu sein, pg_repackder der verbesserte Nachfolger von ist pg_reorg.
Erwin Brandstetter

Eine gute Antwort in Bezug auf das Hinzufügen einer Spalte mit einem Standardwert (oder berechneten Wert) besteht darin, weniger "blockierend" eine ganze neue Tabelle zu erstellen, die alte Tabelle zum Einfügen / Aktualisieren / Löschen zu blockieren, aber das Auswählen und Auffüllen der neuen zuzulassen. Stellen Sie schließlich eine kurze exklusive Sperre für die alte Tabelle zum Auswählen, Löschen und Umbenennen von Neu in Alt aus. Abhängig von Ihrem Szenario können Sie auch die neuen zu füllen beginnen , ohne Einsätze in den alten und Problem , die exklusive Sperre nur während der Blockierung der diff Lösung (hoffentlich nur ein paar neue Datensätze einfügen)
jean

7

Percona hat ein eigenes Tool für die Durchführung von Online-Schemaänderungen entwickelt

Das Tool heißt pt-online-schema-change

Es handelt sich um Auslöser. Lesen Sie die Dokumentation daher sorgfältig durch.

Nach der Dokumentation sind die wichtigsten Operationen durchgeführt

  • Überprüfung der geistigen Gesundheit
  • Chunking
  • Online-Schemaänderung
    • Temporäre Tabelle erstellen und ändern
    • Erfassen Sie Änderungen von der Tabelle in die temporäre Tabelle
    • Kopieren Sie Zeilen aus der Tabelle in die temporäre Tabelle
    • Synchronisieren Sie die Tabelle und die temporäre Tabelle
    • Tauschen Sie die Tabelle und die temporäre Tabelle aus / benennen Sie sie um
    • Aufräumen

Vielen Dank, scheint wie eine "soldatisierte" Version von Facebook Ansatz, der ich mehr vertrauen könnte ...
NeuronQ

pt-online-schema-change ist definitiv die bevorzugte Methode, wenn Sie Ihren eigenen MySQL-Server betreiben. Ab Percona Tools 2.2 unterstützen sie (leider) RDS / Aurora unter AWS nicht. pt-online-schema-change fügt einen Trigger in die Quelltabelle ein, um Zeilen (niedrige Priorität für MyISAM) in das Ziel table_temp zu kopieren, und löscht eine einzelne Schnellverriegelung und benennt sie am Ende um, wenn alle Zeilen zwischen Quelle und Ziel synchronisiert sind Tabellen.
Phpguru

6

Das Herunterfahren des Systems und die gleichzeitige Durchführung aller Änderungen kann sehr riskant sein. Wenn etwas schief geht und dies häufig der Fall ist, gibt es keinen einfachen Weg zurück.

Als Agile-Entwickler muss ich manchmal Tabellen ohne Ausfallzeiten umgestalten, da diese Tabellen geändert und gelesen werden.

Der folgende Ansatz weist ein geringes Risiko auf, da die Änderung in mehreren risikoarmen Schritten ausgeführt wird, die sich sehr einfach zurücksetzen lassen:

  • Stellen Sie sicher, dass alle Module, die auf die Tabelle zugreifen, mit automatisierten Tests abgedeckt sind.
  • Erstellen Sie eine neue Tabelle. Ändern Sie alle Prozeduren, die die alte Tabelle ändern, so dass sie sowohl alte als auch neue Tabellen ändern.
  • Migrieren Sie vorhandene Daten in eine neue Struktur. Führen Sie dies in kleineren Stapeln durch, damit die Gesamtleistung des Servers nicht ernsthaft beeinträchtigt wird.
  • Stellen Sie sicher, dass die Datenmigration erfolgreich war.
  • Leiten Sie einige der Auswahlverfahren aus der alten Tabelle auf die neuen um. Verwenden Sie automatisierte Tests, um sicherzustellen, dass die geänderten Module noch korrekt sind. Stellen Sie sicher, dass ihre Leistung akzeptabel ist. Stellen Sie die geänderten Prozeduren bereit.
  • Wiederholen Sie den vorherigen Schritt, bis alle Berichte die neue Tabelle verwenden.
  • Ändern Sie die Prozeduren, mit denen die Tabellen geändert werden, so dass sie nur auf die neue Tabelle zugreifen.
  • Archivieren Sie die alte Tabelle und entfernen Sie sie aus dem System.

Wir haben diesen Ansatz viele Male verwendet, um große Live-Produktionstabellen ohne Ausfallzeiten ohne Probleme zu ändern.


3
großartig ... aber genau das ist die Art von "Schmerz", die ich vermeiden
möchte

@NeuronQ " Es gibt keinen einfachen Weg zurück " - es gibt in Postgres: Einfach alles in eine Transaktion stecken und rollbackwenn etwas schief geht.
a_horse_with_no_name

2

Ja, in vielen modernen Datenbanken können Sie einfach eine Spalte hinzufügen oder die Eigenschaften einer Spalte ändern, z. B. nullable hinzufügen oder entfernen.

Wenn Sie eine Spalte löschen, gehen Daten verloren, es besteht jedoch keine große Angst vor Korruption.



-1

Um die Frage zu beantworten, was mit einer ALTER TABLEAnweisung passiert , hängt es vom Umfang Ihrer Änderungen ab. In bestimmten Fällen erstellt die Engine beim Hinzufügen einer neuen Spalte, zumindest in MS SQL Server, eine temporäre Kopie der Tabelle, während die neue Tabellendefinition erstellt wird, und fügt die Daten dann wieder dort ein. Für die Dauer der Änderung wäre die Tabelle somit für Benutzer nicht zugänglich.

Ein Beispiel für die spezifischen Vorgänge für MSSQL-Server finden Sie hier: http://support.microsoft.com/kb/956176/en-us

Ich würde davon ausgehen, dass andere RMDBs über ähnliche Methoden verfügen, obwohl die genaue Implementierung anhand der Herstellerdokumentation überprüft werden müsste.


-1 Dies ist für SQL Server völlig falsch: "Wenn Sie zumindest in MS SQL Server eine neue Spalte hinzufügen, erstellt die Engine eine temporäre Kopie der Tabelle, während sie die neue Tabellendefinition erstellt, und fügt dann die Daten wieder ein
AK

@AlexKuznetsov - Ich dachte, die vorherige Zeile sowie die Verknüpfung mit einigen der aufgeführten Fälle würden klarstellen, dass dies nicht immer der Fall ist. Ich habe den Satz geändert, um dies besser widerzuspiegeln.
SchmitzIT

1
Sie erwähnen das Verhalten der GUI, SSMS, nicht das Verhalten von SQL Server selbst. Wenn Sie Ihrem Link folgen, wird empfohlen, T-SQL direkt zu verwenden, um DDL-Änderungen vorzunehmen. SSMS ist kein sehr gutes Tool zum Ändern der DDL.
AK

@AlexKuznetsov - Ich habe den Artikel gelesen und gesagt, dass es Risiken gibt, aber nicht als Entmutigung. Auf jeden Fall habe ich den Artikel nicht für das GUI-Bit verlinkt, sondern als Hinweis auf einige der Vorgänge, die aufgrund von Änderungen in der zugrunde liegenden Datenstruktur zu einer ALTER-Anweisung führen, die zur Erstellung einer temporären Tabelle führt. Ich habe nicht getestet, ob genau das Gleiche gilt, wenn die Anweisung direkt von T-SQL ausgegeben wird, aber ich denke, der Prozess ist ziemlich ähnlich und SL Server erledigt die Arbeit hinter den Kulissen.
SchmitzIT

Sie können Profiler starten, die Anweisung ALTER TABLE direkt ausführen und sehen, was gerade passiert. Anschließend können Sie über ein Dialogfeld eine Tabelle ändern und selbst sehen, welche Befehle ausgeführt werden.
AK
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.