Mit Spanner lassen sich Schemas ohne Ausfallzeit aktualisieren. Sie haben mehrere Möglichkeiten, das Schema einer vorhandenen Datenbank zu aktualisieren:
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 die Seite Spanner Studio aufzurufen.
Mit dem
gcloud spanner-BefehlszeilentoolSenden Sie einen
ALTER TABLEBefehl mit demgcloud spanner databases ddl updateBefehl.Mit der
projects.instances.databases.updateDdlREST APIMit der
UpdateDatabaseDdl-RPC API
Unterstützte Schemaaktualisierungen
Für das Schema einer vorhandenen Datenbank unterstützt Spanner folgende Arten von Aktualisierungen:
- 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.
- Tabelle mit einem Fremdschlüssel erstellen oder löschen.
- 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 Prüfeinschränkung verwendet wird.
NOT NULLin eine Nicht-Schlüsselspalte aufnehmen und dabeiARRAY-Spalten ausschließen.NOT NULLaus einer Nicht-Schlüsselspalte entfernen.- Eine
STRING-Spalte in eineBYTES-Spalte ändern oder umgekehrt (STRINGinBYTESoderBYTESinSTRING). - Eine
PROTO-Spalte in eineBYTES-Spalte ändern oder umgekehrt (PROTOinBYTESoderBYTESinPROTO). - Den Proto-Nachrichtentyp einer
PROTO-Spalte ändern. - Mit
ALTER PROTO BUNDLEneue Werte zu einerENUM-Definition hinzufügen und vorhandene Werte umbenennen. - Nachrichten, die in einem
PROTO BUNDLEdefiniert sind, auf beliebige Weise ändern, sofern die geänderten Felder dieser Nachrichten in keiner Tabelle als Schlüssel verwendet werden und die vorhandenen Daten den neuen Einschränkungen entsprechen. - Die Längenbeschränkung für einen
STRINGoderBYTESTyp (einschließlich aufMAX) erhöhen oder verringern, es sei denn, es ist eine Primärschlüssel spalte, die von einer oder mehreren untergeordneten Tabellen übernommen wird. - Die Längenbeschränkung für eine
ARRAY<STRING>,ARRAY<BYTES>oderARRAY<PROTO>-Spalte auf das zulässige Maximum erhöhen oder verringern. - Commit-Zeitstempel in Wert- und Primär schlüsselspalten aktivieren oder deaktivieren.
- 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.
- Neues Statistikpaket für das Abfrageoptimierungstool erstellen.
- Ansichten erstellen und verwalten.
- Sequenzen erstellen und verwalten.
- Datenbankrollen erstellen und Berechtigungen gewähren.
- Den Standardwert einer Spalte festlegen, ändern oder löschen.
- Die Datenbankoptionen ändern (z. B.
default_leaderoderversion_retention_period). - Änderungsstreams erstellen und verwalten.
- ML-Modelle erstellen und verwalten.
Nicht unterstützte Schemaaktualisierungen
Spanner unterstützt die folgenden Schemaaktualisierungen für eine vorhandene Datenbank nicht:
Wenn ein
PROTO-Feld vom TypENUMvorhanden ist, auf das von einem Tabellen- oder Indexschlüssel verwiesen wird, können Sie keineENUM-Werte aus den Proto-Enums entfernen. Das Entfernen vonENUMWerten aus Enums, die vonENUM<>Spalten verwendet werden, wird unterstützt, einschließlich wenn diese Spalten als Schlüssel verwendet werden.Eine
STRING(36)-Spalte in eineUUID-Spalte ändern oder umgekehrt (STRING(36)inUUIDoderUUIDinSTRING(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 ausfü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 NOT NULL Annotation zu einer vorhandenen Spalte hinzufügen,
muss Spanner alle Werte in der Spalte lesen, um sicherzustellen, dass
die Spalte keine NULL Werte enthält. Wenn viele Daten validiert werden müssen, kann dieser Schritt lange dauern. 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 einer Tabelle eine neue Spalte hinzufügen, sind keine vorhandenen Daten zu validieren, sodass Spanner die Aktualisierung schneller durchführen 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, schlägt die Schemaaktualisierung fehl. Validierungsvorgänge werden als lang laufende Vorgängeausgeführt. 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
RecordLabel-Enum-Definition entfernen.Commit-Zeitstempel für eine vorhandene
TIMESTAMPSpalte 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
Neue Tabelle mit einem Fremdschlüssel erstellen.
Einer vorhandenen Tabelle einen Fremdschlüssel hinzufügen
Diese Schemaaktualisierungen schlagen fehl, wenn die zugrunde liegenden Daten den neuen Einschränkungen nicht entsprechen. Die Anweisung ALTER TABLE Songwriters ALTER COLUMN Nickname
STRING(MAX) NOT NULL schlägt beispielsweise fehl, wenn ein Wert in der Spalte Nickname
NULL ist, da die vorhandenen Daten nicht der NOT NULL-Einschränkung der
neuen Definition entsprechen.
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 zu einer
Spalte hinzufügen, lehnt Spanner fast sofort Schreibvorgänge für
neue Anfragen ab, die NULL für die Spalte verwenden. 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
projects.instances.databases.operations.cancel
Methode oder mit gcloud spanner
operationsabbrechen.
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, um Lesevorgänge zu unterstützen, während die Schemaaktualisierung verarbeitet wird. 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 älteren Datenversionen bereitzustellen.
In der folgenden Tabelle sehen Sie, wie lange es dauert, bis Spanner ein Schema aktualisiert.
| 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 Minuten bis Stunden. |
Änderungen des Datentyps und Änderungsstreams
Wenn Sie den Datentyp einer Spalte ändern, die von einem Änderungs
stream überwacht wird, spiegelt das Feld column_types der
relevanten nachfolgenden Änderungsstream
datensätze den
neuen Typ wider. Das gilt auch für die JSON-Daten old_values im Feld mods der Datensätze.
Die new_values des Felds mods eines Änderungsstreamdatensatzes stimmen immer mit dem aktuellen Typ einer Spalte überein. Das Ändern des Datentyps einer überwachten Spalte hat keine Auswirkungen auf Änderungsstreamdatensätze, die vor dieser Änderung erstellt wurden.
Im Sonderfall einer Änderung von BYTES in STRING validiert Spanner
die alten Werte der Spalte im Rahmen der
Schemaaktualisierung. Daher hat Spanner die alten Werte vom Typ BYTES sicher in Strings decodiert, bevor nachfolgende Änderungsstreamdatensätze geschrieben werden.