Migra las claves primarias

En este documento, se ofrecen instrucciones para migrar las claves primarias desde las tablas de la base de datos de origen en Spanner. Debes conocer la información disponible en Descripción general de la migración de claves primarias.

Antes de comenzar

  • A fin de obtener los permisos que necesitas para migrar las claves primarias a Spanner, solicita a tu administrador que te otorgue el Rol de IAM Administrador de base de datos de Cloud Spanner (roles/spanner.databaseAdmin) en la instancia.

Cómo migrar claves secuenciales generadas automáticamente

Si migras desde una base de datos que usa claves monótonas secuenciales, como AUTO_INCREMENT en MySQL, SERIAL en PostgreSQL, o el tipo IDENTITY estándar en Oracle o SQL Server, considera la siguiente estrategia de migración de alto nivel:

  1. En Spanner, replica la estructura de la tabla de tu base de datos de origen con una clave primaria de número entero.
  2. Para cada columna en Spanner que contenga valores secuenciales, crea una secuencia y asigna el GET_NEXT_SEQUENCE_VALUE (GoogleSQL, PostgreSQL) como valor predeterminado para la columna.
  3. Migra los datos existentes con claves originales desde la fuente la base de datos en Spanner. Considera usar la Herramienta de migración de Spanner o una plantilla de Dataflow
  4. De forma opcional, puedes establecer restricciones de clave externas a cualquier tablas dependientes.
  5. Antes de insertar datos nuevos, ajusta la configuración para omitir el rango de valores clave existentes.
  6. Inserta datos nuevos, lo que permite que la secuencia genere claves únicas automáticamente.

Ejemplo de flujo de trabajo de migración

El siguiente código define la estructura de la tabla y la secuencia relacionada en Spanner con un SEQUENCE y establece el objeto como el valor principal predeterminado de la tabla de destino:

GoogleSQL

CREATE SEQUENCE singer_id_sequence OPTIONS (
     SequenceKind = 'bit_reversed_positive'
  );

CREATE TABLE Singers (
     SingerId INT64 DEFAULT
     (GET_NEXT_SEQUENCE_VALUE(SEQUENCE SingerIdSequence)),
     Name STRING(1024),
     Biography STRING(MAX),
  ) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
     AlbumId INT64,
     SingerId INT64,
     AlbumName STRING(1024),
     SongList STRING(MAX),
     CONSTRAINT FK_singer_album
     FOREIGN KEY (SingerId)
       REFERENCES Singers (SingerId)
  ) PRIMARY KEY (AlbumId);

PostgreSQL

CREATE SEQUENCE SingerIdSequence BIT_REVERSED_POSITIVE;

CREATE TABLE Singers (
  SingerId BIGINT DEFAULT nextval('SingerIdSequence') PRIMARY KEY,
  Name VARCHAR(1024) NOT NULL,
  Biography TEXT
);

CREATE TABLE Albums (
  AlbumId BIGINT PRIMARY KEY,
  SingerId BIGINT,
  AlbumName VARCHAR(1024),
  SongList TEXT,
  CONSTRAINT FK_singer_album FOREIGN KEY (SingerId) REFERENCES Singers (SingerId)
);

La opción bit_reversed_positive indica que los valores generados por el del tipo INT64, son mayores que cero y no son secuenciales.

A medida que migras las filas existentes de la base de datos de origen a Spanner, las claves primarias no se modifican.

Para las inserciones nuevas que no especifican una clave primaria, Spanner recupera automáticamente un valor nuevo llamando el GET_NEXT_SEQUENCE_VALUE()(GoogleSQL o PostgreSQL) .

Estos valores se distribuyen de manera uniforme en el rango [1, 263] y podría haber posibles conflictos con las claves existentes. Para evitar esto, puedes configura la secuencia con ALTER_SEQUENCE (GoogleSQL o PostgreSQL) para omitir el rango de de los valores cubiertos por las claves existentes.

Supongamos que la tabla singers se migró de PostgreSQL, donde se encuentra su clave primaria singer_id es del tipo SERIAL. En el siguiente PostgreSQL, se muestra el DDL de la base de datos de origen:

PostgreSQL

CREATE TABLE Singers (
SingerId SERIAL PRIMARY KEY,
Name varchar(1024),
Biography varchar
);

Los valores de clave primaria aumentan monótonamente. Después de la migración, puedes recuperar el valor máximo de la clave primaria singer_id en Spanner. Usa el siguiente código en Spanner:

GoogleSQL

SELECT MAX(SingerId) FROM Singers;

PostgreSQL

SELECT MAX(SingerId) FROM Singers;

Supón que el valor que se muestra es 20,000. Puedes configurar el bucket de Spanner para omitir el rango [1, 21000]. Los 1,000 adicionales sirven como para alojar escrituras en la base de datos de origen después de la migración inicial. Las nuevas claves generadas en Spanner no entran en conflicto con el rango de claves primarias generadas en la base de datos PostgreSQL de origen. Usa el siguiente código en Spanner:

GoogleSQL

ALTER SEQUENCE SingerIdSequence SET OPTIONS (
skip_range_min = 1,
skip_range_max = 21000
);

PostgreSQL

ALTER SEQUENCE SingerIdSequence SKIP RANGE 1 21000;

Usa Spanner y la base de datos de origen

Puedes usar el concepto de rango de omisión para respaldar situaciones en las que Spanner o que la base de datos de origen genere claves primarias, por ejemplo, para habilitar la replicación en para la recuperación ante desastres durante una migración de sistemas.

Para ello, ambas bases de datos generan claves primarias y los datos se sincronizada entre ellas. Puedes configurar cada base de datos para crear una claves en rangos de claves que no se superponen. Cuando defines un rango para la fuente base de datos, puedes configurar la secuencia de Spanner para omitirla del rango de destino de la ruta.

Por ejemplo, después de la migración de la aplicación de pistas de música, replica el datos de PostgreSQL a Spanner para reducir el tiempo cortar.

Cuando hayas actualizado y probado la aplicación en Spanner, podrás dejar de usar la base de datos PostgreSQL de origen y usar Spanner, lo que lo convierte en el sistema de registro de actualizaciones y claves primarias nuevas. Cuando Spanner se haga cargo, podrás revertir el flujo de datos entre las bases de datos en la instancia de PostgreSQL.

Supongamos que tu base de datos de PostgreSQL de origen usa claves primarias SERIAL, que son Números enteros de 32 bits con firma. Las claves primarias de Spanner son más grandes de 64 bits y números de serie. En PostgreSQL, altera la columna de clave primaria para que sea una columna de 64 bits. o bigint. Usa el siguiente código en tu base de datos de PostgreSQL de origen:

PostgreSQL

ALTER TABLE Singers ALTER COLUMN SingerId TYPE bigint;

Puedes establecer una restricción CHECK en la tabla de la base de datos de origen de PostgreSQL. para asegurarte de que los valores de la clave primaria SingerId siempre sean menores o igual a 231-1. Usa el siguiente código en tu base de datos de PostgreSQL de origen:

PostgreSQL

ALTER TABLE Singers ADD CHECK (SingerId <= 2147483647);

En Spanner, podemos modificar la secuencia para omitir el rango [1, 231-1]. Usa el siguiente código en Spanner:

GoogleSQL

ALTER SEQUENCE SingerIdSequence SET OPTIONS (
skip_range_min = 1,
skip_range_max = 2147483647 -- 231-1
);

PostgreSQL

ALTER SEQUENCE SingerIdSequence SKIP RANGE 1 2147483648;

La base de datos PostgreSQL de origen siempre genera claves en un número entero de 32 bits. espacio, mientras que las claves de Spanner están restringidas al mayor que todos los números enteros de 32 bits. Esto garantiza que tanto tu las bases de datos pueden generar de forma independiente claves primarias que no entran en conflicto.

Migra las columnas de claves de UUID

En la práctica, las claves UUIDv4 son únicas sin importar dónde se generan. Las claves UUID generadas en otro lugar se integran con las nuevas claves UUID generadas en Spanner

Considera la siguiente estrategia de alto nivel para migrar Claves de UUID para Spanner:

  1. Define tus claves de UUID en Spanner mediante columnas de cadenas con un la expresión predeterminada. Usa el función GENERATE_UUID() (GoogleSQL, PostgreSQL).
  2. Exporta los datos desde el sistema de origen, serializando las claves UUID como cadenas.
  3. Importa las claves primarias a Spanner.
  4. Opcional: Habilita claves externas.

Este es un ejemplo de flujo de trabajo de migración:

En Spanner, define una columna de clave primaria de UUID como STRING o TEXT escribe y asigna GENERATE_UUID() (GoogleSQL o PostgreSQL) como su valor predeterminado. Migrar todos los de la base de datos de origen a Spanner. Después de la migración, como se insertan filas nuevas, Spanner llama a GENERATE_UUID() para generar valores de UUID nuevos para las claves primarias. Por ejemplo, la clave primaria FanClubId obtiene un valor UUIDv4 cuando se inserta una fila nueva en la tabla FanClubs. Usa el siguiente código en Spanner:

GoogleSQL

CREATE TABLE Fanclubs (
FanClubId STRING(36) DEFAULT (GENERATE_UUID()),
ClubName STRING(1024),
) PRIMARY KEY (FanClubId);

INSERT INTO FanClubs (ClubName) VALUES ("SwiftFanClub");

PostgreSQL

CREATE TABLE FanClubs (
  FanClubId TEXT DEFAULT spanner.generate_uuid() PRIMARY KEY,
  ClubName VARCHAR(1024)
);

INSERT INTO FanClubs (ClubName) VALUES ('SwiftFanClub');

Cómo migrar tus propias claves primarias

Tu aplicación puede basarse en el orden de la clave primaria para determinar qué tan reciente fue la o para secuenciar datos recién creados. Para usar imágenes generadas de forma externa claves secuenciales en Spanner, puedes crear una clave compuesta que combina un valor distribuido de manera uniforme, como un hash, como el primer y tu clave secuencial como el segundo componente. De esta manera, puedes conservar los pares clave-valor secuenciales sin crear hotspots a gran escala. Considera el siguiente flujo de trabajo de migración:

Supongamos que necesitas migrar una tabla de MySQL students con un Clave primaria AUTO_INCREMENT para Spanner. Usa el siguiente código en tu base de datos de MySQL de origen:

MySQL

CREATE TABLE Students (
StudentId INT NOT NULL AUTO_INCREMENT,
Info VARCHAR(2048),
PRIMARY KEY (StudentId)
);

En Spanner, puedes agregar una columna generada StudentIdHash creando un hash de la columna StudentId. Por ejemplo:

  StudentIdHash = FARM_FINGERPRINT(CAST(StudentId AS STRING))

Puedes usar el siguiente código en Spanner:

GoogleSQL

CREATE TABLE student (
  StudentIdHash INT64 AS (FARM_FINGERPRINT(cast(StudentId as string))) STORED,
  StudentId INT64 NOT NULL,
  Info STRING(2048),
) PRIMARY KEY(StudentIdHash, StudentId);

PostgreSQL

CREATE TABLE Student (
  StudentIdHash bigint GENERATED ALWAYS AS
  (FARM_FINGERPRINT(cast(StudentId AS varchar))) STORED,
  StudentId bigint NOT NULL,
  Info varchar(2048),
  PRIMARY KEY (StudentIdHash, StudentId)
);

¿Qué sigue?