Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

InMemory DUPLICATE Confusão no Oracle RAC


A maioria das pessoas provavelmente conhece o novo recurso do Oracle 12.1.0.2, a opção de banco de dados InMemory. Ao usar essa opção no Oracle RAC, o DBA pode especificar a cláusula DUPLICATE para que um objeto seja duplicado entre o armazenamento de colunas InMemory em todas as instâncias. Esta cláusula é para os sistemas projetados da Oracle, como o Exadata. No entanto, em sistemas não projetados, a Oracle parece permitir essa cláusula, mas não funciona como se poderia esperar. Para ilustrar, siga este exemplo, que foi executado em um banco de dados RAC de dois nós no meu MacBook Pro com VirtualBox... definitivamente não é um sistema projetado.



Primeiro, uma tabela é criada e depois alterada 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.



A definição desta cláusula não deveria gerar um erro, pois este é um sistema não projetado?

A tabela é verificada para mostrar que DUPLICATE está especificado.
SQL> select inmemory,inmemory_duplicate 
 2 from user_tables where table_name='DB_OBJS';
INMEMORY INMEMORY_DUPL
-------- -------------
ENABLED  DUPLICATE



Com um simples “select *” a tabela é emitida na instância 1. Podemos então verificar se a tabela é 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

Observe que os resultados acima mostram que o segmento está apenas na instância 1. A mesma tabela é consultada na instância 2, mas a consulta GV$IM_SEGMENTS ainda mostra apenas a instância 1.

Da instância 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 |
---------------------------------------------------------------------------------------

Da instância 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 |
---------------------------------------------------------------------------------------

Portanto, de qualquer instância, a tabela foi acessada INMEMORY. Mas podemos ver que apenas a instância 1 possui o segmento InMemory.



Todos os sinais apontam para a cláusula DUPLICATE como funcionando em um sistema não projetado, o que sabemos ser um erro. DBA_TABLES parece indicar que DUPLICATE está em jogo aqui. O Plano Explicar fornece concorrência. Mas GV$IM_SEGMENTS discorda e mostra que DUPLICATE não está funcionando neste sistema.