Die meisten Leute kennen wahrscheinlich das neue Oracle 12.1.0.2-Feature, die InMemory-Datenbankoption. Bei Verwendung dieser Option auf Oracle RAC kann der DBA die DUPLICATE-Klausel angeben, damit ein Objekt in allen Instanzen im InMemory-Spaltenspeicher dupliziert wird. Diese Klausel gilt für Engineered Systems von Oracle wie Exadata. In nicht-Engineered-Systemen scheint Oracle diese Klausel jedoch zuzulassen, aber sie funktioniert nicht so, wie man es erwarten könnte. Folgen Sie zur Veranschaulichung diesem Beispiel, das auf einer RAC-Datenbank mit zwei Knoten auf meinem MacBook Pro mit VirtualBox ausgeführt wurde … definitiv kein Engineered-System.
Zuerst wird eine Tabelle erstellt und dann für INMEMORY DUPLICATE.
geändert
SQL> create table db_objs 2 as select * From dba_objects;
Table created.
SQL> alter table db_objs inmemory duplicate;
Table altered.
Sollte das Setzen dieser Klausel nicht einen Fehler auslösen, da dies ein nicht entwickeltes System ist?
Die Tabelle wird überprüft, um zu zeigen, dass DUPLICATE angegeben ist.
SQL> select inmemory,inmemory_duplicate 2 from user_tables where table_name='DB_OBJS';
INMEMORY INMEMORY_DUPL -------- ------------- ENABLED DUPLICATE
Ein einfaches „select *“-Formular für die Tabelle wird auf Instanz 1 ausgegeben. Wir können dann überprüfen, ob die Tabelle InMemory ist.
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
Beachten Sie, dass die obigen Ergebnisse zeigen, dass sich das Segment nur in Instanz 1 befindet. Dieselbe Tabelle wird in Instanz 2 abgefragt, aber die Abfrage von GV$IM_SEGMENTS zeigt immer noch nur Instanz 1.
Von Instanz 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 |
---------------------------------------------------------------------------------------
Von Instanz 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 |
---------------------------------------------------------------------------------------
Von beiden Instanzen aus wurde also INMEMORY auf die Tabelle zugegriffen. Aber wir können sehen, dass nur Instanz 1 das Segment InMemory hat.
Alle Anzeichen deuten darauf hin, dass die DUPLICATE-Klausel auf einem nicht entwickelten System arbeitet, von dem wir wissen, dass es sich um einen Fehler handelt. DBA_TABLES scheint darauf hinzudeuten, dass hier DUPLICATE im Spiel ist. Der Explain-Plan sorgt für Übereinstimmung. Aber GV$IM_SEGMENTS ist anderer Meinung und zeigt, dass DUPLICATE in diesem System nicht funktioniert.