Migrar chaves primárias

Este documento oferece instruções para migrar chaves primárias de suas tabelas de banco de dados de origem para o Spanner. Você precisa conhecer as informações disponíveis Visão geral da migração de chave primária.

Antes de começar

  • Para ter as permissões necessárias para migrar chaves primárias para o Spanner, peça ao administrador para conceder a você Papel do IAM Administrador de banco de dados do Cloud Spanner (roles/spanner.databaseAdmin) na instância.

Migrar chaves sequenciais geradas automaticamente

Se você estiver migrando de um banco de dados que usa chaves monotônicas sequenciais, como AUTO_INCREMENT no MySQL, SERIAL no PostgreSQL ou o tipo IDENTITY padrão no SQL Server ou Oracle, use a seguinte estratégia de migração de alto nível:

  1. No Spanner, replique a estrutura da tabela do banco de dados de origem, usando uma chave primária de número inteiro.
  2. Para cada coluna no Spanner que contém valores sequenciais, crie uma sequência e atribua o GET_NEXT_SEQUENCE_VALUE (GoogleSQL, PostgreSQL) como o valor padrão da coluna.
  3. Migrar dados existentes com chaves originais da origem no Spanner. Considere usar o Ferramenta de migração do Spanner ou um modelo do Dataflow.
  4. Como opção, é possível estabelecer restrições de chave estrangeira para qualquer das tabelas dependentes.
  5. Antes de inserir novos dados, ajuste o Spanner para pular o intervalo de chaves-valor existentes.
  6. Insira novos dados, permitindo que a sequência gere chaves exclusivas automaticamente.

Exemplo de fluxo de trabalho de migração

O código a seguir define a estrutura da tabela e a sequência relacionada na ao Spanner usando um SEQUENCE e define o objeto como o valor principal padrão da tabela 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)
);

A opção bit_reversed_positive indica que os valores gerados pelo são do tipo INT64, são maiores que zero e não são sequenciais.

Conforme você migra as linhas do seu banco de dados de origem para Spanner, as chaves primárias permanecem inalteradas.

Para novas inserções sem uma chave primária, o Spanner recupera automaticamente um novo valor chamando do GET_NEXT_SEQUENCE_VALUE()(GoogleSQL ou PostgreSQL) função.

Esses valores são distribuídos de maneira uniforme ao longo do intervalo [1, 263] e lá possíveis colisões com as chaves atuais. Para evitar isso, você pode configure a sequência usando ALTER_SEQUENCE (GoogleSQL ou PostgreSQL) para pular o intervalo de cobertos pelas chaves atuais.

Suponha que a tabela singers tenha sido migrada do PostgreSQL, onde a chave primária singer_id é do tipo SERIAL. O PostgreSQL a seguir mostra a DDL do banco de dados de origem:

PostgreSQL

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

Os valores das chave primária aumentam monotonicamente. Após a migração, é possível recuperar o valor máximo da chave primária singer_id no Spanner. Use o seguinte código no Spanner:

GoogleSQL

SELECT MAX(SingerId) FROM Singers;

PostgreSQL

SELECT MAX(SingerId) FROM Singers;

Suponha que o valor retornado seja 20.000. É possível configurar o Spanner para pular o intervalo [1, 21000]. Os 1.000 adicionais servem como para acomodar gravações no banco de dados de origem após a migração inicial. As novas chaves geradas no Spanner não entram em conflito com o intervalo de chaves primárias geradas no banco de dados PostgreSQL de origem. Use o seguinte código no Spanner:

GoogleSQL

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

PostgreSQL

ALTER SEQUENCE SingerIdSequence SKIP RANGE 1 21000;

Usar o Spanner e o banco de dados de origem

É possível usar o conceito de pular intervalo para oferecer suporte a cenários em que o Spanner ou o banco de dados de origem gere chaves primárias, por exemplo, para ativar a replicação em para a recuperação de desastres durante uma transição de migração.

Para isso, ambos os bancos de dados geram chaves primárias e os dados são sincronizados entre eles. É possível configurar cada banco de dados para criar chaves em intervalos não sobrepostos. Quando você define um intervalo para a origem no banco de dados, configure a sequência do Spanner para pular esse do intervalo 10.240.0.0/16.

Por exemplo, após a migração do aplicativo de faixas de música, replique o dados do PostgreSQL para o Spanner, reduzindo o tempo necessário cortada.

Depois de atualizar e testar o aplicativo no Spanner, é possível parar de usar o banco de dados PostgreSQL de origem e passar a usar o Spanner, tornando-o o sistema de registro para atualizações e novas chaves primárias. Quando o Spanner assumir o controle, será possível reverter o fluxo de dados entre os bancos de dados na instância do PostgreSQL.

Suponha que seu banco de dados PostgreSQL de origem use SERIAL chaves primárias, que são Números inteiros assinados de 32 bits. As chaves primárias do Spanner são maiores de 64 bits números grandes. No PostgreSQL, altere a coluna da chave primária para uma coluna de 64 bits, ou bigint. Use o seguinte código no banco de dados PostgreSQL de origem:

PostgreSQL

ALTER TABLE Singers ALTER COLUMN SingerId TYPE bigint;

É possível definir uma restrição CHECK para a tabela no banco de dados PostgreSQL de origem para garantir que os valores da chave primária SingerId sejam sempre menores ou igual a 231-1. Use o seguinte código no banco de dados PostgreSQL de origem:

PostgreSQL

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

No Spanner, é possível alterar a sequência para pular o intervalo [1, 231-1]. Use o seguinte código no 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;

Seu banco de dados PostgreSQL de origem sempre gera chaves no número inteiro de 32 bits enquanto as chaves do Spanner são restritas ao número inteiro de 64 bits, maior do que todos os valores inteiros de 32 bits. Isso garante que seus bancos de dados podem gerar de maneira independente chaves primárias que não entrem em conflito.

Migrar colunas de chave UUID

As chaves UUIDv4 são efetivamente exclusivas, independentemente de onde são geradas. As chaves UUID geradas em outros lugares se integram às novas chaves UUID geradas em no Spanner.

Considere a seguinte estratégia de alto nível para migrar Chaves UUID para o Spanner:

  1. Defina suas chaves UUID no Spanner usando colunas de string com um expressão padrão. Use o Função GENERATE_UUID() (GoogleSQL, PostgreSQL).
  2. Exporte os dados do sistema de origem, serializando as chaves UUID como strings.
  3. Importar as chaves primárias para o Spanner.
  4. Opcional: ative as chaves estrangeiras.

Este é um exemplo de fluxo de trabalho de migração:

No Spanner, defina uma coluna de chave primária UUID como STRING ou TEXT e atribua GENERATE_UUID() (GoogleSQL ou PostgreSQL) como valor padrão. Migre todos os do banco de dados de origem para o Spanner. Após a migração, como novas linhas são inseridas, o Spanner chama GENERATE_UUID() para gerar novos valores de UUID para as chaves primárias. Por exemplo, a chave primária FanClubId recebe um valor UUIDv4 quando uma nova linha é inserida na tabela FanClubs. Use o seguinte código no 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');

Migrar suas próprias chaves primárias

Seu aplicativo pode se basear na ordem da chave primária para determinar quão recente ou sequenciar dados recém-criados. Para usar recursos gerados externamente chaves sequenciais no Spanner, é possível criar uma chave composta que combina um valor distribuído de maneira uniforme, como um hash, como o primeiro e sua chave sequencial como o segundo componente. Assim, é possível preservar os valores-chave sequenciais sem criar pontos de acesso em escala. Considere o seguinte fluxo de trabalho de migração:

Suponha que você precise migrar uma tabela MySQL students com uma chave primária AUTO_INCREMENT para o Spanner. Use o seguinte código no banco de dados MySQL de origem:

MySQL

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

No Spanner, é possível adicionar uma coluna gerada StudentIdHash criando um hash de na coluna StudentId. Exemplo:

  StudentIdHash = FARM_FINGERPRINT(CAST(StudentId AS STRING))

É possível usar o seguinte código no 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)
);

A seguir