sql >> Base de Datos >  >> RDS >> Oracle

InMemory DUPLICATE Confusión en Oracle RAC

La mayoría de las personas probablemente conocen la nueva característica de Oracle 12.1.0.2, la opción de base de datos InMemory. Al usar esta opción en Oracle RAC, el DBA puede especificar la cláusula DUPLICATE para que un objeto se duplique entre el almacén de columnas InMemory en todas las instancias. Esta cláusula es para los sistemas de ingeniería de Oracle como Exadata. Sin embargo, en los sistemas sin ingeniería, Oracle parece permitir esta cláusula, pero no funciona como cabría esperar. Para ilustrar, siga este ejemplo, que se ejecutó en una base de datos RAC de dos nodos en mi MacBook Pro con VirtualBox... definitivamente no es un sistema diseñado.

Primero, se crea una tabla y luego se modifica para INMEMORY DUPLICATE.

SQL> create table db_objs
 2 as select * From dba_objects;
Table created.
SQL> alter table db_objs inmemory duplicate;
Table altered.

¿No debería generar un error establecer esta cláusula ya que este es un sistema sin ingeniería?

La tabla se verifica para mostrar que se especifica DUPLICATE.

SQL> select inmemory,inmemory_duplicate 
 2 from user_tables where table_name='DB_OBJS';
INMEMORY INMEMORY_DUPL
-------- -------------
ENABLED  DUPLICATE

Un simple formulario de "selección *" de la tabla se emite en la instancia 1. Luego podemos verificar que la tabla está en memoria.

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

Tenga en cuenta que los resultados anteriores muestran que el segmento está solo en la instancia 1. La misma tabla se consulta en la instancia 2, pero al consultar GV$IM_SEGMENTS aún se muestra solo la instancia 1.

De la instancia 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 |
---------------------------------------------------------------------------------------

De la instancia 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 |
---------------------------------------------------------------------------------------

Entonces, desde cualquier instancia, se accedió a la tabla INMEMORY. Pero podemos ver que solo la instancia 1 tiene el segmento InMemory.

Todos los signos apuntan a que la cláusula DUPLICATE funciona en un sistema no diseñado, lo que sabemos que es un error. DBA_TABLES parece indicar que DUPLICATE está en juego aquí. El plan de explicación proporciona concurrencia. Pero GV$IM_SEGMENTS no está de acuerdo y muestra que DUPLICATE no funciona en este sistema.