Smart Flash Cache

Oracle Smart Flash Cache (OSFC) permet de positionner un cache intermédiaire entre les datafiles hébergés sur des disques durs et le cache de données hébergé sur la RAM.  Ce cache est prévu pour être stocké sur une mémoire flash, plus rapide et plus cher au giga-octet que les disques durs et moins rapide et moins cher au giga-octet que la RAM. Quand le cache en RAM (buffer cache) devient obsolète il est descendu sur la mémoire flash. Il sera alors plus rapide de relire les données à partir de le mémoire flash pour les remonter en RAM que si elles se trouvent uniquement sur disque dur. Cette technologie a été créé à l’origine pour Exadata puis à partir de Oracle Database 11.2.0.2, elle est devenue disponible pour n’importe quelque flash device (SSD par exemple) et plus uniquement avec le hardware Exadata. En 12c, la nouveauté est qu’il est possible d’utiliser plusieurs flash devices sans à avoir à utiliser un volume manager.

Illustration extraite de whitepaper: Oracle Database Smart Flash Cache

Dans cet article nous allons voir comment avec VirtualBox nous pouvons rajouter un stockage flash puis configurer ce stockage sous le Linux invité. Ensuite avec une base Oracle 12c (12.1.0.2) nous allons configurer le flash cache sur le device flash et tester si on observe une gain de performance (ou pas !). Nous verrons ensuite comment configurer plusieurs devices flash et plusieurs flash cache. Nous testerons aussi OSFC avec une table dans un table chiffré. Et pour finir testerons si OSCF peut être une source de SPOF.

 

 Configuration VirtualBox

Comme dans tous les articles techniques de ce site, c’est grâce à VirtualBox que nous allons mettre en place OSFC. Sur une machine Oracle Linux virtuelle hébergée sur un disque dur SATA, nous ajoutons un device flash virtuel. Si comme moi vous avez un disque SSD pour votre C: alors vous pouvez créer un disque virtuel dessus comme cela vous pourrez constater (ou pas) l’amélioration de performance. Si vous n’avez pas de SSD, pas de problème vous pouvez créer un device flash à partir d’un fichier stocké sur un disque SATA mais bien sûr il n’y aura pas d’amélioration de performance cela restera de l’émulation.

Sur la console principale de VirtualBox, sélectionnez une  machine Linux avec une 12c d’installée, et cliquez sur la partie stockage. Une fenêtre comme ci-dessous s’ouvre, sélectionnez alors un contrôleur SATA existant et cliquez sur « Ajouter un disque »:

 

 

Ensuite, si vous avez un disque SSD sur votre OS, créez le disque virtuel dessus. Sélectionnez Taille fixe. Pour la taille du disque cela dépendant, ici j’ai pris 6Go car ma base utilise environ 600Mo de buffer cache, et j’ai créé une table d’environ 5Go pour pouvoir tester les performances comme on le verra par la suite. Avec 6Go la table pourra tenir entièrement dans la flash cache mais pas dans le buffer cache:

 

Bien sélectionnez Solid-State Drive:

 

 

 

 Configuration Système

Le hardware virtuel étant configuré, le serveur virtuel peut être démarré et configuré pour prendre en compte le stockage SSD. Pour cela il suffit d’aller dans /dev et faire un « ls -l sd* », et sur le sd* qui n’a pas de partition, de le partitionner avec fdisk.

Ce n’est pas obligatoire, mais ici j’ai transformé la partition en raw device et utiliser UDEV pour qu’à chaque reboot, le device remontent en raw device et avec les droits d’écriture à oracle : 

vi /etc/udev/rules.d/60-raw.rules
ACTION=="add", KERNEL=="sdd1", RUN+="/bin/raw /dev/raw/raw1 %N"
ACTION=="add", KERNEL=="raw*", OWNER=="oracle", GROUP=="oinstall", MODE=="0660"

[root@ora12cdb ~]#  /bin/raw /dev/raw/raw1 /dev/sdd1
/dev/raw/raw1:               bound to major 8, minor 49

[root@ora12cdb ~]#  start_udev
                                                           [  OK  ]

[root@ora12cdb ~]#  raw -qa
/dev/raw/raw1:               bound to major 8, minor 49

Un petit reboot permet de vérifier que UDEV est bien configuré, au reboot /dev/raw/raw1 existe toujours et appartient bien à oracle.

 

Configuration de Flash Cache

Maintenant la mise en place OSFC peut commencer… Une seule commande pour configurer est nécessaire :

SQL> alter system set DB_FLASH_CACHE_FILE ='/dev/raw/raw1' scope=spfile;

Obligatoirement suivi d’un redémarrage de l’instance.

Ensuite pour activer le flash cache, une seule commande aussi suffit, et elle est dynamique, ce n’est pas besoin de redémarrer l’instance :

SQL> alter system set DB_FLASH_CACHE_SIZE = 5G scope=both;

Ce n’est donc pas compliquer à mettre en place. Pour vérifier que la configuration est bien prise en compte :

SQL> SELECT * FROM v$flashfilestat;

FLASHFILE# NAME                BYTES         ENABLED     SINGLEBLKRDS       SINGLEBLKRDTIM_MICRO  CON_ID
---------- ----------------  -------------   ---------   -----------------  --------------------  ----------
      1    /dev/raw/raw1      5368709120        1                 0             0                    0

Pour visualiser les statistiques systèmes de class cache portant sur le flash cache :

SQL> SELECT name, value FROM v$sysstat WHERE class="8" and name like '%flash cache%' and name not like '%cell%'

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
physical read flash cache hits                                            0
flash cache inserts                                                       0
flash cache eviction: invalidated                                         0
flash cache eviction: buffer pinned                                       0
flash cache eviction: aged out                                            0
flash cache insert skip: not current                                      0
flash cache insert skip: DBWR overloaded                                  0
flash cache insert skip: exists                                           0
flash cache insert skip: not useful                                       0
flash cache insert skip: modification                                     0
flash cache insert skip: corrupt                                          0

Comme vous pouvez le voir tout est à zéro, c’est normal si la base vient de démarrer et qu’aucune « grosse » table n’a été chargé.

Sur cette base la sga est composé comme suit :

SQL> show sga

Total System Global Area       1107296256 bytes
Fixed Size                     2923488 bytes
Variable Size                  301990944 bytes
Database Buffers               788529152 bytes
Redo Buffers                   13852672 bytes

(sga_target à 1056M, pas de setting de memory_target ni db_cache_size)

 

 

Test d'utilisation du flash cache

Pour pouvoir tester le fash cache, il suffit de créer une table un peu plus petite que la taille de la fash (SSD) pour qu’elle puisse être contenue entièrement dedans et plus grosse que le buffer cache (RAM) pour ne pouvoir être que très partiellement contenue dans celui-ci.

Ci-dessous un exemple pour créer une table de d’environ 4,5Go :

SQL> create table testuser.test_flash (
id  number GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1),
value  varchar2(1000)
) tablespace  tbs_sata_store;

SQL> ALTER TABLE testuser.test_flash ADD CONSTRAINT pkid PRIMARY KEY (ID) using index tablespace tbs_sata_store ;

SQL> begin
                FOR i in 1..1000000
                LOOP
                               insert into testuser.test_flash (value) values (dbms_random.string('U', 1000));
                               IF ( mod( i, 100000 ) ) = 0 THEN        
                                  commit;
                               END IF;
                END LOOP;
                COMMIT;
end;
/
SQL> insert into testuser.test_flash (value) select value from testuser.test_flash;
SQL> insert into testuser.test_flash (value) select value from testuser.test_flash where rownum <=1000000;
SQL> insert into testuser.test_flash (value) select value from testuser.test_flash where rownum <=1000000;
SQL> commit ;

SQL> select tablespace_name,segment_name,sum(bytes)/1024/1024/1024 Go from dba_segments where owner='TESTUSER' and segment_name= 'TEST_FLASH' group by tablespace_name,segment_name ;
TABLESPACE_NAME                SEGMENT_NAME               Go
------------------------------ -------------------------  ------------
TBS_SATA_STORE                 TEST_FLASH                 4.44439697

 

Il suffit de faire des « gros » select sur la table pour voir les statistiques systèmes, sur les class d’évènement de buffer flash, augmenter (requête v$sysstat précédente)…  et bien dans mon cas que nenni. Alors en regardant dans V$BH pour chercher les objets en cache, la table test_flash ne remonte jamais à plus de quelque Mo !!!

Après quelques recherches, la solution a été trouvée sur le support oracle : Bug 18498878 - medium size tables do not cached consistently (Doc ID 18498878.8).

Medium size tables (_small_table_treshold < table size < 10% db block buffers) may not cached properly and consistently  even after repeatedly full scan, causing unnecessary direct reads.

Pour résoudre le problème deux solutions : télécharger et installer le patch Patch 18498878 sinon pour une base de formation comme ici vous pouvez mettre en place le workaround :

alter system set "_serial_direct_read" = never scope=both;

Suite au correctif, les "select *" sur la table TEST_FLASH provoquent enfin l’incrémentation des statistiques systèmes d’évènement buffer flash cache dans v$sysstat. Et l’examen du contenu du cache, révèle que la table TEST_FLASH occupe environ 5Go du cache :

SQL> SELECT   b.owner, b.object_name, b.object_type,   (COUNT(*) * 8192)/1024/1024  Mo,
ROUND (100 * RATIO_TO_REPORT  (COUNT (*)) OVER(), 2) percent_cache
FROM     V$BH a,   DBA_OBJECTS b  WHERE    b.object_id = a.objd
GROUP BY b.owner, b.object_name, b.object_type
having  (COUNT(*) * 8192)/1024/1024 > 2 ORDER BY 5;

OWNER                OBJECT_NAME   OBJECT_TYP      MO           PERCENT_CACHE
-------------------- -------------------- ---------- ---------- -------------
SYS                  OBJ$         TABLE         11.1171875      .22
TESTUSER             TEST_FLASH   TABLE         5023.57813      99.78

Environ 5Go de TEST_FLASH en cache… donc forcément dans la flash cache car le buffer cache fait environ 600Mo. Donc 600Mo en buffer cache et 4,4Go (5G-600Mo) en flash cache, soit l’intégralité de la table.

 

 

Test d'amélioration de performance

 Pour faire un test assez simple de performance, la flash cache est désactivée et un flush est exécuté :

SQL> alter system set DB_FLASH_CACHE_SIZE =0 scope=both;

Puis une série de « gros » select est lancé :

set timing on
declare
                TYPE T_ID IS TABLE OF TESTUSER.TEST_FLASH.ID%TYPE;
                ID_TAB T_ID;    
                TYPE T_VALUE IS TABLE OF  TESTUSER.TEST_FLASH.VALUE%TYPE;
                VALUE_TAB T_VALUE; 
                  
                type r_cursor is REF CURSOR;
                c r_cursor;         
BEGIN
                FOR i in 1..2
                LOOP
                               OPEN c for 'SELECT id, value FROM TESTUSER.TEST_FLASH';
                               LOOP
                                               FETCH c
                                               BULK COLLECT INTO ID_TAB, VALUE_TAB
                                               LIMIT 1000;
                                               exit when ID_TAB.COUNT = 0;
                               END LOOP;
                END LOOP;
END;
/

Ce bloc plsql est lancé 5 fois, le résultat est : 1min48s pour le premier chargement puis une moyenne de 1min43s pour les 4 suivants.

Maintenant enfin le verdict, en activant le flash cache :

SQL> alter system set DB_FLASH_CACHE_SIZE = 5G scope=both;

Et comme précédemment après avoir exécuté 5 fois le block plsql ci-dessus, le résultat est : 1min51s pour le premier chargement puis une moyenne 38s pour les 4 suivants.

Le gain de performance est bien là, ce qui semble logique dans notre cas, la table reste en cache dans la flash sur un disque SSD, ce qui est plus rapide à remonter en mémoire que de remonter la donnée à partir d’un disque SATA. Cette fonctionnalité peut donc être utile pour une application très gourmande en buffer cache  et dont la quantité de RAM physique ne pourrait être satisfaite pour des questions physiques et/ou de coût. D’ailleurs la documentation Oracle recommande d’utiliser la Smart Flash Cache quand l’advisor AWR indique de doubler la taille du buffer cache ou bien que l’évènement « db file sequential read » remonte dans le top des évènements d’attente.

Remarque : Comme pour le buffer cache, il possible d’ « épingler » la table dans la flash cache, si on ne veut pas que d’autres objets l’expulsent.

SQL> ALTER TABLE TESTUSER.TEST_FLASH STORAGE (FLASH_CACHE KEEP);

 

 

 Configuration multi flash

Avec la 12c, la nouveauté est que l’on peut activer plusieurs mémoires flash physique, directement au niveau de l’instance sans passer par un volume manager. Il suffit de mettre la liste des devices à utiliser dans la variable DB_FLASH_CACHE_FILE et la liste des tailles respectives  à utiliser dans DB_FLASH_CACHE_SIZE. Rien de plus simple :

SQL> alter system set DB_FLASH_CACHE_FILE = '/dev/raw/raw1','/dev/raw/raw2' scope=spfile;

SQL> alter system set  DB_FLASH_CACHE_SIZE = 5G,4G  scope=spfile;

Un redémarrage d’instance est nécessaire, et le tour est joué :

SELECT * FROM v$flashfilestat;

FLASHFILE# NAME                       BYTES       ENABLED   SINGLEBLKRDS SINGLEBLKRDTIM_MICRO     CON_ID
---------- ------------------------- ---------- ---------- ------------ -------------------- ----------
         1 /dev/raw/raw1             5368709120         1             0             0                0
         2 /dev/raw/raw2             4294967296         1             0             0                0

Pour vérifier que les 2 mémoires flash sont bien utilisées, il suffit de charger une table plus grosse qu’une seule flash cache pour qu’elle soit répartie sur les deux devices flash. On peut rajouter un gros 2 Go dans la table test_flash:

SQL> insert into testuser.test_flash (value) select value from testuser.test_flash where rownum <=2000000 ;

SQL> commit;

SQL> select tablespace_name,segment_name,sum(bytes)/1024/1024/1024 Go from dba_segments where owner='TESTUSER' group by tablespace_name,segment_name ;

TABLESPACE_NAME                SEGMENT_NAME                GO
------------------------------ -------------------- ----------
TBS_SATA_STORE                  PKID                    .09375
TBS_SATA_STORE                  TEST_FLASH           6.5703125

Puis on relance le bloc plsql de chargement, en recheckant v$flashfilestat, on constate l’utilisation des 2 devices flash :

SQL> SELECT * FROM v$flashfilestat;
FLASHFILE# NAME              BYTES    ENABLED SINGLEBLKRDS SINGLEBLKRDTIM_MICRO  CON_ID
---------- ------------------------- ---------- ---------- ------------ -------------------- ----------
    1 /dev/raw/raw1      5368709120     1     72452        63094616          0
    2 /dev/raw/raw2      4294967296     1     14125        11378324          0

De plus si on regarde le contenu du cache (buffer+flash) :

OWNER           OBJECT_NAME     OBJECT_TYP         MO      PERCENT_CACHE
-------------------- -------------------- ---------- ---------- -------------
TESTUSER        PKID            INDEX      19.4140625        .28
TESTUSER        TEST_FLASH      TABLE      6970.49219        99.39

Le cache total pris par la table TEST_FLASH est de  6,8Go, si on enlève les 600Mo de buffer (RAM), cela représente 6,2Go de cache en flash. Le cache dans la flash pour la table TEST_FLASH est donc obligatoirement répartit entre raw1 (5Go) et raw2 (4Go).

 

 

 Crash the flash

Que se passe-t-il si la flash crashe suite à un problème, hardware par exemple ? … La base tombe-t-elle ? Les sessions qui lisent dans la flash crashent-elles ?

Pour voir comment va réagir la base, il suffit de lancer la lecture avec le bloc plsql précédent, et supprimer le disque virtuel sur le PC hôte si vous êtes sous linux avec un rm. Ce qui n’est pas possible dans mon cas, car étant sous windows, le fichier est locké, à la place je vais exécuter un dd dans linux invité.

[oracle@ora12cdb ~]$ dd if=/dev/zero of=/dev/raw/raw2 bs=1024 count=4194304

La session lisant la table TEST_FLASH dans la flash ne crashe pas, mais forcement elle met plus de temps que prévu à rendre la main.

En revanche dans le alert.log de l’instance, on constate le crash de /dev/raw/raw2 et la mise en disable de celui-ci:

Encounter problem verifying flash cache file /dev/raw/raw2. Disable flash cache and issue an ORA-700 for diagnostics
Errors in file /oracle/oraBase/diag/rdbms/bigdb/BIGDB/trace/BIGDB_gen0_4273.trc  (incident=151241) (PDBNAME=CDB$ROOT):
ORA-00700: soft internal error, arguments: [kcbl2vfyfh_action], [db_flash_cache_file integrity check failed], [], [], [], [], [], [], [], [],
Incident details in: /oracle/oraBase/diag/rdbms/bigdb/BIGDB/incident/incdir_151241/BIGDB_gen0_4273_i151241.trc
Flash Cache: disabling started for file
1
Flash cache: future write-issues disabled
Start disabling flash cache writes..
Wed Feb 08 21:48:20 2017
Flash cache: DBW0 stopping flash writes...
Flash cache: DBW0 garbage-collecting for issued writes..
Flash cache: DBW0 invalidating existing flash buffers..
Wed Feb 08 21:48:20 2017
Dumping diagnostic data in directory=[cdmp_20170208214820], requested by (instance=1, osid=4273 (GEN0)), summary=[incident=151241].
Wed Feb 08 21:48:22 2017
Sweep [inc][151241]: completed
Sweep [inc2][151241]: completed
Wed Feb 08 21:48:22 2017
Flash cache: DBW0 done with write disabling. Checking other DBWs..
Flash Cache file /dev/raw/raw2 (3, 1) closed by dbwr 0
Wed Feb 08 21:48:23 2017
Flash cache: disable completed

On peut constater que la flash sur /dev/raw1 reste active :

SELECT * FROM v$flashfilestat;
FLASHFILE# NAME                      BYTES        ENABLED SINGLEBLKRDS SINGLEBLKRDTIM_MICRO     CON_ID
---------- ------------------------- ---------- ---------- ------------ -------------------- ----------
       1 /dev/raw/raw1                5368709120         1        81199             93904014              0
       2 /dev/raw/raw2                4294967296         0        15743             13303493              0

Oracle Smart Flash Cache a bien réagit, il n’a pas crashé l’instance Oracle, ni la session utilisant indirectement le cache.

 

 

Smart Flash Cache and TDE

Le cache s’écrit dans un device, ce qui signifie donc qu’il est relativement facile à lire. Par exemple un « strings » sur /dev/raw/raw1 permet de voir le contenu ASCII.

[oracle@ora12cdb ~]$ strings /dev/raw/raw1
[…]
NIMODMSZOXDOVVDYZMILNPSIORBGGVQZVIVXUGVRAHXXCISRHVHWRFRBZNUJIIZKGZLQCZQAUGIPXKZVMIDXBHBVVQGDPUCGGJNEHIRBBQMOQQWLWYHJQAFBPSTRUSGAPVUFTQWNZPMRYXGSOOMFVIIVBGWBBXBQMGUJHTZVOUBOYMUDGGXPBOWRCRGVOYELWGBFQFNCIOUTUCZIMURCMYHOXAEVRDHKACTPRHGOUSJVRWZOLYYAXLZUHFBIIVNIQOIMKGXGMAYDVHCJZCWOPHFIIVXADTXLGRIBDWVYYXESSCEGIXXXCSRZJGNNAUSSRHEYDYHXZAHHKJPRSUYFMPKPXVODRNQQEIQWBLEIXEFMBGQBAMSMKCIPDTBVMYOEJXELUTZQYESNWBRYIHPBQZGHCSRNKSNHBKYWAQSZRLAGDZOLARWDXULLPWZFMMXAPQKWRJXZSQHUYUTDJOQIMYSRHXBMDQZGBLCVJLKTIEXWOEOZLQNYLQRWNMJUAXFTBKQIGDWRTOEBDGQSNPLPGRDOXMPJJQNJPNEUIKQFFSAPWIPBBVJGPIIYWGSPTJBICJVMRHYSHLFDZSQYHZQZYWILUXKCUSOHCWCOPNTJGPJPBYXDFIOSGJUWGGOMZMAJIHRPGJHNOAOAUFPZFZVBCIEJCQAPZUTOWBFHIFRUIDSAPKWMFJNBVFTKYSFFEACLBTHDLHUNCNBSTBVHAORUAMZUTKNNFUGJXZEARRAIXPUOHOSZHWAEMCFUDUQRBAXANGTKTVQYELJHBRTAGNRSWLEBUUSTSXILVNYAKIXLHJLNTZVKIIJYMBBIBLDMTYJAYIILARMOXDGQLALCDBRFZJTXYCMDHHLGSUZUQHZGLQPXCNKENVRSIDXWKVPIYXVPXGLBILIOSGCBXEBLXEWQKIDCPOCOFUWJXAZKYTTFBUUGHYIHZLYJGYSNUNQOFFYPGBMVYURYYQWSHLKOABYMTOWRNPYDZRVIVHBGTZGX,
[…]

Les données apparaissent donc en clair, on peut le vérifier en recherchant la chaine de caractère dans le table TEST_FLASH:

SQL> select ID from TESTUSER.TEST_FLASH where value = 'NIMODMSZOXDOVVDYZMILNPSIORBGGVQZVIVXUGVRAHXXCISRHVHWRFRBZNUJIIZKGZLQCZQAUGIPXKZVMIDXBHBVVQGDPUCGGJNEHIRBBQMOQQWLWYHJQAFBPSTRUSGAPVUFTQWNZPMRYXGSOOMFVIIVBGWBBXBQMGUJHTZVOUBOYMUDGGXPBOWRCRGVOYELWGBFQFNCIOUTUCZIMURCMYHOXAEVRDHKACTPRHGOUSJVRWZOLYYAXLZUHFBIIVNIQOIMKGXGMAYDVHCJZCWOPHFIIVXADTXLGRIBDWVYYXESSCEGIXXXCSRZJGNNAUSSRHEYDYHXZAHHKJPRSUYFMPKPXVODRNQQEIQWBLEIXEFMBGQBAMSMKCIPDTBVMYOEJXELUTZQYESNWBRYIHPBQZGHCSRNKSNHBKYWAQSZRLAGDZOLARWDXULLPWZFMMXAPQKWRJXZSQHUYUTDJOQIMYSRHXBMDQZGBLCVJLKTIEXWOEOZLQNYLQRWNMJUAXFTBKQIGDWRTOEBDGQSNPLPGRDOXMPJJQNJPNEUIKQFFSAPWIPBBVJGPIIYWGSPTJBICJVMRHYSHLFDZSQYHZQZYWILUXKCUSOHCWCOPNTJGPJPBYXDFIOSGJUWGGOMZMAJIHRPGJHNOAOAUFPZFZVBCIEJCQAPZUTOWBFHIFRUIDSAPKWMFJNBVFTKYSFFEACLBTHDLHUNCNBSTBVHAORUAMZUTKNNFUGJXZEARRAIXPUOHOSZHWAEMCFUDUQRBAXANGTKTVQYELJHBRTAGNRSWLEBUUSTSXILVNYAKIXLHJLNTZVKIIJYMBBIBLDMTYJAYIILARMOXDGQLALCDBRFZJTXYCMDHHLGSUZUQHZGLQPXCNKENVRSIDXWKVPIYXVPXGLBILIOSGCBXEBLXEWQKIDCPOCOFUWJXAZKYTTFBUUGHYIHZLYJGYSNUNQOFFYPGBMVYURYYQWSHLKOABYMTOWRNPYDZRVIVHBGTZGX';
           ID
----------
    969769
   1916171
   2974249
   3974249
   5446473
   6835298

6 rows selected.

Ce n’est pas forcément une faille de sécurité en soit car dans le datafile, la donnée est aussi en clair :

[oracle@ora12cdb BIGDB]$ strings sata_store01.dbf|grep "NIMODMSZOXDOVVDYZMILNPSIORBGGVQZVIVXUGVRAHXXCISRHVHWRFRBZNUJIIZKGZLQCZQAUGIPXKZVMIDXBHBVVQGDPUCGGJNEHIRBBQMOQQWLWYHJQAFBPSTRUSGAPVUFTQWNZPMRYXGSOOMFVIIVBGWBBXBQMGUJHTZVOUBOYMUDGGXPBOWRCRGVOYELWGBFQFNCIOUTUCZIMURCMYHOXAEVRDHKACTPRHGOUSJVRWZOLYYAXLZUHFBIIVNIQOIMKGXGMAYDVHCJZCWOPHFIIVXADTXLGRIBDWVYYXESSCEGIXXXCSRZJGNNAUSSRHEYDYHXZAHHKJPRSUYFMPKPXVODRNQQEIQWBLEIXEFMBGQBAMSMKCIPDTBVMYOEJXELUTZQYESNWBRYIHPBQZGHCSRNKSNHBKYWAQSZRLAGDZOLARWDXULLPWZFMMXAPQKWRJXZSQHUYUTDJOQIMYSRHXBMDQZGBLCVJLKTIEXWOEOZLQNYLQRWNMJUAXFTBKQIGDWRTOEBDGQSNPLPGRDOXMPJJQNJPNEUIKQFFSAPWIPBBVJGPIIYWGSPTJBICJVMRHYSHLFDZSQYHZQZYWILUXKCUSOHCWCOPNTJGPJPBYXDFIOSGJUWGGOMZMAJIHRPGJHNOAOAUFPZFZVBCIEJCQAPZUTOWBFHIFRUIDSAPKWMFJNBVFTKYSFFEACLBTHDLHUNCNBSTBVHAORUAMZUTKNNFUGJXZEARRAIXPUOHOSZHWAEMCFUDUQRBAXANGTKTVQYELJHBRTAGNRSWLEBUUSTSXILVNYAKIXLHJLNTZVKIIJYMBBIBLDMTYJAYIILARMOXDGQLALCDBRFZJTXYCMDHHLGSUZUQHZGLQPXCNKENVRSIDXWKVPIYXVPXGLBILIOSGCBXEBLXEWQKIDCPOCOFUWJXAZKYTTFBUUGHYIHZLYJGYSNUNQOFFYPGBMVYURYYQWSHLKOABYMTOWRNPYDZRVIVHBGTZGX" |wc -l
6

Le problème serait si on avait mis en place le chiffrage TDE, et si la donnée était visible en clair dans la flash device alors qu’elle ne l’est pas dans le datafile, car chiffrée par TDE. La donnée est-elle en clair? Vérifions.

Le test est simple à faire. Il suffit de créer un tablespace chiffré (cf les nombreux articles sur proracle.fr):

SQL> create tablespace TBS_CRYPT datafile '/oracle/oradata/BIGDB/SHAKA/tbs_crypt01.dbf' size 6g ENCRYPTION USING 'AES128' DEFAULT STORAGE (ENCRYPT);

Puis on créé exactement la même table que précédemment mais dans le tablespace chiffré:

SQL> create table testuser.test_flash_crypt (…) tablespace  TBS_CRYPT;

Et pour être sûr de bien reconnaitre la donnée on peut rajouter un mot clef dans les insert comme par exemple :

('The secret is:'||dbms_random.string('U', 900)

On relance le chargement avec le bloc plsql précédent mais en changeant le nom de la table. Et quand le chargement est finit, on « strings » le flash device :

[oracle@ora12cdb ~]$ strings /oracle/oradata/BIGDB/SHAKA/tbs_crypt01.dbf |grep "The secret is"

Rien ne remonte! La donnée n’a pas visible, tant mieux. Mais est-elle seulement dans le flash cache ? Il suffit de regarde la quantité de la table dans les buffers pour se rendre compte que la table est uniquement dans le buffer cache :

OWNER           OBJECT_NAME       OBJECT_TYP          MO   PERCENT_CACHE
-------------------- -------------------- ---------- ---------- -------------
SYS             C_OBJ#             CLUSTER    7.296875       1.34
SYS             OBJ$               TABLE      11.1171875     2.05
TESTUSER        TEST_FLASH_CRYPT   TABLE      524.507813     96.61

Non, la table ne se retrouve pas dans le flash cache, elle reste dans le buffer cache.

On peut donc en déduire que Smart Flash Cache est incompatible avec le chiffrage TDE. J’ai cherché cette information dans la documentation Oracle mais je ne l’ai pas trouvé, …ni même sur google, il faudrait que j’ouvre un support Oracle pour avoir confirmation.

 

Remarque : TDE semble donc protéger d’un détournement par Smart Flash Cache ce qui n’est pas le cas de la gestion AMM de la mémoire (memory_target). Vous pouvez faire le test, si vous initialisez  memory_target dans le spfile, alors vous verrez que les données chiffrée se retrouvent en clair, et facilement accessible, dans /dev/shm

oracle@ora12cdb shm]$ pwd
/dev/shm
[oracle@ora12cdb shm]$ strings *|grep "The secret is:"
[...]
The secret is:YWODEMQTDQJQCKECJAJJQNOTYSUTSXRPBCTQXTRFKZHBRNSPKYNHVAVWPIWWKHJFSDGADVHTAQKIAHJJRHANYNMQLQNHBAKCDNBVJAILPXPWHFGHQXKIVWVDTTHEWSWEEMEJHSVHFQKGSTYBNXPWXFGWHJAFSFQUKUGPXCOWNVONPTFHRXAUXDBMVEPAXLBPKRVPVMXBSEJNZLEYHBZQIRGFYWPUNQLYMKCLGCIJCKHXPFLCFPQGCIUJNLKJDJAEPLYGONIJLGOXWSHELGAQZGIZWMUKMJORWFEDSTLRWEDZBCNYRKZDQIELYSRBWXBHMSBPMTVHKEPAJWYOXUOCRTDUYVFPRNZIXEONVJGCPPEZEDZWMFDOQECKOGEDGVQIJEOFGFQMJSBWXDQLBIDISBSMLTQCFWLYTSEKJQIWYFKNHTVQPILYWIUUYFHLCCLDLGGGTZHZOOVAVOCBBCBBFGTSXMVLSUAJMRUBTDQEWHYRXXWZHINHIFVJSCRMUHJAFQBORSFYJZTCDPRFUISBZVSEULONKZEBXAFOQBYRIGJLUNONLKNUDBFZBPBBRJAHAZQTQQXCPCMUJHRFVBHNAJBZQHQHKYZIGAFLDMPBMAOMJWFXRJPSTBHQHGBBOWLVDSFNTHHICWAKGGXHRGAEAGYNHHNSIAXQSUZCEMGTFQCAIEYYNCGOCJJKZSFBIEYUQAMKTDBWWDEIKWMUJTHLKGBSNFEMQEOVQPKBHZVJGKXNGVFJMNNTLZNDFRXKIQSNTPKRWHEPDEYQCGBZSRFCEBZWGIMPPNWZAHECDJYPRLJNGODYIDMMSSJZYWGMVAODMCTGQZPKCPPKQDUPLYBHGFYYDLOZKNTDODUWOSILTCXIVEOKUIUBGNBPOIFANIORTKHF,
[...]

 

 

 Smart Flash Cache, how much is it?

Maintenant que vous êtes convaincu il faut parler du prix. La bonne nouvelle est que Smart Flash Cache est gratuit ! La mauvaise est qu’il est disponible uniquement sur la version Entreprise Edition. Il faut préciser aussi que Smart Flash Cache n’est présent que sur Solaris ou Linux.