Migrer avec les Foreign Data Wrappers

Atelier Migration FDW

Dalibo & Contributors

Introduction

Objectif de l’atelier

  • Découvrir les Foreign Data Wrappers
  • Connaître les outils de migration
  • Réaliser une migration de bout en bout

Déroulé de l’atelier

  • 3 heures
  • Travaux pratiques sur la base Sakila
    • Migration des tables et des données
    • Manipulation de l’extension db_migrator

Prérequis de l’atelier

  • Un terminal
  • Une VM Rocky Linux 8 ou équivalent
  • Compétences Linux et SQL
  • Une instance Docker au choix avec la base Sakila
    • MySQL (image mysql:8.2)
    • Oracle (image gvenzl/oracle-free:23-slim)
  • Une instance PostgreSQL 16

Foreign Data Wrappers

Historique

  • Norme ISO/IEC 9075-9 (révision 2003)
    • SQL/MED = SQL Management of External Data
    • Introduction des foreign-data wrappers et dblink
    • Système de bases de données fédérées

Implémentations de la norme SQL/MED dans PostgreSQL

  • 2009 (8.4) : Ajout de l’infrastructure pour SQL/MED

  • 2011 (9.1) : Tables externes en lecture seule, contribution file_fdw

  • 2013 (9.3) : Tables externes en écriture, contribution postgres_fdw

  • 2016 (9.5) : Support de l’instruction IMPORT FOREIGN SCHEMA

  • 2018 (11) : Routage des écritures pour les tables partitionnées

  • 2021 (14) : Optimisation des INSERT avec l’option batch_size, support des exécutions asynchrones

  • 2023 (16) : Prise en compte de l’option batch_size pour les instructions COPY

Syntaxe de création d’un serveur

CREATE EXTENSION postgres_fdw;

CREATE SERVER localhost FOREIGN DATA WRAPPER postgres_fdw
    OPTIONS (host '/tmp', dbname 'pagila', port '5432');

CREATE USER MAPPING FOR dalibo SERVER localhost
    OPTIONS (user 'dalibo', password '');

Syntaxe de création d’une table externe

CREATE FOREIGN TABLE public.films (
    film_id integer NOT NULL,
    title varchar(255) NOT NULL,
    description text
) SERVER localhost OPTIONS (
    schema_name 'public',
    table_name 'films'
);

ALTER FOREIGN TABLE public.films
    ALTER COLUMN description OPTIONS (
        column_name 'desc'
    );

Contributions de la communauté

Dans le domaine des systèmes relationnels

  • oracle_fdw : Laurenz Albe (Cybertec)
  • mysql_fdw : David Page, Ibrar Ahmed, Jeevan Chalke (EntrepriseDB)
  • tds_fdw : Geoff Montee, Julio González
  • db2_fdw : Wolfgang Brandl

Travaux pratiques #1

  • Installation des FDW
  • Configuration du serveur et de l’authentification
  • Import automatique avec IMPORT FOREIGN SCHEMA
  • Transfert des données avec INSERT

Installation

  • mysql_fdw disponible depuis le dépôt RPM classique

  • oracle_fdw disponible depuis le dépôt RPM « non-free »

    • Dépendance avec Oracle InstantClient

Configuration

  • À l’intérieur de la base PostgreSQL cible
  • Création de l’extension de son choix
  • Création du serveur avec la chaîne de connexion
  • Authentification

Import automatique des tables

  • Instruction IMPORT FOREIGN SCHEMA
    • importe les définitions d’une table d’une instance distante
    • collecte automatique des noms des tables et colonnes
    • correspondance du typage des colonnes entre les deux systèmes
    • prise en charge partielle des contraintes

Transfert des données

  • Transfert sans transformation
  • Transformation à la volée
    • Intervertir la position des colonnes
    • Ignorer une ou plusieurs colonnes
    • Changer l’encodage d’un texte
    • Appliquer une time zone
    • TP : colonne film.special_features

Bilan

  • Les types des colonnes peuvent ne pas être pertinents
    • … voire complétement ignorés lors d’un import automatique
  • Le transfert des données repose sur une instruction INSERT ... SELECT
    • Copie à l’identique
    • Transformation de données à la volée
    • Jointure complexe pour consolider plusieurs tables en une seule
    • … ou éclater une table en plusieurs
  • Uniquement les tables et leurs colonnes sont importées
    • Pas d’index
    • Pas de définition des vues
    • Pas de contrainte primaire, unique ou étrangère
    • Pas de procédures stockées ni de fonctions

Les outils de migration

Ora2pg

  • Génère les instructions DDL pour tous les schémas
    • Tables, partitions et colonnes compatibles avec PostgreSQL
    • Contraintes et index
    • Vues, vues matérialisées, fonctions
  • Exporte les données à travers les Foreign Data Wrappers
    • Disponible depuis la version 22.0 (août 2021)
    • Directive FDW_SERVER à renseigner
    • Gain observé de 30 à 40% sur le débit de transfert

db_migrator

  • Collections d’extensions entièrement en PL/pgSQL
    • ora_migrator (et oracle_fdw)
    • mysql_migrator (et mysql_fdw)
    • mssql_migrator (et tds_fdw)
  • Exporte la définition des objets d’un schéma dans un catalogue
  • Automatise les grandes étapes de migration
    • Transforme les tables externes en tables permanentes
    • Recrée les contraintes et les index
    • Reporte la définition des vues et fonctions (… sans les convertir)

Travaux pratiques #2

  • Installation de db_migrator et de ses plugins
  • Récupération et configuration du catalogue (snapshot)
  • Transfert des données avec db_migrate_tables
  • Création des vues, contraintes et index

Installation

  • Pas (encore) de paquets
  • Téléchargement de la version en développement
  • Déploiement avec CREATE EXTENSION

Récupération du catalogue distant

  • Méthode db_migrate_prepare
    • plugin : nom du plugin à utiliser
    • server : le nom du serveur à créer au préalable
    • staging_schema : emplacement des tables externes connectées au catalogue distant
    • pgstage_schema : emplacement du catalogue normalisé (ou snapshot)
    • only_schemas : liste des schémas distants à exporter
    • options (optionnel) : propre à chaque plugin

Création des tables externes

  • Méthode db_migrate_mkforeign
    • Création des schémas et des séquences au préalable
    • Une table externe pour chaque table à migrer
  • Correspond à l’instruction IMPORT FOREIGN SCHEMA
    • Renommage des noms des relations ou colonnes
    • Ajustement du type des colonnes

Transfert des données

  • Méthode db_migrate_tables
    • Réalise une boucle sur les tables à migrer
    • Matérialise les tables les unes après les autres
  • Méthode materialize_foreign_table
    • Créer la table (et ses partitions si requises)
    • Réalise le transfert avec des instructions INSERT
    • Détruit la table externe

Création des objets complexes

  • Fonctions et procédures avec db_migrate_functions
  • Triggers avec db_migrate_triggers
  • Vues avec db_migrate_views
  • Pas de conversion automatique

Création des index et des contraintes

  • Méthode db_migrate_indexes
    • construct_indexes_statements
  • Méthode db_migrate_constraints
    • construct_key_constraints_statements
    • construct_fkey_constraints_statements
    • construct_check_constraints_statements
    • construct_defaults_statements

Finaliser la migration

  • Méthode db_migrate_finish
    • Suppression des schémas internes
  • Retrait des extensions

Bilan

  • Les outils de migration sont bien plus complets
    • Ora2Pg est un client en Perl, clé en main
    • db_migrator est un framework en PL/pgSQL
  • db_migrator n’a pas encore trouvé son public
    • Contribuez !
    • Ouvrez des issues sur GitHub !
    • Créez des plugins !

Pour aller plus loin

  • Conférences de migrations aux PG Sessions et PG Day France
  • Articles de blog sur https://fljd.in
  • Formation MIGORPG dispensée par Dalibo
  • Guide de portage Oracle vers PostgreSQL

Questions ?