InnoDB : architecture et contraintes

InnoDB stocke chaque ligne sous forme de tuple contenant toutes les colonnes. Cette organisation rend la lecture d’une seule colonne aussi coûteuse que la lecture de toutes les colonnes, car le buffer pool charge le bloc complet. Les index sont implémentés comme des B‑tree séparés ; chaque écriture doit mettre à jour chaque B‑tree concerné, ce qui ralentit les charges d’ingestion massives. Le moteur utilise un journal d’annulation (undo log) pour permettre la lecture concurrente grâce au MVCC. Lors d’une mise à jour ou d’une suppression, l’ancienne version est conservée dans le journal jusqu’à ce que toutes les sessions antérieures se terminent, puis le journal est purgé. Cette logique évite les blocages mais augmente la taille du journal dans les bases fortement modifiées. Le schéma présenté montre une table FinancialData avec plus d’une dizaine de colonnes numériques et une clé primaire composite. La partition par hash crée 100 fichiers .ibd, chacun contenant approximativement 1 % des lignes, mais chaque fichier conserve le format ligne‑orienté, conservant ainsi le problème de lecture de colonnes inutiles.

CREATE TABLE `FinancialData` (
  `FinancialDataID` int NOT NULL AUTO_INCREMENT,
  `StockID` int NOT NULL,
  `StockDate` datetime DEFAULT NULL,
  `Open` decimal(20,5) DEFAULT NULL,
  `Low` decimal(20,5) DEFAULT NULL,
  `High` decimal(20,5) DEFAULT NULL,
  `Close` decimal(20,5) DEFAULT NULL,
  `Volume` decimal(20,5) DEFAULT NULL,
  `EMA` decimal(20,5) DEFAULT NULL,
  `VWAP` decimal(20,5) DEFAULT NULL,
  `RateOfChange` decimal(20,5) DEFAULT NULL,
  `OnBalanceVolume` decimal(20,5) DEFAULT NULL,
  PRIMARY KEY (`FinancialDataID`,`StockID`),
  UNIQUE KEY `StockID_Date_Idx` (`StockID`,`StockDate`),
  KEY `idx3` (`StockID`,`FinancialDataID`,`StockDate`,`Close`)
) ENGINE=InnoDB PARTITION BY HASH(`StockID`) PARTITIONS 100;

Iceberg sur MinIO : modèle colonne et métadonnées

Iceberg transforme le même job en lecture de fichiers Parquet stockés dans MinIO. Chaque fichier conserve les colonnes de façon contiguë, ce qui permet aux moteurs de requête (Spark) de ne charger que les colonnes requises. La définition de la table indique PARTITIONED BY (bucket(16, `symbol`)). Iceberg calcule les partitions à la création et les consigne dans le catalogue Polaris, évitant ainsi le recalcul à chaque requête. Le système conserve un fichier de métadonnées qui décrit les fichiers de données, leurs statistiques et leurs schémas. Ajouter une colonne ne nécessite qu’une mise à jour du schéma dans le catalogue ; les fichiers existants restent lisibles tant que la colonne est marquée nullable. Le modèle objet élimine le besoin de fichiers de tablespace séparés, réduisant le nombre d’objets à gérer.

CREATE TABLE IF NOT EXISTS raw_bars (
  `symbol` string,
  `time_stamp` timestamp,
  `open` double,
  `high` double,
  `low` double,
  `close` double,
  `volume` bigint,
  `vwap` double,
  `trade_count` bigint,
  `is_valid` boolean
) USING iceberg PARTITIONED BY (bucket(16, `symbol`));

Analyse comparative des performances et limites

Le facteur déterminant est le modèle de stockage. InnoDB, en lecture ligne‑orientée, nécessite le chargement complet d’une ligne même si la requête ne cible que close. Dans un scénario où chaque indicateur ne touche que deux colonnes, le coût d’I/O augmente proportionnellement au nombre de colonnes inutilisées. Iceberg, en revanche, lit uniquement les colonnes demandées grâce à la structure colonne‑par‑colonne de Parquet, réduisant le volume de données transférées de plusieurs dizaines de pourcents selon la largeur du schéma. La partition bucket de 16 valeurs répartit les symboles de façon quasi‑uniforme, limitant le nombre de fichiers à scanner par requête. Cependant, Iceberg dépend d’un moteur de calcul (Spark) et d’un stockage objet ; la latence d’accès à MinIO peut dépasser celle du disque local d’InnoDB pour de petites requêtes, ce qui rend Iceberg moins performant sur des charges de travail à forte granularité.

En termes de consistance, InnoDB offre un MVCC natif avec purge automatisée, garantissant des lectures cohérentes même pendant des écritures massives. Iceberg repose sur le contrôle de version du catalogue ; les snapshots permettent de lire des versions antérieures, mais la gestion des conflits d’écriture nécessite une coordination explicite (optimistic concurrency). Enfin, la maintenance diffère : InnoDB requiert le suivi des partitions .ibd et du journal d’annulation, tandis qu’Iceberg centralise la logique de schéma et de partition dans le catalogue, simplifiant les évolutions de schéma mais introduisant une dépendance supplémentaire au service de métadonnées.