Migrer de MySQL vers Spanner

Cet article explique comment migrer votre base de données OLTP (Online Transactional Processing) de MySQL vers Spanner.

Contraintes de migration

Cloud Spanner utilise certains concepts différemment des autres outils de gestion de base de données d'entreprise. Par conséquent, vous devrez peut-être ajuster l'architecture de votre application pour tirer pleinement parti de ses fonctionnalités. Vous devrez peut-être également compléter Cloud Spanner avec d'autres services Google Cloud pour répondre à vos besoins.

Procédures et déclencheurs stockés

Cloud Spanner n'est pas compatible avec l'exécution de code utilisateur au niveau de la base de données. Par conséquent, dans le cadre de la migration, la logique métier mise en œuvre par les procédures et les déclencheurs stockés au niveau de la base de données doit être déplacée dans l'application.

Séquences

Spanner vous recommande d'utiliser l'UUID version 4 comme méthode par défaut pour générer des valeurs de clé primaire. La fonction GENERATE_UUID() (GoogleSQL, PostgreSQL) renvoie les valeurs de l'UUID version 4 représentées par le type STRING.

Si vous devez générer des valeurs entières, Spanner accepte les séquences positives inversées sur les bits (GoogleSQL, PostgreSQL), qui produisent des valeurs qui se répartissent uniformément dans l'espace de nombres positifs de 64 bits. Vous pouvez utiliser ces numéros pour éviter les problèmes de hotspotting.

Pour en savoir plus, consultez la section Stratégies pour la valeur par défaut de la clé primaire.

Contrôle des accès

Spanner permet un contrôle précis des accès au niveau des tables et des colonnes. Il n'est pas possible de contrôler précisément les accès aux vues. Pour en savoir plus, consultez la section À propos du contrôle ultraprécis des accès.

Contraintes de validation des données

Cloud Spanner n'accepte qu'un ensemble limité de contraintes de validation des données dans la couche de base de données. Si vous avez besoin de contraintes de données plus complexes, vous devez les mettre en œuvre dans la couche d'application.

Le tableau suivant décrit les types de contraintes fréquemment rencontrés dans les bases de données MySQL et explique comment les mettre en œuvre avec Cloud Spanner.

Contrainte Mise en œuvre avec Spanner
Non nul Contrainte de colonne NOT NULL
Unique Index secondaire avec contrainte UNIQUE
Foreign key (pour les tables standards) Consultez la page Créer et gérer des relations avec des clés étrangères.
Actions ON DELETE/ON UPDATE de la clé étrangère Possible uniquement pour les tables entrelacées, sinon, mise en œuvre dans la couche d'application
Vérification de la valeur et validation par le biais de contraintes CHECK Consultez la page Créer et gérer des contraintes de vérification.
Vérification de la valeur et validation par le biais de déclencheurs Mis en œuvre dans la couche d'application

Colonnes générées

Spanner accepte les colonnes générées pour lesquelles la valeur de la colonne est toujours générée par une fonction fournie dans le cadre de la définition de table. Comme dans MySQL, les colonnes générées ne peuvent pas être définies explicitement sur une valeur fournie dans une instruction LMD.

Les colonnes générées sont définies dans le cadre de la définition de colonne lors d'une instruction LDD (langage de définition de données) CREATE TABLE ou ALTER TABLE. Le mot clé AS est suivi d'une fonction SQL valide et du mot clé suffixe obligatoire STORED. Le mot clé STORED fait partie de la spécification ANSI SQL. Il indique que les résultats de la fonction seront stockés avec les autres colonnes de la table.

La fonction SQL, l'expression de génération, peut inclure toute expression, fonction et opérateur déterministe et peut être utilisée dans des index secondaires ou en tant que clé étrangère.

Pour plus d'information sur la gestion de ce type de colonne, consultez la page Créer et gérer des colonnes générées.

Types de données acceptés

MySQL et Spanner acceptent différents ensembles de types de données. Le tableau ci-dessous répertorie les types de données MySQL et leur équivalent dans Cloud Spanner. Pour obtenir des définitions détaillées de chaque type de données Spanner, consultez la section Types de données.

Vous devrez peut-être transformer davantage vos données, comme indiqué dans la colonne "Notes", pour que les données MySQL puissent s'intégrer dans votre base de données Spanner. Par exemple, vous pouvez stocker un BLOB volumineux en tant qu'objet dans un bucket Cloud Storage plutôt que dans la base de données, puis stocker la référence URI de l'objet Cloud Storage dans la base de données sous forme de STRING.

Type de donnée MySQL Équivalent dans Spanner Notes
INTEGER, INT, BIGINT MEDIUMINT, SMALLINT INT64
TINYINT, BOOL, BOOLEAN BOOL, INT64 Les valeurs TINYINT(1) représentent les valeurs booléennes "true" (différent de zéro) ou "false" (0).
FLOAT, DOUBLE FLOAT64
DECIMAL, NUMERIC NUMERIC, STRING Dans MySQL, les types de données NUMERIC et DECIMAL acceptent jusqu'à 65 chiffres dans les paramètres de précision et d'échelle, comme défini dans la déclaration de colonne. Le type de données Spanner NUMERIC accepte jusqu'à 38 chiffres dans les paramètres de précision et 9 chiffres décimaux dans les paramètres d'échelle.
Si vous avez besoin d'une plus grande précision, consultez la section Stocker des données numériques de précision arbitraire pour découvrir d'autres mécanismes.
BIT BYTES
DATE DATE Cloud Spanner et MySQL utilisent tous deux le format "yyyy-mm-dd" pour les dates. Aucune transformation n'est donc nécessaire. Les fonctions SQL sont fournies pour convertir les dates en une chaîne formatée.
DATETIME TIMESTAMP TIMESTAMP Cloud Spanner stocke l'heure indépendamment du fuseau horaire. Si vous devez stocker un fuseau horaire, vous devez utiliser une colonne STRING distincte. Les fonctions SQL permettent de convertir les horodatages en chaînes formatées utilisant les fuseaux horaires.
CHAR VARCHAR STRING Remarque : Cloud Spanner utilise des chaînes Unicode.
Le type VARCHAR accepte une longueur maximale de 65 535 octets, tandis que Cloud Spanner accepte jusqu'à 2 621 440 caractères.
BINARY, VARBINARY, BLOB, TINYBLOB BYTES Les petits objets (moins de 10 Mio) peuvent être stockés sous forme de BYTES. Pensez à utiliser des offres Google Cloud alternatives, comme Cloud Storage, pour stocker des objets plus volumineux.
TEXT, TINYTEXT, ENUM STRING Les petites valeurs TEXT (moins de 10 Mio) peuvent être stockées sous forme de STRING. Pensez à utiliser des offres Google Cloud alternatives, telles que Cloud Storage, pour accepter des valeurs TEXT plus importantes.
ENUM STRING La validation des valeurs ENUM doit être effectuée dans l'application.
SET ARRAY<STRING> La validation des valeurs des éléments SET doit être effectuée dans l'application.
LONGBLOB, MEDIUMBLOB BYTES ou STRING contenant l'URI vers l'objet Les petits objets (moins de 10 Mio) peuvent être stockés sous forme de BYTES. Pensez à utiliser des offres Google Cloud alternatives, telles que Cloud Storage, pour stocker des objets plus volumineux.
LONGTEXT, MEDIUMTEXT STRING (contenant des données ou un URI pour un objet externe) Les petits objets (moins de 2 621 440 caractères) peuvent être stockés sous forme de STRING. Pensez à utiliser des offres Google Cloud alternatives, telles que Cloud Storage, pour stocker des objets plus volumineux.
JSON JSON Les petites chaînes JSON (moins de 2 621 440 caractères) peuvent être stockées sous forme de JSON. Pensez à utiliser des offres Google Cloud alternatives, telles que Cloud Storage, pour stocker des objets plus volumineux.
GEOMETRY, POINT, LINESTRING, POLYGON, MULTIPOINT, MULTIPOLYGON, GEOMETRYCOLLECTION Cloud Spanner n'accepte pas les données de type géospatial. Vous devez stocker ces données à l'aide de types de données standards et mettre en œuvre une logique de recherche/filtrage dans la couche d'application.

Processus de migration

La chronologie générale de votre processus de migration peut se décomposer ainsi :

  1. Convertissez votre schéma et votre modèle de données.
  2. Traduisez les requêtes SQL.
  3. Migrez votre application pour utiliser Cloud Spanner en plus de MySQL.
  4. Exportez vos données de manière groupée à partir de MySQL et importez-les dans Cloud Spanner à l'aide de Cloud Dataflow.
  5. Maintenez la cohérence entre les deux bases de données lors de votre migration.
  6. Migrez votre application hors de MySQL.

Étape 1: Convertissez votre base de données et votre schéma

Convertissez votre schéma existant en un schéma Cloud Spanner pour stocker vos données. Afin de simplifier les modifications d'application, assurez-vous que le schéma converti correspond le plus fidèlement possible au schéma MySQL existant. Cependant, en raison des différences de fonctionnalités, certaines modifications peuvent être nécessaires.

L'utilisation des bonnes pratiques de conception de schéma peut vous aider à augmenter le débit et à réduire les hotspots dans votre base de données Cloud Spanner.

Clés primaires

Dans Spanner, chaque table devant stocker plusieurs lignes doit avoir une clé primaire composée d'une ou de plusieurs colonnes de la table. La clé primaire de votre table identifie de manière unique chaque ligne d'une table, et Spanner utilise la clé primaire pour trier les lignes de la table. Spanner étant hautement distribué, il est important de choisir une technique de génération de clé primaire qui s'adapte bien à la croissance de vos données. Pour en savoir plus, consultez les stratégies de migration de clé primaire que nous recommandons.

Notez qu'après avoir désigné votre clé primaire, vous ne pouvez pas ajouter ni supprimer de colonne de clé primaire, ni modifier une valeur de clé primaire sans supprimer et recréer la table. Pour savoir comment désigner votre clé primaire, consultez Schéma et modèle de données – clés primaires.

Entrelacer vos tables

Cloud Spanner propose une fonctionnalité dans laquelle vous pouvez définir deux tables comme ayant une relation parent/enfant de un à plusieurs. Cette fonctionnalité entrelace les lignes de données enfants à côté de leur ligne parente dans le stockage. L'entrelacement signifie que les tables sont préjointes, ce qui permet d'améliorer l'efficacité de la récupération des données lorsque le parent et les enfants sont recherchés ensemble.

La clé primaire de la table enfant doit commencer par la ou les colonnes de clé primaire de la table parente. Du point de vue de la ligne enfant, la clé primaire de la ligne parente est appelée clé étrangère. Vous pouvez définir jusqu'à six niveaux de relations parent-enfant.

Vous pouvez définir des actions lors de la suppression pour les tables enfants afin de déterminer ce qui se passe lorsque la ligne parente est supprimée : soit toutes les lignes enfants sont supprimées, soit la suppression de la ligne parente est bloquée tant qu'il existe des lignes enfants.

Voici un exemple de création d'une table Albums entrelacée dans la table parente Singers définie précédemment :

CREATE TABLE Albums (
  SingerId     INT64 NOT NULL,
  AlbumId      INT64 NOT NULL,
  AlbumTitle   STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId)
INTERLEAVE IN PARENT (Singers)
ON DELETE CASCADE;

Créer des index secondaires

Vous pouvez également créer des index secondaires pour indexer des données dans la table en dehors de la clé primaire. Cloud Spanner met en œuvre les index secondaires de la même manière que les tables, de sorte que les valeurs de colonne à utiliser comme clés d'index auront les mêmes contraintes que les clés primaires des tables. Cela signifie également que les index ont la même garantie de cohérence que les tables Spanner.

Les recherches de valeurs utilisant des index secondaires sont en réalité les mêmes que les requêtes avec jointure de table. Vous pouvez améliorer les performances des requêtes utilisant des index en stockant des copies des valeurs de colonne de la table d'origine dans l'index secondaire à l'aide de la clause STORING, ce qui en fait un index de couverture.

L'optimiseur de requêtes de Cloud Spanner n'utilise automatiquement un index secondaire que lorsque l'index stocke lui-même toutes les colonnes interrogées (une requête couverte). Pour forcer l'utilisation d'un index lors de la recherche de colonnes dans la table d'origine, vous devez utiliser une directive FORCE INDEX dans l'instruction SQL, par exemple :

SELECT *
FROM MyTable@{FORCE_INDEX=MyTableIndex}
WHERE IndexedColumn=@value

Les index peuvent être utilisés pour imposer des valeurs uniques dans une colonne de table en définissant un index UNIQUE sur cette colonne. L'index empêchera l'ajout de valeurs en double.

Voici un exemple d'instruction DDL créant un index secondaire pour la table Albums :

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

Si vous créez des index supplémentaires après le chargement de vos données, le remplissage de l'index peut prendre un certain temps. Nous vous recommandons de limiter la fréquence à laquelle vous les ajoutez à une moyenne de trois par jour. Pour obtenir plus de conseils sur la création d'index secondaires, consultez la section Index secondaires. Pour en savoir plus sur les limitations relatives à la création d'index, consultez la section Mises à jour de schémas.

Étape 2: Traduisez des requêtes SQL

Cloud Spanner utilise le dialecte SQL ANSI 2011 avec extensions et dispose de nombreux opérateurs et fonctions pour vous permettre de traduire et d'agréger vos données. Toutes les requêtes SQL utilisant un dialecte, des fonctions et des types spécifiques à MySQL devront être converties pour être compatibles avec Cloud Spanner.

Même si Cloud Spanner n'accepte pas les données structurées en tant que définitions de colonne, vous pouvez utiliser des données structurées dans les requêtes SQL à l'aide des types ARRAY<> et STRUCT<>. Par exemple, vous pouvez écrire une requête qui renvoie tous les albums d’un artiste à l’aide d'un tableau (ARRAY) de STRUCT (en tirant parti des données préjointes). Consultez la section Sous-requêtes de la documentation pour en savoir plus.

Les requêtes SQL peuvent être profilées à l'aide de la page Spanner Studio de la console Google Cloud pour exécuter la requête. En général, les requêtes qui effectuent des analyses complètes de tables sur des tables volumineuses sont très coûteuses et doivent être utilisées avec parcimonie. Pour en savoir plus sur l'optimisation des requêtes SQL, consultez la documentation relative aux bonnes pratiques SQL.

Étape 3: Migrez votre application pour utiliser Spanner

Cloud Spanner fournit un ensemble de bibliothèques clientes pour différents langages, ainsi que la possibilité de lire et d'écrire des données en utilisant des appels d'API spécifiques à Spanner, ou bien des requêtes SQL et des instructions LMD (langage de manipulation de données). L'utilisation d'appels d'API peut être plus rapide pour certaines requêtes, telles que les lectures directes de lignes par clé, car il n'est pas nécessaire de traduire l'instruction SQL.

Vous pouvez également utiliser le pilote JDBC (Java DataBase Connectivity) pour vous connecter à Cloud Spanner, en exploitant les outils et l'infrastructure existants dépourvus d'intégration native.

Dans le cadre du processus de migration, les fonctionnalités non disponibles dans Cloud Spanner, telles que mentionnées ci-dessus, doivent être mises en œuvre dans l'application. Par exemple, un déclencheur permettant de vérifier les valeurs de données et de mettre à jour une table associée devrait être mis en œuvre dans l'application à l'aide d'une transaction de lecture/écriture pour lire la ligne existante, vérifier la contrainte, puis écrire les lignes mises à jour dans les deux tables.

Cloud Spanner propose des transactions en lecture/écriture et en lecture seule, qui garantissent la cohérence externe de vos données. De plus, des limites d'horodatage peuvent être appliquées aux transactions en lecture si vous lisez une version cohérente des données :

  • à une heure exacte dans le passé (jusqu'à il y a une heure) ;
  • dans l’avenir (où la lecture bloquera jusqu'au moment indiqué) ;
  • avec une limite acceptable d'obsolescence, ce qui retournera une vue cohérente jusqu’à un certain moment sans qu’il soit nécessaire de vérifier que des données ultérieures sont disponibles sur une autre instance dupliquée. Cela peut améliorer les performances au détriment de données éventuellement obsolètes.

Étape 4: Transférez vos données de MySQL vers Spanner

Pour transférer vos données de MySQL vers Cloud Spanner, vous devez exporter votre base de données MySQL vers un format de fichier portable, par exemple XML, puis importer ces données dans Cloud Spanner à l'aide de Cloud Dataflow.

Transfert de données de MySQL vers Cloud Spanner

Exportation groupée depuis MySQL

L'outil mysqldump fourni avec MySQL est capable d'exporter la totalité de la base de données dans des fichiers XML correctement formatés. Vous pouvez également vous servir de l'instruction SQL SELECT ... INTO OUTFILE pour créer des fichiers CSV pour chaque table. Cependant, cette approche présente l'inconvénient de ne pouvoir exporter qu'une seule table à la fois, ce qui signifie que vous devez mettre en pause votre application ou suspendre votre base de données afin que son état reste cohérent pour l'exportation.

Après avoir exporté ces fichiers de données, nous vous recommandons de les télécharger dans un bucket Cloud Storage afin qu'ils soient accessibles pour l'importation.

Importer de manière groupée dans Spanner

Étant donné que les schémas de base de données diffèrent probablement entre MySQL et Cloud Spanner, vous devrez peut-être inclure certaines conversions de données dans le processus d'importation. Le moyen le plus simple d'effectuer ces conversions et d'importer les données dans Cloud Spanner consiste à utiliser Cloud Dataflow. Cloud Dataflow est le service d'extraction, de transformation et de chargement (ETL) distribué de Google Cloud. Il fournit une plate-forme pour l'exécution de pipelines de données écrits à l'aide du SDK Apache Beam afin de lire et de traiter de grandes quantités de données en parallèle sur plusieurs machines.

Le SDK Apache Beam nécessite l’écriture d’un programme Java simple permettant de définir la lecture, la transformation et l’écriture des données. Des connecteurs Beam existent pour Cloud Storage et Cloud Spanner. Le seul code que vous devez écrire est donc la transformation de données elle-même.

Pour obtenir un exemple de pipeline simple qui lit des fichiers CSV et écrit dans Cloud Spanner, consultez l'exemple de dépôt de code.

Si vous utilisez des tables entrelacées parent-enfant dans votre schéma Cloud Spanner, veillez, lors du processus d'importation, à ce que la ligne parente soit créée avant la ligne enfant. Le code du pipeline d'importation Cloud Spanner résout ce problème en important d'abord toutes les données des tables de niveau racine, puis toutes les tables enfants de niveau 1, puis toutes les tables enfants de niveau 2, etc.

Vous pouvez utiliser directement le pipeline d'importation Cloud Spanner pour importer vos données de manière groupée, à condition qu'elles soient stockées dans des fichiers Avro utilisant le schéma approprié.

Étape 5: Maintenez la cohérence entre les deux bases de données

De nombreuses applications ont des exigences de disponibilité rendant impossible le maintien de l'application hors ligne pendant le temps nécessaire à l'exportation et l'importation des données. Par conséquent, pendant que vous transférez vos données vers Cloud Spanner, votre application continue à modifier la base de données existante. Il est donc nécessaire de dupliquer les mises à jour effectuées pendant l'exécution de l'application dans la base de données Cloud Spanner.

Il existe différentes méthodes pour synchroniser vos deux bases de données, par exemple la capture de données modifiées et la mise en œuvre de mises à jour simultanées dans l'application.

Capture de données modifiées

MySQL ne dispose pas d'utilitaire natif de capture de données modifiées (CDC, Change Data Capture). Cependant, plusieurs projets Open Source peuvent recevoir des binlogs MySQL et les convertir en flux CDC. Par exemple, l'application Maxwell's Daemon peut fournir un flux CDC pour votre base de données.

Vous pouvez écrire une application qui s'abonne à ce flux et applique les mêmes modifications (après la conversion des données, bien sûr) à votre base de données Cloud Spanner.

Mettre à jour les deux bases de données simultanément depuis l'application

Une autre méthode consiste à modifier votre application pour effectuer des écritures dans les deux bases de données. L'une d'entre elles (initialement MySQL) serait considérée comme source fiable. Après chaque écriture dans la base de données, la ligne entière est lue, convertie et écrite dans la base de données Cloud Spanner. De cette manière, l’application remplace en permanence les lignes de Cloud Spanner avec les données les plus à jour.

Lorsque vous êtes sûr que toutes vos données ont été transférées correctement, vous pouvez basculer la source fiable vers la base de données Cloud Spanner. Ce mécanisme permet d'effectuer un rollback si des problèmes sont détectés lors du passage à Cloud Spanner.

Vérifier la cohérence des données

Lorsque les données sont diffusées dans votre base de données Cloud Spanner, vous pouvez effectuer périodiquement une comparaison entre les données Cloud Spanner et les données MySQL pour vous assurer de leur cohérence. Vous pouvez valider la cohérence en interrogeant les deux sources de données et en comparant les résultats.

Vous pouvez utiliser Cloud Dataflow pour effectuer une comparaison détaillée sur des ensembles de données volumineux à l'aide de la transformation de jointure. Cette transformation prend deux ensembles de données disposant de clés et fait correspondre les valeurs par clé. Les valeurs correspondantes peuvent ensuite être comparées pour vérifier l'égalité. Vous pouvez effectuer cette vérification régulièrement jusqu'à ce que le niveau de cohérence corresponde à vos besoins.

Étape 6: Choisissez Spanner comme source fiable de votre application

Lorsque vous êtes sûr de la migration des données, vous pouvez basculer votre application pour utiliser Cloud Spanner comme source fiable. Si vous continuez à écrire les modifications dans la base de données MySQL, celle-ci restera à jour, laissant une possibilité de rollback en cas de problème.

Enfin, vous pouvez désactiver et supprimer le code de mise à jour de la base de données MySQL et arrêter cette dernière, désormais obsolète.

Exporter et importer des bases de données Spanner

Vous pouvez éventuellement exporter vos tables de Cloud Spanner vers un bucket Cloud Storage à l'aide d'un modèle Cloud Dataflow. Le dossier résultant contient un ensemble de fichiers Avro et de fichiers manifestes JSON contenant vos tables exportées. Ces fichiers peuvent avoir divers usages, y compris :

  • sauvegarder votre base de données pour la conformité aux règles de conservation des données ou la reprise après sinistre ;
  • importer le fichier Avro dans des offres Google Cloud alternatives telles que BigQuery.

Pour en savoir plus sur les processus d'exportation et d'importation, consultez les pages Exporter des bases de données et Importer des bases de données.

Étapes suivantes