Spanner te permite realizar actualizaciones del esquema sin tiempo de inactividad. Puedes actualizar el esquema de una base de datos existente de varias maneras:
En la consola de Google Cloud
Envía un comando
ALTER TABLEen la página Spanner Studio.Para acceder a la página Spanner Studio, haz clic en Spanner Studio en la página de resumen de la base de datos o de la tabla.
Usa la herramienta de línea de comandos de
gcloud spannerEnvía un comando
ALTER TABLEcon el comandogcloud spanner databases ddl update.Con las bibliotecas cliente
Usa la API de REST de
projects.instances.databases.updateDdlUsa la API de RPC de
UpdateDatabaseDdl
Actualizaciones del esquema compatibles
Spanner admite las siguientes actualizaciones del esquema de una base de datos existente:
- Agrega o quita un esquema con nombre.
- Crear una tabla nueva Las columnas de las tablas nuevas pueden ser
NOT NULL - Borrar una tabla, si la tabla no tiene otras intercaladas ni índices secundarios
- Crea o borra una tabla con una clave externa.
- Agregar o quitar una clave externa de una tabla existente
- Agregar una columna sin clave a una tabla. Las columnas nuevas sin clave no pueden ser
NOT NULL.- Eliminar una columna sin clave de cualquier tabla, a menos que la use un índice secundario, una clave externa, una columna generada almacenada o una restricción de verificación
- Agregar
NOT NULLa una columna sin clave, excepto las columnasARRAY - Quitar
NOT NULLde una columna sin clave - Cambiar una columna
STRINGpor una columnaBYTESo una columnaBYTESpor una columnaSTRING - Cambiar una columna
PROTOpor una columnaBYTESo una columnaBYTESpor una columnaPROTO - Cambia el tipo de mensaje .proto de una columna
PROTO. - Agrega valores nuevos a una definición de
ENUMy cambia el nombre de los valores existentes conALTER PROTO BUNDLE. - Cambiar los mensajes definidos en un
PROTO BUNDLEde formas arbitrarias, siempre que los campos modificados de esos mensajes no se usen como claves en ninguna tabla y que los datos existentes satisfagan las nuevas restricciones - Aumentar o disminuir el límite de longitud para un tipo
STRINGoBYTES(incluidoMAX), a menos que sea una columna de clave primaria heredada por una o más tablas secundarias - Aumentar o disminuir el límite de longitud de una columna
ARRAY<STRING>,ARRAY<BYTES>oARRAY<PROTO>hasta el máximo permitido - Habilitar o inhabilitar marcas de tiempo de confirmación en las columnas de valor y clave primaria
- Agregar o quitar un índice secundario
- Agrega o quita una restricción de verificación de una tabla existente.
- Agrega o quita una columna generada almacenada de una tabla existente.
- Construye un nuevo paquete de estadísticas del optimizador.
- Crear y administrar vistas
- Crear y administrar secuencias
- Crear roles de bases de datos y otorgar privilegios
- Establece, cambia o descarta el valor predeterminado de una columna.
- Cambia las opciones de la base de datos (
default_leaderoversion_retention_period, por ejemplo). - Crear y administrar flujos de cambios
- Crear y administrar modelos de AA
Actualizaciones de esquemas no compatibles
Spanner no admite las siguientes actualizaciones del esquema de una base de datos existente:
Si hay un campo
PROTOdel tipoENUMal que hace referencia una clave de tabla o de índice, no puedes quitar valoresENUMde las enumeraciones de proto. (Se admite la eliminación de valoresENUMde las enumeraciones que usan las columnasENUM<>, incluso cuando esas columnas se usan como claves).Cambiar una columna
STRING(36)por una columnaUUIDo una columnaUUIDpor una columnaSTRING(36)
Rendimiento de la actualización del esquema
Las actualizaciones del esquema en Spanner no requieren tiempo de inactividad. Cuando emites un lote de declaraciones DDL a una base de datos de Spanner, puedes continuar escribiendo en la base de datos y leyendo desde ella sin interrupciones mientras Spanner aplica la actualización como una operación de larga duración.
El tiempo que tarda ejecutar una declaración DDL está sujeto a si la actualización requiere la validación de los datos existentes o el reabastecimiento de algún dato. Por ejemplo, si agregas la anotación NOT NULL a una columna existente, Spanner debe leer todos los valores de la columna para asegurarse de que la columna no contenga valores NULL. Este paso puede demorar bastante si hay muchos datos para validar. Otro ejemplo es si agregas un índice a una base de datos: Spanner reabastece el índice con datos existentes, y ese proceso puede tardar mucho tiempo según la definición del índice y el tamaño de la tabla base correspondiente. Sin embargo, si agregas una columna nueva a una tabla, no hay datos que validar, por lo que Spanner puede realizar la actualización con más rapidez.
En resumen, las actualizaciones del esquema que no requieren que Spanner valide los datos existentes pueden completarse en minutos. Las actualizaciones del esquema que requieren validación pueden tardar más, según la cantidad de datos existentes que deban validarse. Sin embargo, la validación de datos ocurre en segundo plano con una prioridad menor que el tráfico de producción. Las actualizaciones del esquema que requieren validación de datos se analizan con más detalle en la sección siguiente.
Actualizaciones del esquema validadas en función de las definiciones de vistas
Cuando realizas una actualización del esquema, Spanner valida que la actualización no invalide las consultas que se usan para definir las vistas existentes. Si la validación no falla, se realizará de forma correcta la actualización del esquema. Si la validación falla, la actualización del esquema no se realizará de forma correcta. Consulta Prácticas recomendadas para crear vistas para obtener más detalles.
Actualizaciones del esquema que requieren validación de datos
Puedes realizar actualizaciones del esquema que requieran validar que los datos existentes cumplan con las restricciones nuevas. Cuando una actualización del esquema requiere la validación de datos, Spanner no permite actualizaciones del esquema en conflicto para las entidades del esquema afectadas y valida los datos en segundo plano. Si la validación no falla, se realizará de forma correcta la actualización del esquema. Si la validación falla, la actualización del esquema no se realizará de forma correcta. Las operaciones de validación se ejecutan como operaciones de larga duración. Puedes verificar el estado de estas operaciones para determinar si se realizaron de forma correcta o no.
Por ejemplo, supongamos que definiste el siguiente archivo music.proto con un enum RecordLabel y un mensaje de protocolo 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;
}
Para agregar una tabla Songwriters a tu esquema, sigue estos pasos:
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);
Se permiten las siguientes actualizaciones del esquema, pero requieren validación y pueden tardar más en completarse, según la cantidad de datos existentes:
Agregar la anotación
NOT NULLa una columna sin clave. Por ejemplo:ALTER TABLE Songwriters ALTER COLUMN Nickname STRING(MAX) NOT NULL;Reducir la longitud de una columna. Por ejemplo:
ALTER TABLE Songwriters ALTER COLUMN FirstName STRING(10);Cambiar
BYTESporSTRING. Por ejemplo:ALTER TABLE Songwriters ALTER COLUMN OpaqueData STRING(MAX);Cambiar
INT64/INT32porENUM. Por ejemplo:ALTER TABLE Albums ALTER COLUMN Label googlesql.example.music.RecordLabel;Se quitaron valores existentes de la definición de la enumeración
RecordLabel.Habilitar marcas de tiempo de confirmación en una columna
TIMESTAMPexistente. Por ejemplo:ALTER TABLE Albums ALTER COLUMN LastUpdateTime SET OPTIONS (allow_commit_timestamp = true);Agrega una restricción de verificación a una tabla existente.
Agrega una columna generada almacenada a una tabla existente.
Crear una tabla nueva con una clave externa
Agregar una clave externa a una tabla existente
Estas actualizaciones del esquema fallan si los datos subyacentes no cumplen con las restricciones nuevas. Por ejemplo, la declaración ALTER TABLE Songwriters ALTER COLUMN Nickname
STRING(MAX) NOT NULL falla si algún valor de la columna Nickname es NULL, porque los datos existentes no cumplen con la restricción NOT NULL de la nueva definición.
La validación de datos puede tardar varios minutos o varias horas. El tiempo para completar la validación de los datos depende de lo siguiente:
- El tamaño del conjunto de datos
- La capacidad de procesamiento de la instancia
- La carga de la instancia
Algunas actualizaciones del esquema pueden cambiar el comportamiento de las solicitudes a la base de datos antes de que se complete la actualización del esquema. Por ejemplo, si agregas NOT NULL a una columna, Spanner casi de inmediato comienza a rechazar escrituras para solicitudes nuevas que usan NULL para la columna. Si la actualización del esquema nuevo al final falla para la validación de datos, habrá un período en el que se bloquearon las escrituras, incluso si el esquema anterior las hubiera aceptado.
Puedes cancelar una operación de validación de datos de larga duración con el método projects.instances.databases.operations.cancel o con gcloud spanner
operations.
Versiones de esquema creadas durante las actualizaciones del esquema
Spanner usa el control de versiones de esquema para que no haya tiempo de inactividad durante una actualización del esquema de una base de datos grande. Spanner mantiene la versión anterior del esquema para admitir las lecturas mientras se procesa la actualización del esquema. A continuación, Spanner crea una o más versiones nuevas del esquema para procesar la actualización del esquema. Cada versión contiene el resultado de una colección de instrucciones en un solo cambio atómico.
No es necesario que las versiones de esquema se correspondan uno a uno con lotes de declaraciones DDL ni con declaraciones DDL individuales. Algunas declaraciones DDL individuales, como la creación de índices para tablas base existentes o las declaraciones que requieren la validación de datos, dan como resultado varias versiones de esquema. En otros casos, varias declaraciones DDL se pueden agrupar en una sola versión. Las versiones de esquema antiguas pueden consumir recursos de servidor y almacenamiento significativos, y se conservan hasta que vencen (ya no son necesarias para atender las lecturas de versiones anteriores de los datos).
En la siguiente tabla, se muestra el tiempo que le toma a Spanner actualizar un esquema.
| Operación de esquema | Duración estimada |
|---|---|
CREATE TABLE |
Minutos |
CREATE INDEX |
Minutos a horas, si la tabla base se creó antes del índice Minutos, si la declaración se ejecuta al mismo tiempo que la declaración |
DROP TABLE |
Minutos |
DROP INDEX |
Minutos |
ALTER TABLE ... ADD COLUMN |
Minutos |
ALTER TABLE ... ALTER COLUMN |
Minutos a horas, si se requiere validación en segundo plano Minutos, si la validación en segundo plano no es necesaria |
ALTER TABLE ... DROP COLUMN |
Minutos |
ANALYZE |
De minutos a horas, según el tamaño de la base de datos |
Cambios en los tipos de datos y flujos de cambios
Si cambias el tipo de datos de una columna que supervisa un flujo de cambios, el campo column_types de los registros del flujo de cambios posteriores pertinentes reflejará su nuevo tipo, al igual que los datos JSON old_values dentro del campo mods de los registros.
El new_values del campo mods de un registro de flujo de cambios siempre coincide con el tipo actual de una columna. Cambiar el tipo de datos de una columna observada no afecta ningún registro de flujo de cambios anterior a ese cambio.
En el caso particular de un cambio de BYTES a STRING, Spanner valida los valores anteriores de la columna como parte de la actualización del esquema. Como resultado, Spanner decodificó de forma segura los valores antiguos de tipo BYTES en cadenas para cuando escribe los registros posteriores del flujo de cambios.