Spanner ti consente di aggiornare lo schema senza tempi di inattività. Puoi aggiornare lo schema di un database esistente in diversi modi:
Tramite la Google Cloud console
Invia un comando
ALTER TABLEnella pagina Spanner Studio.Per accedere alla pagina Spanner Studio, fai clic su Spanner Studio dalla pagina Panoramica database o Panoramica tabella.
Utilizzando lo strumento a riga di comando
gcloud spannerInvia un comando
ALTER TABLEutilizzando il comandogcloud spanner databases ddl update.Utilizzando le librerie client
Utilizzando l'
projects.instances.databases.updateDdlAPI RESTUtilizzando l'API RPC
UpdateDatabaseDdl
Aggiornamenti dello schema supportati
Spanner supporta i seguenti aggiornamenti dello schema di un database esistente:
- Aggiungere o eliminare uno schema denominato.
- Creare una nuova tabella. Le colonne delle nuove tabelle possono essere
NOT NULL. - Eliminare una tabella, se non sono presenti altre tabelle con interleaving e non ha indici secondari.
- Creare o eliminare una tabella con una chiave esterna.
- Aggiungere o rimuovere una chiave esterna da una tabella esistente.
- Aggiungere una colonna non chiave a qualsiasi tabella. Le nuove colonne non chiave non possono essere
NOT NULL.- Eliminare una colonna non chiave da qualsiasi tabella, a meno che non venga utilizzata da un indice secondario, una chiave esterna, una colonna generata archiviata o un vincolo di controllo.
- Aggiungere
NOT NULLa una colonna non chiave, escluse le colonneARRAY. - Rimuovere
NOT NULLda una colonna non chiave. - Modificare una colonna
STRINGin una colonnaBYTESo una colonnaBYTESin una colonnaSTRING. - Modificare una colonna
PROTOin una colonnaBYTESo una colonnaBYTESin una colonnaPROTO. - Modificare il tipo di messaggio proto di una colonna
PROTO. - Aggiungere nuovi valori a una definizione
ENUMe rinominare i valori esistenti utilizzandoALTER PROTO BUNDLE. - Modificare i messaggi definiti in un
PROTO BUNDLEin modi arbitrari, a condizione che i campi modificati di questi messaggi non vengano utilizzati come chiavi in nessuna tabella e che i dati esistenti soddisfino i nuovi vincoli. - Aumentare o diminuire il limite di lunghezza per un tipo
STRINGoBYTES(inclusoMAX), a meno che non si tratti di una colonna di chiave primaria ereditata da una o più tabelle figlio. - Aumentare o diminuire il limite di lunghezza per una colonna
ARRAY<STRING>,ARRAY<BYTES>oARRAY<PROTO>al massimo consentito. - Attivare o disattivare i timestamp di commit nelle colonne di valore e di chiave primaria.
- Aggiungere o rimuovere un indice secondario.
- Aggiungere o rimuovere un vincolo di controllo da una tabella esistente.
- Aggiungere o rimuovere una colonna generata archiviata da una tabella esistente.
- Costruire un nuovo pacchetto di statistiche dello strumento di ottimizzazione.
- Creare e gestire le viste.
- Creare e gestire le sequenze.
- Creare ruoli di database e concedere privilegi.
- Impostare, modificare o eliminare il valore predefinito di una colonna.
- Modificare le opzioni del database (ad esempio
default_leaderoversion_retention_period). - Creare e gestire gli stream di modifiche.
- Creare e gestire i modelli di machine learning.
Aggiornamenti dello schema non supportati
Spanner non supporta i seguenti aggiornamenti dello schema di un database esistente:
Se è presente un campo
PROTOdi tipoENUMa cui fa riferimento una chiave di tabella o di indice, non puoi rimuovere i valoriENUMdagli enum proto. (La rimozione deiENUMvalori dagli enum utilizzati dalleENUM<>colonne è supportata, anche quando queste colonne vengono utilizzate come chiavi.)Modificare una colonna
STRING(36)in una colonnaUUIDo una colonnaUUIDin una colonnaSTRING(36).
Prestazioni dell'aggiornamento dello schema
Gli aggiornamenti dello schema in Spanner non richiedono tempi di inattività. Quando invii un batch di istruzioni DDL a un database Spanner, puoi continuare a eseguire operazioni di lettura e scrittura sul database senza interruzioni mentre Spanner applica l'aggiornamento come operazione a lunga esecuzione.
Il tempo necessario per eseguire un'istruzione DDL dipende dalla necessità o meno di convalidare i dati esistenti o di eseguire il backfill di dati durante l'aggiornamento. Ad esempio,
se aggiungi l'annotazione NOT NULL a una colonna esistente,
Spanner deve leggere tutti i valori della colonna per assicurarsi che
la colonna non contenga valori NULL. Questo passaggio può richiedere tempi lunghi in presenza di grandi quantità di dati da convalidare. Un altro esempio è l'aggiunta di un indice a un database: Spanner esegue il backfill dell'indice utilizzando i dati esistenti e questo processo può richiedere tempi lunghi a seconda della definizione dell'indice e delle dimensioni della tabella di base corrispondente. Tuttavia, se aggiungi una nuova colonna a una tabella, non sono presenti dati esistenti da convalidare, quindi Spanner può eseguire l'aggiornamento più rapidamente.
In sintesi, gli aggiornamenti dello schema che non richiedono la convalida dei dati esistenti da parte di Spanner possono essere eseguiti in pochi minuti. Gli aggiornamenti dello schema che richiedono la convalida possono richiedere più tempo, a seconda della quantità di dati esistenti da convalidare, ma la convalida dei dati avviene in background e con una priorità inferiore rispetto al traffico di produzione. Gli aggiornamenti dello schema che richiedono la convalida dei dati sono descritti in maggiore dettaglio nella sezione successiva.
Aggiornamenti dello schema convalidati in base alle definizioni delle viste
Quando esegui un aggiornamento dello schema, Spanner convalida che l'aggiornamento non invalidi le query utilizzate per definire le viste esistenti. Se la convalida ha esito positivo, l'aggiornamento dello schema viene eseguito. Se la convalida non ha esito positivo, l'aggiornamento dello schema non viene eseguito. Per maggiori dettagli, consulta le best practice per la creazione di viste.
Aggiornamenti dello schema che richiedono la convalida dei dati
Puoi eseguire aggiornamenti dello schema che richiedono la convalida dei dati esistenti in base ai nuovi vincoli. Quando un aggiornamento dello schema richiede la convalida dei dati, Spanner non consente aggiornamenti dello schema in conflitto con le entità dello schema interessate e convalida i dati in background. Se la convalida ha esito positivo, l'aggiornamento dello schema viene eseguito. Se la convalida non ha esito positivo, l'aggiornamento dello schema non viene eseguito. Le operazioni di convalida vengono eseguite come operazioni a lunga esecuzione. Puoi controllare lo stato di queste operazioni per determinare se sono state eseguite correttamente o meno.
Supponiamo, ad esempio, di aver definito il seguente file music.proto con un enum RecordLabel e un messaggio del protocollo Songwriter:
enum RecordLabel {
COOL_MUSIC_INC = 0;
PACIFIC_ENTERTAINMENT = 1;
XYZ_RECORDS = 2;
}
message Songwriter {
required string nationality = 1;
optional int64 year_of_birth = 2;
}
Per aggiungere una tabella Songwriters allo schema:
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);
I seguenti aggiornamenti dello schema sono consentiti, ma richiedono la convalida e potrebbero richiedere più tempo per essere completati, a seconda della quantità di dati esistenti:
Aggiungere l'annotazione
NOT NULLa una colonna non chiave. Ad esempio:ALTER TABLE Songwriters ALTER COLUMN Nickname STRING(MAX) NOT NULL;Ridurre la lunghezza di una colonna. Ad esempio:
ALTER TABLE Songwriters ALTER COLUMN FirstName STRING(10);Modificare da
BYTESaSTRING. Ad esempio:ALTER TABLE Songwriters ALTER COLUMN OpaqueData STRING(MAX);Modificare da
INT64/INT32aENUM. Ad esempio:ALTER TABLE Albums ALTER COLUMN Label googlesql.example.music.RecordLabel;Rimuovere i valori esistenti dalla definizione dell'enum
RecordLabel.Attivare i timestamp di commit in una colonna
TIMESTAMPesistente. Ad esempio:ALTER TABLE Albums ALTER COLUMN LastUpdateTime SET OPTIONS (allow_commit_timestamp = true);Aggiungere un vincolo di controllo a una tabella esistente.
Aggiungere una colonna generata archiviata a una tabella esistente.
Creare una nuova tabella con una chiave esterna.
Aggiungere una chiave esterna a una tabella esistente.
Questi aggiornamenti dello schema non vengono eseguiti se i dati sottostanti non soddisfano i nuovi vincoli. Ad esempio, l'istruzione ALTER TABLE Songwriters ALTER COLUMN Nickname
STRING(MAX) NOT NULL non viene eseguita se un valore nella colonna Nickname è
NULL, perché i dati esistenti non soddisfano il vincolo NOT NULL della
nuova definizione.
La convalida dei dati può richiedere da alcuni minuti a molte ore. Il tempo necessario per completare la convalida dei dati dipende da:
- Le dimensioni del set di dati
- La capacità di calcolo dell'istanza
- Il carico sull'istanza
Alcuni aggiornamenti dello schema possono modificare il comportamento delle richieste al database prima del completamento dell'aggiornamento dello schema. Ad esempio, se aggiungi NOT NULL a una
colonna, Spanner inizia quasi immediatamente a rifiutare le scritture per
nuove richieste che utilizzano NULL per la colonna. Se il nuovo aggiornamento dello schema non viene eseguito a causa della convalida dei dati, si verifica un periodo di tempo in cui le scritture sono state bloccate, anche se sarebbero state accettate dal vecchio schema.
Puoi annullare un'operazione di convalida dei dati a lunga esecuzione utilizzando il
projects.instances.databases.operations.cancel
metodo o utilizzando gcloud spanner
operations.
Versioni dello schema create durante gli aggiornamenti dello schema
Spanner utilizza il controllo delle versioni dello schema in modo che non si verifichino tempi di inattività durante un aggiornamento dello schema di un database di grandi dimensioni. Spanner mantiene la versione precedente dello schema per supportare le letture durante l'elaborazione dell'aggiornamento dello schema. Spanner crea quindi una o più nuove versioni dello schema per elaborare l'aggiornamento dello schema. Ogni versione contiene il risultato di una raccolta di istruzioni in una singola modifica atomica.
Le versioni dello schema non corrispondono necessariamente uno a uno ai batch di istruzioni DDL o alle singole istruzioni DDL. Alcune singole istruzioni DDL, come la creazione di indici per le tabelle di base esistenti o le istruzioni che richiedono la convalida dei dati, generano più versioni dello schema. In altri casi, più istruzioni DDL possono essere raggruppate in batch in una singola versione. Le versioni precedenti dello schema possono consumare risorse di server e di archiviazione significative e vengono conservate fino alla scadenza (non sono più necessarie per gestire le letture delle versioni precedenti dei dati).
La tabella seguente mostra il tempo necessario a Spanner per aggiornare uno schema.
| Operazione dello schema | Durata stimata |
|---|---|
CREATE TABLE |
Minuti |
CREATE INDEX |
Da minuti a ore, se la tabella di base viene creata prima dell'indice. Minuti, se l'istruzione viene eseguita contemporaneamente all'istruzione |
DROP TABLE |
Minuti |
DROP INDEX |
Minuti |
ALTER TABLE ... ADD COLUMN |
Minuti |
ALTER TABLE ... ALTER COLUMN |
Da minuti a ore, se è richiesta la convalida in background. Minuti, se non è richiesta la convalida in background. |
ALTER TABLE ... DROP COLUMN |
Minuti |
ANALYZE |
Da minuti a ore, a seconda delle dimensioni del database. |
Modifiche del tipo di dati e modifiche in tempo reale
Se modifichi il tipo di dati di una colonna monitorata da uno stream
di modifiche, il campo column_types dei record
dello stream di modifiche
successivi pertinenti riflette il nuovo tipo, così come i dati JSON old_values all'interno del campo mods dei record.
Il campo new_values del campo mods di un record dello stream di modifiche corrisponde sempre al tipo attuale di una colonna. La modifica del tipo di dati di una colonna monitorata non influisce sui record dello stream di modifiche precedenti a questa modifica.
Nel caso specifico di una modifica da BYTES a STRING, Spanner
convalida i vecchi valori della colonna nell'ambito dell'aggiornamento dello schema. Di conseguenza, Spanner ha decodificato in modo sicuro i vecchi valori di tipo BYTES in stringhe nel momento in cui scrive i record dello stream di modifiche successivi.