La plupart des gens connaissent probablement la nouvelle fonctionnalité d'Oracle 12.1.0.2, l'option de base de données InMemory. Lors de l'utilisation de cette option sur Oracle RAC, le DBA peut spécifier la clause DUPLICATE pour qu'un objet soit dupliqué dans le magasin de colonnes InMemory dans toutes les instances. Cette clause concerne les systèmes d'ingénierie d'Oracle comme Exadata. Cependant, dans les systèmes non-Engineered, Oracle semble autoriser cette clause, mais cela ne fonctionne pas comme on pourrait s'y attendre. Pour illustrer, suivez cet exemple, qui a été exécuté sur une base de données RAC à deux nœuds sur mon MacBook Pro avec VirtualBox… certainement pas un système Engineered.
Tout d'abord, une table est créée, puis modifiée pour INMEMORY DUPLICATE.
SQL> créer la table db_objs 2 en tant que select * From dba_objects ;
Table créée.
SQL> modifier la table db_objs en double en mémoire ;
Tableau modifié.
La définition de cette clause ne devrait-elle pas générer une erreur puisqu'il s'agit d'un système non-Engineered ?
La table est vérifiée pour montrer que DUPLICATE est spécifié.
SQL> sélectionnez inmemory,inmemory_duplicate 2 dans user_tables où table_name='DB_OBJS' ;
INMEMORY INMEMORY_DUPL-------- -------------ENABLED DUPLICATE
Un simple "select *" de la table est émis sur l'instance 1. Nous pouvons alors vérifier que la table est InMemory.
SQL> sélectionnez inst_id,owner,segment_name,populate_status,inmemory_duplicate 2 de gv$im_segments ;
INST_ID PROPRIETAIRE SEGMENT_NA POPULATE_ INMEMORY_DUPL---------- ---------- ---------- --------- --- ---------- 1 SCOTT DB_OBJS COMPLETED DUPLICATE
Notez que les résultats ci-dessus montrent que le segment est uniquement dans l'instance 1. La même table est interrogée dans l'instance 2, mais l'interrogation de GV$IM_SEGMENTS ne montre toujours que l'instance 1.
À partir de l'instance 1 :
SQL> sélectionnez avg(object_id) à partir de db_objs ;
AVG(OBJECT_ID)------------- 11095.2049
Écoulé :00:00:00.01
Plan d'exécution--------------------------------------------- -------------Valeur de hachage du plan :1349857420
------------------------------------------------------------ ----------------------------------------
| identifiant | Opération | Nom | Lignes | Octets | Coût (%CPU)| Heure |
------------------------------------------------------------ ----------------------------------------
| 0 | SÉLECTIONNER L'INSCRIPTION | | 1 | 5 | 10 (0)| 00:00:01 |
| 1 | TRIER L'AGRÉGAT | | 1 | 5 | | |
| 2 | TABLE ACCESS INMEMORY FULL | DB_OBJS | 21319 | 104K| 10 (0)| 00:00:01 |
------------------------------------------------------------ ----------------------------------------
À partir de l'instance 2 :
SQL> sélectionnez avg(object_id) à partir de db_objs ;AVG(OBJECT_ID)------------- 11095.2049Écoulé :00:00:00.03Plan d'exécution--------------------------------------------- -------------Valeur de hachage du plan :1349857420------------------------------------------------------------ ----------------------------------------| identifiant | Opération | Nom | Lignes | Octets | Coût (%CPU)| Heure |------------------------------------------------------------ ----------------------------------------| 0 | SÉLECTIONNER L'INSCRIPTION | | 1 | 5 | 4 (0)| 00:00:01 || 1 | TRIER L'AGRÉGAT | | 1 | 5 | | || 2 | TABLE ACCESS INMEMORY FULL | DB_OBJS | 21319 | 104K| 4 (0)| 00:00:01 |------------------------------------------------------------ ----------------------------------------Ainsi, à partir de l'une ou l'autre instance, la table a été consultée INMEMORY. Mais nous pouvons voir que seule l'instance 1 a le segment InMemory.
Tous les signes indiquent que la clause DUPLICATE fonctionne sur un système non-Engineered, ce que nous savons être une erreur. DBA_TABLES semble indiquer que DUPLICATE est en jeu ici. Le plan d'explication fournit l'assentiment. Mais GV$IM_SEGMENTS n'est pas d'accord et montre que DUPLICATE ne fonctionne pas dans ce système.