En esta página, se describe cómo migrar claves primarias de las tablas de la base de datos de origen a las bases de datos de dialecto de GoogleSQL y de dialecto de PostgreSQL de Spanner. Antes de realizar los procedimientos de la página, revisa la Descripción general de la migración de claves primarias.
Antes de comenzar
-
Para obtener los permisos que necesitas para migrar claves primarias a Spanner, pídele a tu administrador que te otorgue el rol de IAM de administrador de bases de datos de Cloud Spanner (
roles/spanner.databaseAdmin) en tu instancia.
Migra claves secuenciales generadas automáticamente
Si realizas la migración desde una base de datos que usa claves monotónicas secuenciales, como
AUTO_INCREMENT
en MySQL, SERIAL
en PostgreSQL o el tipo IDENTITY estándar en SQL Server o
Oracle, considera la siguiente estrategia de migración de alto nivel:
- En Spanner, replica la estructura de la tabla de tu base de datos de origen con una clave primaria entera.
- Para cada columna de Spanner que contenga valores secuenciales,
crea una secuencia y asigna la
GET_NEXT_SEQUENCE_VALUE( GoogleSQL, PostgreSQL) función como el valor predeterminado de la columna. - Migra los datos existentes con claves originales de la base de datos de origen a Spanner. Considera usar la herramienta de migración de Spanner o una plantilla de
Dataflow.
- De manera opcional, puedes establecer restricciones de clave externa para cualquier tabla dependiente .
- Antes de insertar datos nuevos, ajusta la secuencia de Spanner para omitir el rango de valores de clave existentes.
- Inserta datos nuevos, lo que permite que la secuencia genere claves únicas de forma automática.
Flujo de trabajo de migración de muestra
El siguiente código define la estructura de la tabla y la secuencia relacionada en
Spanner con un SEQUENCE
objeto y establece el objeto como el valor primario 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 la secuencia son de tipo INT64, son mayores que cero y no son secuenciales.
A medida que migras filas existentes de tu base de datos de origen a Spanner, las claves primarias permanecen sin cambios.
Para las inserciones nuevas que no especifican una clave primaria, Spanner
recupera automáticamente un valor nuevo llamando a la función GET_NEXT_SEQUENCE_VALUE(GoogleSQL
o PostgreSQL)
.
Estos valores se distribuyen de manera uniforme en el rango
[1, 263] y podría haber posibles colisiones con las
claves existentes. Para evitar esto, puedes configurar la secuencia con ALTER_SEQUENCE
(GoogleSQL
o PostgreSQL)
para omitir el rango de valores cubiertos por las claves existentes.
Supongamos que la tabla singers se migró desde PostgreSQL, donde su clave primaria singer_id es de tipo SERIAL. El siguiente código de PostgreSQL muestra el DDL de tu base de datos de origen:
PostgreSQL
CREATE TABLE Singers ( SingerId SERIAL PRIMARY KEY, Name varchar(1024), Biography varchar );
Los valores de la clave primaria aumentan de forma monotónica. 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;
Supongamos que el valor que se muestra es 20,000. Puedes configurar la secuencia de Spanner para omitir el rango [1, 21000]. Los 1,000 adicionales sirven como búfer para admitir escrituras en la base de datos de origen después de la migración inicial. Las claves nuevas 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 tu base de datos de origen
Puedes usar el concepto de rango de omisión para admitir situaciones en las que Spanner o tu base de datos de origen generan claves primarias, por ejemplo, para habilitar la replicación en cualquier dirección para la recuperación ante desastres durante una migración de sistemas.
Para admitir esto, ambas bases de datos generan claves primarias y los datos se sincronizan entre ellas. Puedes configurar cada base de datos para crear claves primarias en rangos de claves que no se superpongan. Cuando defines un rango para tu base de datos de origen, puedes configurar la secuencia de Spanner para que omita ese rango.
Por ejemplo, después de la migración de la aplicación de pistas de música, replica los datos de PostgreSQL a Spanner para reducir el tiempo que lleva realizar el cambio.
Después de actualizar y probar la aplicación en Spanner, puedes dejar de usar tu base de datos PostgreSQL de origen y usar Spanner, lo que la convierte en el sistema de registros para las actualizaciones y las claves primarias nuevas. Cuando Spanner se hace cargo, puedes invertir el flujo de datos entre las bases de datos en la instancia de PostgreSQL.
Supongamos que tu base de datos PostgreSQL de origen usa claves primarias SERIAL, que son números enteros con signo de 32 bits. Las claves primarias de Spanner son números más grandes de 64 bits. En PostgreSQL, modifica 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 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 PostgreSQL
de origen para asegurarte de que los valores de la clave primaria SingerId siempre sean menores
o iguales que 231-1.
Usa el siguiente código en tu base de datos PostgreSQL de origen:
PostgreSQL
ALTER TABLE Singers ADD CHECK (SingerId <= 2147483647);
En Spanner, podemos modificar la secuencia para omitir el
[1, 231-1] rango.
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;
Tu base de datos PostgreSQL de origen siempre genera claves en el espacio de números enteros de 32 bits, mientras que las claves de Spanner se restringen al espacio de números enteros de 64 bits, que es más grande que todos los valores de números enteros de 32 bits. Esto garantiza que ambas bases de datos puedan generar de forma independiente claves primarias que no entren en conflicto.
Migra columnas de clave UUID
Las claves UUIDv4 son efectivamente únicas, independientemente de dónde se generen. Las claves UUID generadas en otro lugar se integran con las claves UUID nuevas generadas en Spanner.
Considera la siguiente estrategia de alto nivel para migrar claves UUID a Spanner:
- Define tus claves UUID en Spanner con columnas de cadena con una expresión predeterminada. Usa la función
GENERATE_UUID()(GoogleSQL, PostgreSQL). - Exporta los datos del sistema de origen y serializa las claves UUID como cadenas.
- Importa las claves primarias a Spanner.
- Opcional: Habilita las claves externas.
A continuación, se muestra un flujo de trabajo de migración de muestra:
En Spanner, define una columna de clave primaria UUID como un tipo STRING o
TEXT y asigna GENERATE_UUID()
(GoogleSQL
o
PostgreSQL)
como su valor predeterminado. Migra todos los datos de tu base de datos de origen a Spanner. Después de la migración, a medida que se insertan filas nuevas, Spanner llama a GENERATE_UUID() para generar valores 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');
Migra tus propias claves primarias
Es posible que tu aplicación dependa del orden de la clave primaria para determinar qué tan recientes son los datos o para secuenciar los datos recién creados. Para usar claves secuenciales generadas de forma externa en Spanner, puedes crear una clave compuesta que combine un valor distribuido de manera uniforme, como un hash, como el primer componente y tu clave secuencial como el segundo componente. De esta manera, puedes conservar los valores de clave secuenciales sin crear puntos de acceso a gran escala. Considera el siguiente flujo de trabajo de migración:
Supongamos que necesitas migrar una tabla students de MySQL con una clave primaria AUTO_INCREMENT a Spanner. Usa el siguiente código en tu base de datos 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 by
creando un hash de la StudentId columna. 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) );
Migra columnas de clave secuencial
Si tu sistema de base de datos de origen genera valores secuenciales para una columna de clave, puedes usar una secuencia positiva invertida en bits (GoogleSQL, PostgreSQL) en tu esquema de Spanner para generar valores que se distribuyan de manera uniforme en el espacio de números enteros positivos de 64 bits. Para evitar que la secuencia de Spanner genere un valor que se superponga con un valor migrado, puedes definir un rango omitido para ella.
Por ejemplo, puedes omitir el rango de 1 a 4,294,967,296 (2^32) para las siguientes dos secuencias, si sabes que la base de datos de origen solo genera números enteros de 32 bits:
GoogleSQL
CREATE SEQUENCE MyFirstSequence OPTIONS ( sequence_kind = "bit_reversed_positive", skip_range_min = 1, skip_range_max = 4294967296 ); ALTER SEQUENCE MySecondSequence SET OPTIONS ( skip_range_min = 1, skip_range_max = 4294967296 );
PostgreSQL
CREATE SEQUENCE MyFirstSequence BIT_REVERSED_POSITIVE SKIP RANGE 1 4294967296; ALTER SEQUENCE MySecondSequence SKIP RANGE 1 4294967296;
Si usas IDENTITY
columnas para
generar automáticamente valores enteros para tus columnas de clave, puedes establecer rangos de
omisión:
GoogleSQL
Para establecer un rango de omisión, usa el
GENERATED BY DEFAULT AS IDENTITY
comando:
ALTER DATABASE db SET OPTIONS (
default_sequence_kind = 'bit_reversed_positive',
);
CREATE TABLE MyFirstTable (
Id INT64 GENERATED BY DEFAULT AS IDENTITY (SKIP RANGE 1, 4294967296),
Name STRING(MAX),
) PRIMARY KEY (Id);
ALTER TABLE MyFirstTable ALTER COLUMN Id ALTER IDENTITY SET SKIP RANGE 1, 4294967296;
PostgreSQL
Para establecer un rango de omisión, usa el
GENERATED BY DEFAULT AS IDENTITY
comando:
ALTER DATABASE db
SET spanner.default_sequence_kind = 'bit_reversed_positive';
CREATE TABLE MyFirstTable (
Id bigint GENERATED BY DEFAULT AS IDENTITY (SKIP RANGE 1 4294967296),
Name text,
PRIMARY KEY (Id)
);
ALTER TABLE MyFirstTable ALTER COLUMN Id SET SKIP RANGE 1 4294967296;
Migra columnas de clave invertida en bits
Si ya invertiste en bits tus valores de clave para evitar problemas de puntos de acceso en tu base de datos de origen, también puedes usar una secuencia positiva invertida en bits de Spanner (GoogleSQL, PostgreSQL) para seguir generando esos valores. Para evitar generar valores duplicados, puedes configurar la secuencia para que inicie su contador desde un número personalizado.
Por ejemplo, si invertiste números del 1 al 1,000 para generar valores de clave primaria, la secuencia de Spanner puede iniciar su contador desde cualquier número mayor que 10,000. De manera opcional, puedes elegir un número alto para dejar un búfer para las escrituras nuevas que se producen en la base de datos de origen después de la migración de datos. En el siguiente ejemplo, los contadores comienzan en 11,000:
GoogleSQL
CREATE SEQUENCE MyFirstSequence OPTIONS ( sequence_kind = "bit_reversed_positive", start_with_counter = 11000 ); ALTER SEQUENCE MySecondSequence SET OPTIONS ( start_with_counter = 11000 );
PostgreSQL
CREATE SEQUENCE MyFirstSequence BIT_REVERSED_POSITIVE START COUNTER 11000; ALTER SEQUENCE MySecondSequence RESTART COUNTER 11000;
Si usas IDENTITY
columnas para
generar automáticamente valores enteros para tus columnas de clave, puedes establecer un contador de inicio:
GoogleSQL
Para establecer un contador de inicio, usa el
GENERATED BY DEFAULT AS IDENTITY
comando:
ALTER DATABASE db SET OPTIONS (
default_sequence_kind = 'bit_reversed_positive',
);
CREATE TABLE MyFirstTable (
Id INT64 GENERATED BY DEFAULT AS IDENTITY (START COUNTER WITH 11000),
Name STRING(MAX),
) PRIMARY KEY (Id);
ALTER TABLE MyFirstTable ALTER COLUMN Id ALTER IDENTITY RESTART COUNTER WITH 11000;
PostgreSQL
Para establecer un contador de inicio, usa el
GENERATED BY DEFAULT AS IDENTITY
comando:
ALTER DATABASE db
SET spanner.default_sequence_kind = 'bit_reversed_positive';
CREATE TABLE MyFirstTable (
Id bigint GENERATED BY DEFAULT AS IDENTITY (START COUNTER WITH 11000),
Name text,
PRIMARY KEY (Id)
);
ALTER TABLE MyFirstTable ALTER COLUMN Id RESTART COUNTER WITH 11000;