TechnOracle In Memory Database

Nous, partenaires, avons la chance d’être invité régulièrement par Oracle à des événements marketing technique qui se déroulent régulièrement en région. Là, sous la forme de courtes présentation de deux à trois heures un avant vente nous déroulent les éléments techniques d’un sujet « chaud ». Cette fois le thème était « In memory Database »  après un prémisse reprenant les dernières nouveautés et une rapide synthèse de OOW14 que je résumerais ici en quatre mots clés:  CLOUD++ ,  BIGDATA SQL, OVM 3.3 et linux 7, de plus large échos et des analyses pertinentes ayant été fait par nos experts sur place et lors de nos séminaires en ligne, je ne reviendrais pas dessus ici; la part du lion est consacré à cette nouvelle option de la base de données apparue depuis le patchset 12.1.0.2.0
 
 
Le concept « In memory Database »
Le rappel des trois objectifs fixés aux développeurs:

  • Requêtes 100 X  plus rapides et analyses en temps réel
  • Une amélioration réelle pour les environnements DWH et OLTP
  • Une implémentation transparente

L’introduction reprend la controverse historique entre le stockage des données en ligne ou en colonne illustré par une animation cartoon de la guerre entre Daffy duck et Bugs bunny sur la période d’ouverture de la chasse au canard et celle du lapin.
daffy-duck-and-bugs-bunny
Tout cela pour bien montré qu’Oracle c’est donnée le luxe de ne pas choisir  entre :

  • le stockage en ligne : adapté pour les transactions sur un faible nombre de lignes (ligne constituée potentiellement d’un grand nombre de colonnes)
  • Le stockage en colonne : analyse rapide d’un très grand nombre de ligne avec peu de colonne , particulièrement bien adapté pour édité le nombre de vente d’un produit par région par exemple.

Après cette entrée en matière suivent les éléments techniques majoritairement issus du « white paper » localisé à cette adresse sur le site d’Oracle dont voici la restitution:
L’utilisation de la nouvelle option va permettre de se retrouver avec le choix entre une zone mémoire où les données sont  rangées en colonne et la zone de cache des données historiques (db_cache_size) où l’information est rangée en ligne dans les blocs. Le choix d’utiliser l’une ou l’autre de ces zones est fait de manière transparente par l’optimiseur.
Ce qui donne l’apparition de la nouvelle structure « In-Memory Area » dans la SGA (System Global Area):
InMem01
Dans cette zone on va retrouver principalement deux espaces :

  • IMCU pool: « In Memory Compression Unit », contenant les données en colonne compressées
  • SMU pool :  « Snapshot Metadata Units » , informations de cardinalités, valeur minimum et maximum, et informations transactionnelles – lors de la modification des valeurs –

InMemoryDB.10
Mise en oeuvre minimale
Cet espace est défini par le paramètre d’instance INMEMORY_SIZE.  Il n’est pas dynamique et doit être positionné d’abord dans le fichier spfile, avant d’être visible au démarrage de la base :

SQL> startup
ORACLE instance started.
Total System Global Area 1073741824 bytes
Fixed Size                  2932632 bytes
Variable Size             759169128 bytes
Database Buffers           96468992 bytes
Redo Buffers                5455872 bytes
In-Memory Area            209715200 bytes
Database mounted.
Database opened.

La taille minimale est de 100Mo, c’est une zone qui est allouée au démarrage en prenant sa place dans la SGA  (il  faut donc penser à augmenter SGA_TARGET et/ou MEMORY_TARGET en conséquence)  et qui va rester statique.
Caractéristiques
La technologie « In-Memory columnar »  se caractérise par les éléments suivant :

  • Format en colonne des données, mais seulement en mémoire :
    • Pas d’image sur disque, pas de gestion associée de redolog ou de undo
    • Le stockage des blocs sur le disque reste au format ligne
  • Le taux de compression utilisé peut être entre 2x et 20x (suivant le paramétrage que l’on précisera)
  • L’activation se fait par table ou partition d’une table
  • La fonctionnalité est disponible sur toutes les plateformes (pour lesquelles le patchset est disponible!)

Optimisations
L’utilisation d’un index particulier associé aux différents « IMCU » va permettre d’aller vite dans la sélection en éliminant toutes les zones ne répondant pas aux critères :

  • Chaque « IMCU »  contient un ensemble de valeur
  • L’index enregistre les valeurs minimale et maximale de chacune des zones
  • Avec un critère de sélection de plage de date,  toutes les zones ne correspondant pas sont éliminées rapidement (« IMCU pruning »)

Exemple pour une table des ventes et un ordre « SELECT * FROM SALES WHERE ORDER_DATE between ‘2013-01-01’ and ‘2014-01-01’ :
InMemoryDB11

  • Les requêtes de type analytiques sont performantes sur toutes les colonnes, il n’y a plus besoin des indexes associés.
  • La suppression de la gestion associée à ces indexes allège le transactionnel (insertion, mise à jour et suppression plus rapide)
  • Aucun surcoût d’E/S disque puisque les données restent seulement en mémoire

Les parcours complets (scans)  des tables sont  particulièrement plus rapide  :

  • Chaque CPU utlilise la mémoire « locale »  (directement rattachée au processeur)
  • L’utilisation des opérations de type SIMD internes au processeur permet de réaliser des scans de milliards de lignes/sec (pour un ordre de grandeur millions de lignes / sec avec le stockage au format ligne)

InMemoryDB12
Jointures et « bloom filter »
les critères sur les dimensions des tables de faits comme la sélection de la date d’une commande donne des jointures qui peuvent utiliser des scans complets  filtrés ensuite par un algorithme  de « Bloom filter »  donnant un traitement de la jointure 10x plus rapide. C’est la même technologie que celle utilisée dans l’Exadata. Le « hint » PX_JOIN_FILTER permet d’orienter son usage.
Exemple pour un requête devant retrouver la somme des ventes de toutes les commandes passées la veille de Noël :
InMemoryDB13
Vecteur de transformation en mémoire
L’agrégation de résultats peut se faire directement en mémoire par la construction dynamique de vecteurs de regroupement des données en colonne, le contrôle peut se faire par un nouvel « hint »  : VECTOR_TRANSFORM,  les éditions sont accélérées sans avoir besoin de construire de vues matérialisées.
Exemple pour avoir le rapport des ventes d’un produit donné (ici des chaussures « Footwear »)  dans les magasins d’usine :
 
InMemoryDB14
Annotation des plans
L’optimiseur est capable de choisir ces nouveaux chemins d’accès et le plan d’exécution sera annoté avec les informations correspondantes :

  • Scan de la zone :
  • InMemoryDB15
  • Jointures transformées en scan et « Bloom filter »:
  • InMemoryDB16
  • Regroupement par vecteur :
  • InMemoryDB17

Remplissage et altération des objets
Comment se passe l’alimentation de cette zone « In-memory Colum store » ?

  • Elle est réalisée en tache de fonds par les processus nommés : ORA_W00n_<ORACLE_SID>
  • Le nombre de processus est défini par le paramètre INMEMORY_MAX_POPULATE_SERVERS , dont la valeur par défaut est le plus petit des nombres entre CPU thread / 2  et PGA_AGGREGATE_TARGET / 512 Mo
  • La base reste complètement accessible durant cette opération (avantage de la présence des deux formats)

Un nouvel attribut est disponible pour les ordres de création ou d’altération des  tables ou partition ; INMEMORY.

ALTER TABLE sales INMEMORY ;
ALTER TABLE sales NO INMEMORY ;
CREATE TABLE customers ...
PARTITION BY LIST
(PARTITION p1 ... INMEMORY,
PARTITION p2 ... NO INMEMORY) ;

Les segments éligibles à cet altération sont :

  • Tables
  • Partitions
  • Sous – partitions
  • Vues Matérialisées

Les segments non éligibles sont :

  • Tables de type IOT
  • Hash Clusters
  • LOBS externe

Il est possible d’inclure ou d’exclure uniquement certaines colonnes, comme dans les exemples suivant :

ALTER TABLE sales INMEMORY NO INMEMORY (PROD_ID)  ;
CREATE TABLE orders ( c1 number, c2 varchar(20), c3 number)  INMEMORY PRIORITY CRITICAL
NO INMEMORY (c1) ;

la clause PRIORITY avec ses différentes options CRITICAL, HIGH, MEDIUM ou LOW va définir le moment et la priorité de création des données en colonne dans la zone In-Memory.

Niveau de Priorité Description
CRITICAL les informations sont construites dans la zone In-Memory dés l’ouverture de la base
HIGH les informations sont construites dans la zone In-Memory dés l’ouverture de la base,
après le traitement des objets à l’attribut CRITICAL et s’il reste de la place
MEDIUM les informations sont construites dans la zone In-Memory dés l’ouverture de la base,
après le traitement des objets à l’attribut CRITICAL et HIGH s’il reste de la place
LOW les informations sont construites dans la zone In-Memory dés l’ouverture de la base,
après le traitement des objets à l’attribut CRITICAL,HIGH et MEDIUM s’il reste de la place
NONE Valeur par défaut. La construction se fait uniquement après le premier scan de l’objet
A condition qu’il y ait de la place disponible dans la zone

Options de compression
La compression avec le mot clé MEMCOMPRESS est une clause supplémentaire de l’attribut INMEMORY, elle va permettre de choisir l’algorithme le plus pertinent en fonction de l’usage de la donnée :

ALTER MATERIALIZED VIEW mw1  INMEMORY MEMCOMPRESS FOR QUERY ;
CREATE TABLE trades (Name varchar(20), Desc varchar(200))
INMEMORY MEMCOMPRESS FOR DML(Desc) ;
  • Les objets sont compressés pendant la création des informations dans la zone mémoire (solicitation des mêmes processus ORA_W00n_<ORACLE_SID> )
  • La spécification peut se faire au niveau partition/sous-partition/colonne
  • Les différents niveaux sont :
    1. NO MEMCOMPRESS, pas de compression, objets fortement  transactionnel
    2. MEMCOMPRESS FOR DML , pour les objets transactionnels
    3. MEMCOMPRESS FOR QUERY,  pour la majorité des objets (valeur par défaut de la compression)
    4. MEMCOMPRESS FOR CAPACITY pour les segments peu utilisés.
  • L’ajustement des niveaux peut être contrôlé par des stratégies ILM

Exemple :

CREATE TABLE ORDERS ...
PARTITION BY RANGE ...
(PARTITION P1 ...  INMEMORY NO MEMCOMPRESS,
PARTITION P2 ... INMEMORY MEMCOMPRESS FOR DML,
PARTITION P3 .. INMEMORY MEMCOMPRESS FOR QUERY,
...
PARTITION P200 ... INMEMORY MEMCOMPRESS FOR CAPACITY) ;

Pour identifier les objets décorés par l’attribut INMEMORY une nouvelle colonne a été ajouté aux vues *_TABLES

  • Ce sont des attributs par segments
  • Pour les tables partitionnées , il faut regarder *_TAB_PARTITIONS et *_TAB_SUBPARTITIONS, dans l’exemple les tables COSTS et SALES sont partitionnées , l’attribut n’apparait pas dans USER_TABLES ;

InMemoryDB18
Vision interne
La nouvelle vue dynamique V$IM_SEGMENTS montre

  • Les objets présents dans la zone In-Memory
  • Le statut de l’alimentation de la zone (« started » ou « completed »)

InMemoryDB19
La vue V$IM_COLUMN_LEVEL permet elle d’avoir le détail des colonnes pour lesquelles les informations sont présentesnt dans la zone avec le taux de compression choisi au travers de la colonne INMEMORY_COMPRESSION :

SQL> SELECT table_name, column_name, inmemory_compression from V$IM_COLUMN_LEVEL ;

InMemoryDB21
Évolutivité avec RAC
la fonctionnalité tire pleinement partie de l’architecture RAC en distribuant la zone mémoire sur les différents nœuds, les requêtes se déroulant alors en parallèle sur chacune des machines, chacune utilisant sa propre RAM. La répartition pouvant se faire suivant plusieurs critères et étant définie par table/partition/sous-partition comme option supplémentaire de la clause INMEMORY.
InMemoryDB22
L’option DISTRIBUTE de la clause INMEMORY peut prendre les valeurs :

  • Par paquet de lignes  (BY ROWID RANGE)
  • Par partition ou sous- partition  (BY PARTITION|SUBPARTITION)
  • Distribuer automatiquement par le moteur (AUTO)
ALTER TABLE lineorder INMEMORY DISTRIBUTE BY ROWID RANGE;
ALTER TABLE sales INMEMORY DISTRIBUTE BY PARTITION;
ALTER TABLE COSTS INMEMORY DISTRIBUTE AUTO;

Tolérance de panne sur les « Engineered System » Oracle
Dernière possibilité, le mirroring de la zone entre les nœuds d’un cluster RAC, uniquement disponible sur ses propres machines. Une fois la zone dupliquer en cas de perte d’un nœud , le moteur peut continuer de réaliser des scans sur la zone In-Memory restante.
InMemoryDB23
Le tout est contrôlé  par une énième option de la clause INMEMORY: la clause DUPLICATE

SQL> ALTER TABLE orders INMEMORY DUPLICATE ;

Ce qui génère une copie dans un des noeuds du cluster
Et pour avoir une copie des « ICMUs » de la table sur tous les noeuds on peut ajouter le mot clé ALL:

SQL> ALTER TABLE orders INMEMORY DUPLICATE ALL ;

Pour terminer
Ultime éléments technique, dans une configuration multitenant, chaque PDB (base pluggable)  peut avoir sa propre zone INMEMORY définie.C’est un point de détail important car si vous ne connaissez pas cette architecture, sachez que le reste de la SGA (et donc le cache des données)  est commun à toutes les PDBs. Avec INMEMORY ce sera le bon moyen pour isoler vos accès!
La fin de la présentation de ce techn’Oracle  nous a montré les nouveautés d’  Enterprise Manager qui prennent en compte cette fonctionnalité  In Memory , comme un nouveau conseillé graphique, qui montre l’avantage que vous auriez à positionné certains objets dans la zone ou les nouvelles statistiques qui dans le temps CPU prennent en compte la catégorie « In Memory Query »
Une matinée particulièrement intéressante à l’agence locale de l’éditeur que je me devais de partager avec vous.