Mit Spanner lassen sich Schemas ohne Ausfallzeit aktualisieren. Das Schema einer vorhandenen Datenbank kann mit verschiedenen Methoden aktualisiert werden:
In der Google Cloud Console
Senden Sie auf der Seite Spanner Studio einen
ALTER TABLE-Befehl.Klicken Sie auf der Seite „Datenbankübersicht“ oder „Tabellenübersicht“ auf Spanner Studio, um auf die Seite Spanner Studio zuzugreifen.
gcloud spanner-Befehlszeilentool verwendenSenden Sie einen
ALTER TABLE-Befehl mit dem Befehlgcloud spanner databases ddl update.projects.instances.databases.updateDdlREST API verwendenUpdateDatabaseDdlRPC API verwenden
Unterstützte Schemaaktualisierungen
Für das Schema einer vorhandenen Datenbank unterstützt Spanner folgende Arten von Aktualisierungen:
- Ein benanntes Schema hinzufügen oder löschen.
- Erstellen einer neuen Tabelle Spalten in neuen Tabellen können
NOT NULLsein. - Eine Tabelle löschen, sofern keine anderen Tabellen damit verschränkt sind und die zu löschende Tabelle keine sekundären Indexe hat.
- Erstellen oder Löschen einer Tabelle mit einem Fremdschlüssel.
- Hinzufügen oder entfernen eines Fremdschlüssels aus einer vorhandenen Tabelle.
- Eine Nicht-Schlüsselspalte in eine Tabelle aufnehmen. Neue Nicht-Schlüsselspalten dürfen nicht
NOT NULLsein.- Eine Nicht-Schlüsselspalte aus einer Tabelle löschen, sofern sie nicht von einem sekundären Index, einem Fremdschlüssel, einer gespeicherten generierten Spalte oder einer Diagnoseeinschränkung verwendet wird.
NOT NULLin eine Nicht-Schlüsselspalte aufnehmen und dabeiARRAY-Spalten ausschließen.NOT NULLaus einer Nicht-Schlüsselspalte entfernen.- Eine Spalte des Typs
STRINGin eine Spalte des TypsBYTESändern oder umgekehrt (BYTESinSTRING). - Eine Spalte des Typs
PROTOin eine Spalte des TypsBYTESändern oder umgekehrt (BYTESinPROTO). - Den Proto-Nachrichtentyp einer
PROTO-Spalte ändern. - Fügen Sie einer
ENUM-Definition neue Werte hinzu und benennen Sie vorhandene Werte mitALTER PROTO BUNDLEum. - Ändern Sie Nachrichten, die in einem
PROTO BUNDLEdefiniert sind, beliebig, sofern geänderte Felder dieser Nachrichten nicht als Schlüssel in einer Tabelle verwendet werden und die vorhandenen Daten den neuen Einschränkungen entsprechen. - Die Längenbeschränkung für einen
STRING- oderBYTES-Typ erhöhen oder verringern (einschließlich aufMAX), es sei denn, es ist eine Primärschlüsselspalte, die von einer oder mehreren untergeordneten Tabellen übernommen wird. - Die Längenbeschränkung für eine Spalte vom Typ
ARRAY<STRING>,ARRAY<BYTES>oderARRAY<PROTO>auf das maximal zulässige Limit erhöhen oder verringern. - Commit-Zeitstempel in Wert- und Primärschlüsselspalten aktivieren oder deaktivieren.
- Einen sekundären Index hinzufügen oder entfernen.
- Diagnoseeinschränkung zu einer vorhandenen Tabelle hinzufügen oder daraus entfernen.
- Gespeicherte generierte Spalte zu einer vorhandenen Tabelle hinzufügen oder daraus entfernen.
- Erstellt ein neues Statistikpaket für das Optimierungstool.
- Ansichten erstellen und verwalten.
- Sequenzen erstellen und verwalten.
- Datenbankrollen erstellen und Berechtigungen erteilen
- Standardwert einer Spalte festlegen, ändern oder löschen
- Ändern Sie die Datenbankoptionen (z. B.
default_leaderoderversion_retention_period). - Änderungsstreams erstellen und verwalten.
- ML-Modelle erstellen und verwalten
Nicht unterstützte Schemaaktualisierungen
Die folgenden Schemaaktualisierungen einer vorhandenen Datenbank werden von Spanner nicht unterstützt:
Wenn ein Feld
PROTOvom TypENUMvorhanden ist, auf das von einem Tabellen- oder Indexschlüssel verwiesen wird, können SieENUM-Werte nicht aus den Proto-Enums entfernen. Das Entfernen vonENUM-Werten aus Enums, die vonENUM<>-Spalten verwendet werden, wird unterstützt, auch wenn diese Spalten als Schlüssel verwendet werden.Eine Spalte des Typs
STRING(36)in eine Spalte des TypsUUIDändern oder umgekehrt (UUIDinSTRING(36)).
Leistung während der Schemaaktualisierung
Schemaaktualisierungen in Spanner erfolgen ohne Ausfallzeiten. Wenn Sie einen Batch von DDL-Anweisungen an eine Spanner-Datenbank absetzen, können Sie ohne Unterbrechung weiter Daten in die Datenbank schreiben und aus ihr lesen, während Spanner die Aktualisierung als Vorgang mit langer Ausführungszeit durchführt.
Die Ausführungsdauer einer DDL-Anweisung hängt davon ab, ob die Aktualisierung eine Validierung von vorhandenen Daten oder einen Daten-Backfill voraussetzt. Wenn Sie beispielsweise die Annotation NOT NULL in eine vorhandene Spalte aufnehmen, muss Spanner alle Werte in der Spalte lesen und so gewährleisten, dass die Spalte keine NULL-Werte enthält. Dieser Schritt kann lange dauern, wenn viele Daten validiert werden müssen. Ein anderes Beispiel ist die Erweiterung einer Datenbank um einen Index: Spanner verwendet dann vorhandene Daten, um einen Backfill für den Index durchzuführen. In Abhängigkeit von der Definition des Index und der Größe der entsprechenden Basistabelle kann dieser Prozess viel Zeit in Anspruch nehmen. Wenn Sie jedoch eine neue Spalte in eine Tabelle einfügen, müssen keine vorhandenen Daten validiert werden, sodass Spanner die Aktualisierung schneller abwickeln kann.
Zusammenfassend lässt sich sagen, dass Schemaaktualisierungen innerhalb von Minuten durchgeführt werden können, wenn Spanner keine vorhandenen Daten validieren muss. Schemaaktualisierungen mit Validierung können je nach Menge der zu validierenden vorhandenen Daten länger dauern. Allerdings erfolgt die Datenvalidierung im Hintergrund mit niedrigerer Priorität als Produktionstraffic. Schemaaktualisierungen, die eine Datenvalidierung voraussetzen, werden im nächsten Abschnitt ausführlicher erläutert.
Schemaaktualisierungen, die mit Ansichtsdefinitionen validiert werden
Wenn Sie ein Schema aktualisieren, prüft Spanner, ob die Abfragen, die zum Definieren vorhandener Ansichten verwendet werden, durch das Update nicht ungültig werden. Ist die Validierung erfolgreich, verläuft auch die Schemaaktualisierung erfolgreich. Wenn die Validierung nicht erfolgreich ist, schlägt die Schemaaktualisierung fehl. Weitere Informationen finden Sie unter Best Practices beim Erstellen von Ansichten.
Schemaaktualisierungen mit erforderlicher Datenvalidierung
Sie können Schemaaktualisierungen vornehmen, bei denen überprüft werden muss, ob die vorhandenen Daten den neuen Einschränkungen entsprechen. Wenn für eine Schemaaktualisierung eine Datenvalidierung erforderlich ist, lässt Spanner keine in Konflikt stehenden Schemaaktualisierungen der betroffenen Schemaentitäten zu und validiert die Daten im Hintergrund. Ist die Validierung erfolgreich, verläuft auch die Schemaaktualisierung erfolgreich. Wenn die Validierung nicht erfolgreich ist, gilt das auch für die Schemaaktualisierung. Validierungsvorgänge sind lang laufende Vorgänge. Anhand des Status dieser Vorgänge können Sie feststellen, ob sie erfolgreich beendet wurden oder fehlgeschlagen sind.
Angenommen, Sie haben die folgende music.proto-Datei mit einem RecordLabel-Enum und einer Songwriter-Protokollnachricht definiert:
enum RecordLabel {
COOL_MUSIC_INC = 0;
PACIFIC_ENTERTAINMENT = 1;
XYZ_RECORDS = 2;
}
message Songwriter {
required string nationality = 1;
optional int64 year_of_birth = 2;
}
So fügen Sie Ihrem Schema eine Songwriters-Tabelle hinzu:
GoogleSQL
CREATE PROTO BUNDLE (
googlesql.example.music.Songwriter,
googlesql.example.music.RecordLabel,
);
CREATE TABLE Songwriters (
Id INT64 NOT NULL,
FirstName STRING(1024),
LastName STRING(1024),
Nickname STRING(MAX),
OpaqueData BYTES(MAX),
SongWriter googlesql.example.music.Songwriter
) PRIMARY KEY (Id);
CREATE TABLE Albums (
SongwriterId INT64 NOT NULL,
AlbumId INT64 NOT NULL,
AlbumTitle STRING(MAX),
Label INT32
) PRIMARY KEY (SongwriterId, AlbumId);
In diesem Fall sind folgende Schemaaktualisierungen zulässig, die jedoch validiert werden müssen und je nach Menge der vorhandenen Daten länger dauern können:
Die Annotation
NOT NULLin eine Nicht-Schlüsselspalte aufnehmen. Beispiel:ALTER TABLE Songwriters ALTER COLUMN Nickname STRING(MAX) NOT NULL;Die Länge einer Spalte verringern. Beispiel:
ALTER TABLE Songwriters ALTER COLUMN FirstName STRING(10);BYTESinSTRINGändern. Beispiel:ALTER TABLE Songwriters ALTER COLUMN OpaqueData STRING(MAX);INT64/INT32inENUMändern. Beispiel:ALTER TABLE Albums ALTER COLUMN Label googlesql.example.music.RecordLabel;Vorhandene Werte aus der Enum-Definition
RecordLabelentfernen.Commit-Zeitstempel für eine vorhandene
TIMESTAMP-Spalte aktivieren. Beispiel:ALTER TABLE Albums ALTER COLUMN LastUpdateTime SET OPTIONS (allow_commit_timestamp = true);Diagnoseeinschränkung zu einer vorhandenen Tabelle hinzufügen
Gespeicherte generierte Spalte zu einer vorhandenen Tabelle hinzufügen
Erstellen einer neuen Tabelle mit einem Fremdschlüssel.
Einer vorhandenen Tabelle einen Fremdschlüssel hinzufügen
Diese Schemaaktualisierungen schlagen fehl, wenn die zugrunde liegenden Daten den neuen Einschränkungen nicht entsprechen. Beispielsweise schlägt die Anweisung ALTER TABLE Songwriters ALTER COLUMN Nickname
STRING(MAX) NOT NULL fehl, wenn in der Spalte Nickname ein Wert NULL ist. In diesem Fall entsprechen die vorhandenen Daten nicht der Einschränkung NOT NULL der neuen Definition.
Die Datenvalidierung kann mehrere Minuten bis viele Stunden andauern. Die Dauer der Datenvalidierung hängt von folgenden Faktoren ab:
- Größe des Datasets
- Rechenkapazität der Instanz
- Auslastung der Instanz
Einige Schemaaktualisierungen können das Verhalten von Anfragen an die Datenbank während der Schemaaktualisierung ändern. Wenn Sie beispielsweise NOT NULL in eine Spalte aufnehmen, beginnt Spanner nahezu sofort damit, Schreibvorgänge für neue Anfragen abzulehnen, in denen NULL für diese Spalte angegeben ist. Sollte die neue Schemaaktualisierung aufgrund der Datenvalidierung letztendlich fehlschlagen, wurden Schreibvorgänge in einem gewissen Zeitraum blockiert, auch wenn sie vom alten Schema akzeptiert worden wären.
Sie können einen lang andauernden Datenvalidierungsprozess mit der Methode projects.instances.databases.operations.cancel oder mit gcloud spanner
operations abbrechen.
Während der Schemaaktualisierung erstellte Schemaversionen
Da Spanner mit Schemaversionierung arbeitet, können Schemas von großen Datenbanken ohne Ausfallzeit aktualisiert werden. Spanner behält die ältere Schemaversion bei, sodass Lesevorgänge während der Verarbeitung der Schemaaktualisierung möglich sind. Anschließend erstellt Spanner eine oder mehrere neue Versionen des Schemas, um die Schemaaktualisierung zu verarbeiten. Jede Version enthält das Ergebnis einer Gruppe von Anweisungen in einer einzelnen atomaren Änderung.
Die Schemaversionen stimmen nicht zwangsläufig eins zu eins mit Batches von DDL-Anweisungen oder einzelnen DDL-Anweisungen überein. Manche einzelne DDL-Anweisungen führen zu mehreren Schemaversionen, beispielsweise die Indexerstellung für vorhandene Basistabellen oder Anweisungen, die eine Datenvalidierung erfordern. In anderen Fällen können mehrere DDL-Anweisungen in einer einzigen Version zusammengefasst sein. Alte Schemaversionen können erhebliche Server- und Speicherressourcen verbrauchen und werden aufbewahrt, bis sie abgelaufen bzw. nicht mehr erforderlich sind, um Lesevorgänge von früheren Datenversionen bereitzustellen.
Die folgende Tabelle zeigt, wie lange Spanner benötigt, um ein Schema zu aktualisieren.
| Schemavorgang | Geschätzte Dauer |
|---|---|
CREATE TABLE |
Minuten |
CREATE INDEX |
Minuten bis Stunden, wenn die Basistabelle vor dem Index erstellt wird. Minuten, wenn die Anweisung gleichzeitig mit der Anweisung |
DROP TABLE |
Minuten |
DROP INDEX |
Minuten |
ALTER TABLE ... ADD COLUMN |
Minuten |
ALTER TABLE ... ALTER COLUMN |
Minuten bis Stunden, wenn eine Validierung im Hintergrund erforderlich ist. Minuten, wenn keine Validierung im Hintergrund erforderlich ist. |
ALTER TABLE ... DROP COLUMN |
Minuten |
ANALYZE |
Je nach Datenbankgröße kann es einige Minuten bis Stunden dauern. |
Änderungen des Datentyps und Änderungsstreams
Wenn Sie den Datentyp einer Spalte ändern, die von einem Änderungsstream überwacht wird, spiegelt das Feld column_types der relevanten nachfolgenden Änderungsstreamdatensätze den neuen Typ wider, ebenso wie die old_values-JSON-Daten im Feld mods der Datensätze.
Der new_values des Felds mods eines Änderungsstreamdatensatzes entspricht immer dem aktuellen Typ einer Spalte. Wenn Sie den Datentyp einer beobachteten Spalte ändern, wirkt sich das nicht auf Änderungsstreamdatensätze aus, die vor dieser Änderung erstellt wurden.
Im speziellen Fall einer Änderung von BYTES zu STRING werden die alten Werte der Spalte im Rahmen der Schemaaktualisierung von Spanner validiert. Daher hat Spanner die alten Werte vom Typ BYTES sicher in Strings decodiert, bevor nachfolgende Änderungsstreamdatensätze geschrieben werden.