Migrer des clés primaires

Ce document explique comment migrer des clés primaires les tables de votre base de données source vers Spanner. Vous devez connaître les informations disponibles dans Présentation de la migration des clés primaires

Avant de commencer

  • Pour obtenir les autorisations nécessaires pour migrer des clés primaires vers Spanner, demandez à votre administrateur de vous accorder le Rôle IAM Administrateur de bases de données Cloud Spanner (roles/spanner.databaseAdmin) sur l'instance.

Migrer des clés séquentielles générées automatiquement

Si vous effectuez une migration à partir d'une base de données qui utilise des clés monotones séquentielles, telles que AUTO_INCREMENT dans MySQL, SERIAL dans PostgreSQL ou le type IDENTITY standard dans SQL Server ou Oracle, envisagez la stratégie de migration d'ordre général suivante :

  1. Dans Spanner, répliquez la structure de la table votre base de données source, à l'aide d'une clé primaire entière.
  2. Pour chaque colonne de Spanner contenant des valeurs séquentielles, créez une séquence et attribuez la fonction GET_NEXT_SEQUENCE_VALUE (GoogleSQL, PostgreSQL) comme valeur par défaut de la colonne.
  3. Migrer des données existantes avec des clés d'origine depuis la source dans Spanner. Envisagez d'utiliser le Outil de migration Spanner ou modèle Dataflow.
  4. Vous pouvez éventuellement contraintes de clé étrangère tables dépendantes.
  5. Avant d'insérer de nouvelles données, ajustez le paramètre Spanner pour ignorer la plage de valeurs-clés existantes.
  6. Insérer de nouvelles données, ce qui permet à la séquence de générer automatiquement des clés uniques.

Exemple de workflow de migration

Le code suivant définit la structure de la table et la séquence associée dans Spanner à l'aide d'un objet SEQUENCE, puis définit l'objet comme valeur primaire par défaut de la table de destination :

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)
);

L'option bit_reversed_positive indique que les valeurs générées par la séquence sont de type INT64, sont supérieures à zéro et ne sont pas séquentielles.

Lorsque vous migrez des lignes existantes de votre base de données source vers Spanner, les clés primaires restent inchangées.

Pour les nouvelles insertions sans clé primaire, Spanner récupère automatiquement une nouvelle valeur en appelant le GET_NEXT_SEQUENCE_VALUE()(GoogleSQL ou PostgreSQL) .

Ces valeurs sont distribuées uniformément sur la plage [1, 263], et des collisions peuvent se produire avec les clés existantes. Pour éviter cela, vous pouvez configurer la séquence en utilisant ALTER_SEQUENCE (GoogleSQL ou PostgreSQL) pour ignorer la plage de valeurs les valeurs couvertes par les clés existantes.

Supposons que la table singers ait été migrée depuis PostgreSQL, où sa clé primaire singer_id est de type SERIAL. Le code PostgreSQL suivant affiche le DDL de votre base de données source :

PostgreSQL

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

Les valeurs de la clé primaire augmentent de manière monotone. Après la migration, vous pouvez récupérer la valeur maximale de la clé primaire singer_id sur Spanner. Utilisez le code suivant dans Spanner :

GoogleSQL

SELECT MAX(SingerId) FROM Singers;

PostgreSQL

SELECT MAX(SingerId) FROM Singers;

Supposons que la valeur renvoyée est 20 000. Vous pouvez configurer Spanner pour ignorer la plage [1, 21000]. Les 1 000 autres servent de tampon pour gérer les écritures dans la base de données source après la migration initiale. Les nouvelles clés générées dans Spanner n'entrent pas en conflit avec la plage générées dans la base de données PostgreSQL source. Utilisez le code suivant dans Spanner :

GoogleSQL

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

PostgreSQL

ALTER SEQUENCE SingerIdSequence SKIP RANGE 1 21000;

Utiliser Spanner et votre base de données source

Vous pouvez utiliser le concept de plage d'omissions pour les scénarios dans lesquels Spanner ou votre base de données source génère des clés primaires, par exemple pour permettre la réplication dans la direction de la reprise après sinistre lors d'un basculement de migration.

Pour ce faire, les deux bases de données génèrent des clés primaires et les données sont synchronisés entre eux. Vous pouvez configurer chaque base de données pour créer des clés primaires dans des plages de clés non superposées. Lorsque vous définissez une plage pour votre source vous pouvez configurer la séquence Spanner la plage d'adresses IP.

Par exemple, après la migration de l'application des pistes musicales, dupliquez de PostgreSQL vers Spanner afin de réduire basculer.

Une fois que vous avez mis à jour et testé l'application sur Spanner, vous pouvez cesser d'utiliser votre base de données PostgreSQL source et utiliser Spanner, ce qui en fait le système d'enregistrement des mises à jour et des nouvelles clés primaires. Une fois que Spanner prend le relais, vous pouvez inverser le flux de données entre les bases de données dans l'instance PostgreSQL.

Supposons que votre base de données PostgreSQL source utilise des clés primaires SERIAL, qui sont Entiers signés de 32 bits. Les clés primaires Spanner sont des nombres de 64 bits plus grands. Dans PostgreSQL, définissez la colonne de clé primaire sur une colonne 64 bits ou bigint. Utilisez le code suivant sur votre base de données PostgreSQL source :

PostgreSQL

ALTER TABLE Singers ALTER COLUMN SingerId TYPE bigint;

Vous pouvez définir une contrainte CHECK sur la table de la base de données PostgreSQL source pour vous assurer que les valeurs de la clé primaire SingerId sont toujours inférieures à ou égale à 231-1. Utilisez le code suivant sur votre base de données PostgreSQL source:

PostgreSQL

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

Dans Spanner, nous pouvons modifier la séquence pour ignorer la plage [1, 231-1]. Utilisez le code suivant dans 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;

Votre base de données PostgreSQL source génère toujours des clés dans l'espace d'entiers 32 bits, tandis que les clés Spanner sont limitées à l'espace d'entiers 64 bits, plus grand que toutes les valeurs d'entiers 32 bits. Cela garantit à la fois les bases de données peuvent générer indépendamment des clés primaires qui n’entrent pas en conflit.

Migrer les colonnes de clé UUID

Les clés UUIDv4 sont effectivement uniques, quel que soit l'endroit où elles sont générées. Les clés UUID générées ailleurs s'intègrent aux nouvelles clés UUID générées dans Spanner.

Envisagez la stratégie générale suivante pour migrer les clés UUID vers Spanner :

  1. Définissez vos clés UUID dans Spanner à l'aide de colonnes de chaîne avec un par défaut. Utilisez les fonction GENERATE_UUID() (GoogleSQL, PostgreSQL).
  2. Exportez les données du système source en sérialisant les clés UUID sous forme de chaînes.
  3. Importez les clés primaires dans Spanner.
  4. Facultatif: activez les clés étrangères.

Voici un exemple de workflow de migration:

Dans Spanner, définissez une colonne de clé primaire UUID en tant que STRING ou TEXT et définissez GENERATE_UUID() (GoogleSQL ou PostgreSQL) comme valeur par défaut. Migrez tous les depuis votre base de données source vers Spanner. Après la migration, à mesure que de nouvelles lignes sont insérées, Spanner appelle GENERATE_UUID() pour générer de nouvelles valeurs UUID pour les clés primaires. Par exemple, la clé primaire FanClubId obtient une valeur UUIDv4 lorsqu'une nouvelle ligne est insérée dans la table FanClubs. Utilisez le code suivant dans 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');

Migrer vos propres clés primaires

Votre application peut s'appuyer sur l'ordre de la clé primaire pour déterminer la fraîcheur des données ou pour séquencer les données nouvellement créées. Pour utiliser des mots clés générés en externe séquentielles dans Spanner, vous pouvez créer une clé composite qui combine une valeur distribuée uniformément, comme un hachage, comme premier et votre clé séquentielle comme second composant. Vous pouvez ainsi conserver les valeurs de clé séquentielles, sans créer de points chauds à grande échelle. Voici le workflow de migration :

Supposons que vous deviez migrer une table MySQL students avec une clé primaire AUTO_INCREMENT vers Spanner. Utilisez le code suivant dans votre base de données MySQL source :

MySQL

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

Dans Spanner, vous pouvez ajouter une colonne générée StudentIdHash en créant un hachage de la colonne StudentId. Exemple :

  StudentIdHash = FARM_FINGERPRINT(CAST(StudentId AS STRING))

Vous pouvez utiliser le code suivant dans 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)
);

Étape suivante