mardi 30 décembre 2014

Bases colonnes

Les bases colonnes émergent petit à petit dans le monde de l'entreprise, suite à de nombreuses recherches universitaires effectuées au début des années 2000. Il y a quelques années, SAP a mis sur le marché HANA, un moteur in-memory reposant sur un modèle colonne ( le modèle ligne est encore disponible au cas où ). Puis, des sociétés comme HP ( Vertica ) ou Oracle ( option in-memory ) ont proposé des solutions alternatives.

Ce modèle permet d'offrir une nouvelle alternative pour l'OLAP, SAP ayant même l'objectif d'en faire une base "universelle" ( OLAP + OLTP ). Oracle propose quant à lui d'utiliser la base en mode ligne pour l'OLTP et la base en mode colonne pour l'OLAP. De cette manière, de nombreux index peuvent être supprimés, une table en mode colonne ne nécessitant pas d'index, ce qui soulage la partie OLTP pour les mises à jour. De plus, les datamarts peuvent être ramenés au niveau des bases OLTP, le tout étant chargé en RAM.

Les caractéristiques principales d'une base colonne sont les suivantes:
- une compression par colonne permettant des taux de compression parfois impressionnants sur certaines colonnes;
- une vectorisation des données permettant d'exploiter les instructions SIMD des nouveaux processeurs;
- une localité différente des données ( les données sont au pire en RAM et non plus sur le disque ).

Ces propriétés permettent de traiter les requêtes analytiques de manière très efficace si ces dernières portent sur un nombre de colonnes raisonnable. Ce modèle, contrairement à de nombreuses bases nosql, autorisent aussi les jointures.

A ce jour, il reste à vérifier si ce modèle peut s'étendre à l'OLTP de manière satisfaisante. Pour ce faire, SAP a par exemple ajouté une zone delta en mode ligne pour optimiser ses mises à jour unitaires.

Pour aller plus loin, je vous conseille la lecture du ce document :
         The Design and Implementation of Modern Column-Oriented Database System
         D.Abadi, P.Boncz, S.Harizopoulos, S.Idreos, S.Madden


samedi 4 octobre 2014

Compression: retour d'expérience

A l’époque de l’explosion des données ( big data ), il m’a semblé intéressant de mettre en place la compression sur une instance de production ( 11gR2 ), afin de la valider en particulier au niveau des tables, la compression FOR OLTP étant l’objet de nombreux doutes.

J’ai commencé par mettre en œuvre la compression des index ( 9i ) encore assez méconnue. Pour commencer, j’ai estimé le gain potentiel sur les index dépassant une certaine taille, dans le cas présent 2 GB. Pour ce faire, on utilise la commande suivante : 
            analyze index index_name validate structure;
Les colonnes OPT_CMPR_COUNT et OPT_CMPR_PCTSAVE permettent de définir le nombre de colonnes de l’index à spécifier pour la compression et le gain en pourcentage. L’estimation fournie est très satisfaisante suite à mes tests.

Pour activer la compression sur un index, on peut lancer les deux commandes suivantes : 
           alter index index_name rebuild online compress parallel n; 
           alter index index_name  noparallel;

Pour visualiser les index compressés, on exécute la commande suivante: 
           select * from user_indexes where compression = 'ENABLED' order by index_name;
Et pour vérifier le gain réel, on utilise la vue user_segments.

Comme pour les tables, la compression des index permet de réduire la place disque occupée par ces objets mais aussi de diminuer les IO disque au niveau de l'instance.

La compression FOR OLTP pour les tables est, quant à elle, plus délicate à aborder. Avant de l’installer, je vous conseille de lire l’article écrit par J.Lewis afin d’en appréhender les limites : http://allthingsoracle.com/compression-in-oracle-part-3-oltp-compression/ . En particulier, il est intéressant de noter qu’elle est active pour tous les types d’insert, une fois le PCT_FREE atteint. En revanche, elle ne s’active pas lorsqu’une mise à jour concerne les tokens se trouvant dans la table des symboles du bloc de données. Dans ce cas, on peut même observer une décompression des tokens pouvant occasionner des migrations de lignes. Pour ma part, je n’observe pas ce genre de phénomène, mais je reste vigilant sur le sujet, la compression venant d’être mise en place.

Pour estimer le gain apporté par la compression sur une table, on utilise la méthode get_compression_ratio :
alter session set NLS_NUMERIC_CHARACTERS='.,'; => sinon, erreur ORA
set serveroutput on size unlimited
declare
   v_blkcnt_cmp pls_integer;
   v_blkcnt_uncmp pls_integer;
   v_row_cmp pls_integer;
   v_row_uncmp pls_integer;
   v_cmp_ratio number;
   v_comptyp_str varchar2(80);
begin
   dbms_compression.get_compression_ratio(scratchtbsname=>'tablespace_name',
                                          ownname=>'user_name',
                                          tabname=>'table_name',
                                          partname=>NULL,
                                          comptype=>dbms_compression.comp_for_oltp,
                                          blkcnt_cmp => v_blkcnt_cmp,
                                          blkcnt_uncmp => v_blkcnt_uncmp,
                                          row_cmp=> v_row_cmp,
                                          row_uncmp=> v_row_uncmp,
                                          cmp_ratio=> v_cmp_ratio,
                                          comptype_str => v_comptyp_str);
    dbms_output.put_line(to_char(v_blkcnt_cmp));
  
end;

J’ai trouvé l’estimation fournie décevante, souvent sous-évaluée. Si possible, un export/import de la table est souhaitable pour se faire une meilleure idée du taux de compression.

Le segment advisor fournit des tables candidates à la compression FOR OLTP. Initialement, j’ai aussi sélectionné les tables de plus de 8 GB pour identifier d’autres compressions possibles.

Pour compresser une table, vous avez trois principales méthodes : 
              alter table table_name move compress for oltp;
              utilisation du package dbms_redefinition; 
              alter table table_name compress for oltp.
 La première méthode est intéressante pour estimer réellement le taux de compression sur un environnement de test. Mais elle n’est pas online et il faut reconstruire les index par la suite.
La seconde méthode est online, mais je la trouve très lourde à mettre en œuvre. C’est pourquoi j’ai opté pour la troisième méthode en production, sachant que la compression ne s’appliquera que sur les nouveaux blocs. Pour les blocs existants, la purge permettra leur suppression.

Il y a peu de statistiques disponibles pour suivre la compression des tables :
select *
from V$SYSSTAT ( => dba_hist_sysstat )
where ( name like 'HSC%' or name = 'Heap Segment Array Inserts')
order by statistic#;

HSC OLTP Compressed Blocks: how many blocks are compressed using OLTP Compression. Counts only the first compressions in OLTP code
HSC OLTP Space Saving:  how many bytes saved in total using OLTP Compression.
HSC IDL Compressed Blocks: number of Blocks compressed using Insert Direct Load
HSC Compressed Segment Block Changes: total number of block changes to Tables/Heaps (Compressed only)
HSC Heap Segment Block Changes: total number of block changes to Tables/Heaps (Compressed or Non-Compressed)
HSC OLTP Non Compressible Blocks: blocks marked as Final (Not to be compressed again)
HSC OLTP Compression skipped rows: number of rows that are skipped for compression (could be deleted or chained)

dimanche 3 août 2014

OCI: si possible, utiliser l'OCILIB

Dernièrement, j'ai travaillé sur une interface C écrite en OCI natif. Sans rentrer dans les détails, elle était d'une piètre qualité, en particulier les requêtes n'étaient pas bindées ...

Si vous avez le choix, je vous conseille vivement d'utiliser l'OCILIB plutôt que d'attaquer directement la couche native. Dans le cas contraire, inspirez-vous du code source de l'OCILIB disponible à cette adresse. Des exemples sont également fournis dans la doc officielle.

Mais de grâce, ne réinventez pas la roue !

Si vous avez besoin d'un bulk collect en OCI, voici un exemple.


lundi 9 juin 2014

Cassandra

Une présentation de Cassandra ( version 2.0 ), une base nosql hybride.

Cassandra est un moteur in-memory pour l'écriture. Couplé à un produit libre comme Spark pour la lecture, on aboutit à une solution full in-memory, ce qui change la donne en terme de performance.
 

jeudi 17 avril 2014

MongoDB

Une présentation de MongoDB ( version 2.4 ) ,  une base nosql orientée document.

dimanche 16 février 2014

Les données à l'heure du big data

Une réflexion sur l'évolution des bases de données au moment où le big data commence sa démocratisation.