La maggior parte delle persone è probabilmente a conoscenza della nuova funzionalità Oracle 12.1.0.2, l'opzione del database InMemory. Quando si utilizza questa opzione su Oracle RAC, il DBA può specificare la clausola DUPLICATE per duplicare un oggetto nell'archivio colonne InMemory in tutte le istanze. Questa clausola è per i sistemi ingegnerizzati di Oracle come Exadata. Tuttavia, nei sistemi non ingegnerizzati, Oracle sembra consentire questa clausola ma non funziona come ci si potrebbe aspettare. Per illustrare, segui questo esempio, che è stato eseguito su un database RAC a due nodi sul mio MacBook Pro con VirtualBox... sicuramente non un sistema Engineered.
Innanzitutto, viene creata una tabella e quindi modificata per INMEMORY DUPLICATE.
SQL> create table db_objs 2 as select * From dba_objects;
Table created.
SQL> alter table db_objs inmemory duplicate;
Table altered.
L'impostazione di questa clausola non dovrebbe generare un errore poiché si tratta di un sistema non ingegnerizzato?
La tabella viene verificata per mostrare che è specificato DUPLICATE.
SQL> select inmemory,inmemory_duplicate 2 from user_tables where table_name='DB_OBJS';
INMEMORY INMEMORY_DUPL -------- ------------- ENABLED DUPLICATE
Un semplice modulo "seleziona *" per la tabella viene emesso nell'istanza 1. Possiamo quindi verificare che la tabella sia InMemory.
SQL> select inst_id,owner,segment_name,populate_status,inmemory_duplicate 2 from gv$im_segments;
INST_ID OWNER SEGMENT_NA POPULATE_ INMEMORY_DUPL ---------- ---------- ---------- --------- ------------- 1 SCOTT DB_OBJS COMPLETED DUPLICATE
Si noti che i risultati sopra mostrano che il segmento è solo nell'istanza 1. La stessa tabella viene interrogata nell'istanza 2, ma la query GV$IM_SEGMENTS mostra ancora solo l'istanza 1.
Dall'istanza 1:
SQL> select avg(object_id) from db_objs;
AVG(OBJECT_ID) -------------- 11095.2049
Elapsed: 00:00:00.01
Execution Plan ---------------------------------------------------------- Plan hash value: 1349857420
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 10 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
| 2 | TABLE ACCESS INMEMORY FULL| DB_OBJS | 21319 | 104K| 10 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Dall'istanza 2:
SQL> select avg(object_id) from db_objs;
AVG(OBJECT_ID) -------------- 11095.2049
Elapsed: 00:00:00.03
Execution Plan ---------------------------------------------------------- Plan hash value: 1349857420
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 4 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 5 | | |
| 2 | TABLE ACCESS INMEMORY FULL| DB_OBJS | 21319 | 104K| 4 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Quindi, da entrambe le istanze, è stato effettuato l'accesso alla tabella INMEMORY. Ma possiamo vedere che solo l'istanza 1 ha il segmento InMemory.
Tutti i segni indicano che la clausola DUPLICATE funziona su un sistema non ingegnerizzato, che sappiamo essere un errore. DBA_TABLES sembra indicare che DUPLICATE è in gioco qui. L'Explain Plan fornisce concorrenza. Ma GV$IM_SEGMENTS non è d'accordo e mostra che DUPLICATE non funziona in questo sistema.