Actualizaciones del esquema

Cloud Spanner te permite realizar actualizaciones del esquema sin tiempo de inactividad. Puedes actualizar el esquema de una base de datos existente de varias maneras:

Actualizaciones del esquema compatibles

Cloud Spanner es compatible con las siguientes actualizaciones del esquema de una base de datos existente:

  • Crear tablas nuevas. Las columnas de las tablas nuevas pueden ser NOT NULL
  • Borrar una tabla, si la tabla no tiene otras intercaladas ni índices secundarios.
  • Agregar una columna sin clave a una tabla. Las columnas nuevas sin clave no pueden ser NOT NULL
  • Agregar NOT NULL a una columna sin clave, excepto las columnas ARRAY
  • Quitar NOT NULL de una columna sin clave
  • Eliminar una columna sin clave de cualquier tabla, a menos que la use un índice secundario
  • Cambiar una columna STRING por una columna BYTES o una columna BYTES por una columna STRING
  • Aumentar o disminuir el límite de longitud para un tipo STRING o BYTES (incluido MAX), a menos que sea una columna de clave primaria que heredada por una o más tablas secundarias.
  • Habilitar o inhabilitar marcas de tiempo de confirmación en las columnas de valor y clave primaria.
  • Agregar o quitar un índice secundario

Rendimiento de la actualización del esquema

Las actualizaciones del esquema en Cloud Spanner no requieren tiempo de inactividad. Cuando emites un lote de declaraciones DDL a una base de datos de Cloud Spanner, puedes continuar escribiendo en la base de datos y leyendo desde ella sin interrupciones mientras Cloud Spanner aplica la actualización como 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, Cloud 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: Cloud Spanner reabastece el índice con datos existentes; este 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 Cloud Spanner puede realizar la actualización con más rapidez.

En resumen, las actualizaciones del esquema que no requieren que Cloud 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 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, Cloud 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 una tabla Songwriters en tu esquema:

CREATE TABLE Songwriters (
      Id         INT64 NOT NULL,
      FirstName  STRING(1024),
      LastName   STRING(1024),
      Nickname   STRING(MAX),
      OpaqueData BYTES(MAX),
    ) PRIMARY KEY (Id);
    

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 NULL a 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 BYTES por STRING. Por ejemplo:

    ALTER TABLE Songwriters ALTER COLUMN OpaqueData STRING(MAX);
        
  • Habilitar marcas de tiempo de confirmación en una columna TIMESTAMP existente. Por ejemplo:

    ALTER TABLE Albums ALTER COLUMN LastUpdateTime SET OPTIONS (allow_commit_timestamp = true);
        

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 anterior 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 definición nueva.

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 cantidad de nodos en 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, Cloud 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.

Orden de ejecución de las declaraciones en lotes

Si usas la herramienta de gcloud, la API de REST o la API de RPC, puedes emitir un lote de una o más declaraciones CREATE, ALTER o DROP.

Cloud Spanner aplica declaraciones del mismo lote en orden y se detiene en el primer error. Si aplicar una declaración da como resultado un error, esa declaración se revierte. Los resultados de las declaraciones aplicadas antes en el lote no se revierten.

Cloud Spanner puede combinar y reordenar declaraciones de diferentes lotes, por lo que podría combinar declaraciones de diferentes lotes en un cambio atómico que se aplica a la base de datos. Dentro de cada cambio atómico, las declaraciones de diferentes lotes ocurren en un orden arbitrario. Por ejemplo, si un lote de declaraciones contiene ALTER TABLE MyTable ALTER COLUMN MyColumn STRING(50) y otro lote contiene ALTER TABLE MyTable ALTER COLUMN MyColumn STRING(20), Cloud Spanner dejará esa columna en uno de esos dos estados, pero no se especificará cuál.

Versiones de esquema creadas durante las actualizaciones del esquema

Cloud 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. Cloud Spanner mantiene la versión anterior del esquema para admitir las lecturas mientras se procesa la actualización del esquema. A continuación, Cloud 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 declaraciones en un cambio atómico único, como se describió antes.

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 no intercalados 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 pueden consumir recursos de servidor y almacenamiento significativos y se conservan hasta por una semana.

En la siguiente tabla, se muestra el tiempo que le toma a Cloud 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 CREATE TABLE para la tabla base

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

Prácticas recomendadas para las actualizaciones del esquema

En las siguientes secciones, se describen las prácticas recomendadas para actualizar esquemas.

Procedimientos previos a la actualización del esquema

Antes de emitir una actualización del esquema, realiza los siguientes pasos:

  • Verifica que todos los datos existentes en la base de datos que deseas modificar cumplan con las restricciones que impone la actualización del esquema. Como el éxito de algunos tipos de actualizaciones del esquema depende de los datos de la base de datos y no solo del esquema actual, una actualización del esquema correcta de una base de datos de prueba no garantiza una actualización del esquema correcta de una base de datos de producción. A continuación, hay algunos ejemplos comunes:

    • Si agregas una anotación NOT NULL a una columna existente, comprueba que la columna no contenga ningún valor NULL existente.
    • Si acortas la longitud permitida de una columna STRING o BYTES, verifica que todos los valores existentes en esa columna cumplan con la restricción de longitud deseada.
  • Si escribes en una columna, tabla o índice que experimenta una actualización del esquema, asegúrate de que los valores que escribes cumplan con las restricciones nuevas.

  • Si eliminas una columna, una tabla o un índice, asegúrate de no estar escribiendo datos allí ni leyéndolos.

Limita la cantidad de actualizaciones del esquema en un período de 7 días

Si no puedes agrupar en lotes tus declaraciones DDL, evita realizar muchas actualizaciones del esquema por separado del esquema de una base de datos sola en un período de 7 días determinado. Aumenta el tiempo en el que realizas actualizaciones del esquema para permitir que Cloud Spanner quite las versiones anteriores del esquema antes de que se creen versiones nuevas.

  • Para algunos sistemas de administración de bases de datos relacionales, hay paquetes de software que realizan varias series de actualizaciones del esquema a una versión inferior o una posterior en la base de datos en cada implementación de producción. No se recomiendan estos tipos de procesos para Cloud Spanner.
  • Cloud Spanner está optimizado para usar claves primarias en los datos de partición de las soluciones de multiusuario. Las soluciones de multiusuario que usan tablas separadas para cada cliente pueden generar una gran acumulación de operaciones de actualización del esquema que tardan mucho en completarse.

Evita usar más de 30 declaraciones DDL que requieran validación o reabastecimiento de índice en un período determinado de 7 días, ya que cada declaración crea varias versiones de esquema de forma interna.

Opciones para actualizaciones del esquema grandes

La mejor manera de crear una tabla y una gran cantidad de índices en esa tabla es crearlos todos al mismo tiempo. Puedes crear la tabla y sus índices cuando creas la base de datos o en un solo lote grande de declaraciones DDL. Puedes agrupar en lotes miles de declaraciones DDL en una sola solicitud, siempre que no más de 10 declaraciones necesiten validación o reabastecimiento.

Si no puedes crear la tabla y sus índices en un lote grande de declaraciones DDL único, intenta agregar no más de 3 índices nuevos por día.

Espera a que se completen las solicitudes a la API

Cuando realices solicitudes projects.instances.databases.updateDdl (API de REST) o UpdateDatabaseDdl (API de RPC), usa projects.instances.databases.operations.get (API de REST) o GetOperation (API de RPC), respectivamente, para esperar a que se complete cada solicitud antes de iniciar una solicitud nueva. Esperar a que se complete cada solicitud permite que tu aplicación realice un seguimiento del progreso de las actualizaciones del esquema. También mantiene la acumulación de actualizaciones del esquema pendientes en un tamaño administrable.

Carga masiva

Si cargas datos de forma masiva en tus tablas después de crearlas, suele ser más eficaz crear índices después de cargar los datos. Si agregas varios índices, podría ser más eficaz crear la base de datos con todas las tablas y los índices en el esquema inicial, como se describe en las opciones para actualizaciones grandes.