Applicabile a:
Oracle Database - 12.1.0.2
Autore:
Mahesh Reddy M
Introduzione:
Con l'introduzione dell'opzione In-Memory in Oracle Database 12c, un unico database può ora supportare in modo efficiente carichi di lavoro misti, assicurando prestazioni ottimali per le transazioni e supportando contemporaneamente analitica e reporting in tempo reale. L'opzione In-Memory consente a datamart e data warehouse di offrire analitica ad hoc dando agli utenti finali la possibilità di eseguire simultaneamente molteplici query di dati aziendali nel tempo che attualmente si impiega per eseguirne una sola. Questa funzionalità consente di archiviare colonne, tabelle, partizioni e viste materializzate nella memoria in formato colonnare invece che nel tipico formato su righe. La funzione di archiviazione colonnare in-memory (In-Memory Column Store) era la funzione principale del set di patch 12.1.0.2.
Architettura dell'in-memory di Oracle Database 12c :
Generalmente i dati vengono archiviati solo in formato riga mentre il database in-memory archivia dati solo in formato colonna. Oracle Database 12c supporta quindi un'architettura a doppio formato.
- Quando i dati vengono richiesti per operazioni di lettura/scrittura (manipolazione dei dati), vengono caricati nel tradizionale archivio su righe (cache del buffer).
- Quando i dati vengono richiesti per operazioni di sola lettura, vengono aggiunti in un nuovo archivio colonnare in-memory. L'aggiunta, naturalmente, include anche una conversione dal formato riga al formato colonna.
- Quando viene confermata una transazione che include inserimenti, aggiornamenti o eliminazioni, i nuovi dati appaiono istantaneamente e simultaneamente in entrambi gli archivi, quello su righe e quello colonnare in-memory. Entrambi gli archivi, pertanto, sono coerenti dal punto di vista transazionale.
L'archivio colonnare in-memory:
Il database in-memory utilizza un archivio colonnare in-memory, un nuovo componente della SGA (System Global Area) chiamato area in-memory. I dati nell'archivio colonnare in-memory non risiedono nel tradizionale formato riga ma viene invece utilizzato un nuovo formato colonna. L'archivio colonnare in-memory non sostituisce la cache del buffer ma la integra consentendo di archiviare i dati in memoria sia in formato riga che colonna.
L'area in-memory è un pool statico della SGA le cui dimensioni sono controllate dal parametro di inizializzazione INMEMORY_SIZE (valore predefinito 0). Le dimensioni attuali dell'area in-memory sono visibili in V$SGA
L'archivio colonnare in-memory è ulteriormente diviso in due pool:
- Pool da 1 MB, dove vengono archiviati i dati in formato colonna
- Pool da 64 KB, dove vengono archiviati i metadati sugli oggetti.
Per verificare la memoria disponibile in ciascun pool si utilizza la seguente query:
SQL> select * from v$inmemory_area;
POOL |
ALLOC_BYTES |
USED_BYTES |
POPULATE_STATUS |
CON_I |
1MB POOL |
2.5767E+11 |
2.3569E+11 |
DONE |
1 |
64KB POOL |
6.4408E+10 |
876347392 |
DONE |
1 |
1MB POOL |
2.5767E+11 |
2.3569E+11 |
DONE |
2 |
64KB POOL |
6.4408E+10 |
876347392 |
DONE |
2 |
1MB POOL |
2.5767E+11 |
2.3569E+11 |
DONE |
3 |
64KB POOL |
6.4408E+10 |
876347392 |
DONE |
3 |
Tabella 1: memoria disponibile in ciascun pool
Abilitazione dell'archivio colonnare in-memory:
Essendo un pool statico, qualsiasi modifica al parametro INMEMORY_SIZE non produce alcun effetto finché l'istanza del database non viene riavviata. Neanche l'AMM (Automatic Memory Management) esercita alcun effetto o controllo. Le dimensioni minime dell'area in-memory devono essere di 100 MB.
sql> ALTER SYSTEM SET SGA_TARGET=500G SCOPE=SPFILE;
sql> ALTER SYSTEM SET INMEMORY_SIZE=300G SCOPE=SPFILE;
sql>SHUTDOWN IMMEDIATE;
sql>STARTUP;
ORACLE instance started.
Total System Global Area 4.2950E+11 bytes
Fixed Size 7677400 bytes
Variable Size 2.0938E+10 bytes
Database Buffers 8.5899E+10 bytes
Redo Buffers 529190912 bytes
In-Memory Area 3.2212E+11 bytes
Database mounted.
Database opened.
Per visualizzare le impostazioni in-memory si utilizza la seguente query:
SQL> SHOW PARAMETER INMEMORY
NAME TYPE VALUE
---------------------------------- ----------- -----
inmemory_clause_default string
inmemory_force string DEFAULT
inmemory_max_populate_servers integer 1
inmemory_query string ENABLE
inmemory_size biginteger 300G
inmemory_trickle_repopulate_servers_ integer 1
percent
optimizer_inmemory_aware boolean TRUE
È possibile impostare il parametro inmemory_size anche a livello di CDB e PDB. Se si imposta questo parametro a livello di PDB, non è necessario riavviare l'istanza o il PDB. Il valore della somma di tutti i PDB è inferiore o uguale al valore del CDB.
È possibile abilitare e disabilitare l'opzione In-Memory a livello di PDB come indicato di seguito:
Collegarsi al PDB ed eseguire il seguente comando:
Disattivazione:
Alter system set inmemory_size=0; or
Alter system reset inmemory_size;
Attivazione:
Alter system set inmemory_size=20G;
Livelli di priorità in-memory:
Nell'archivio colonnare in-memory devono essere aggiunti i dati del database a cui si deve accedere con maggiore frequenza. I dati meno attivi possono risiedere in memorie flash o su dischi meno costosi. È ovvio che se il database non è molto esteso è possibile aggiungere nell'archivio colonnare in-memory tutte le tabelle. Il database in-memory aggiunge un nuovo attributo INMEMORY per tabelle e viste materializzate.
L'attributo INMEMORY può essere abilitato in:
tablespace, tabella, partizione (secondaria) e vista materializzata.
Se si abilita questo attributo a livello di tablespace tutte le tabelle e le viste materializzate nello spazio utilizzato dalle tabelle verranno abilitate per impostazione predefinita per l'archivio IMCOLUMN.
alter tablespace quest INMEMORY;
Se si abilita questo attributo a livello di tabella, tutte le colonne della tabella devono essere aggiunte all'archivio IMCOLUMN. Nell'archivio IMCOLUMN, tuttavia, è possibile aggiungere solo un sottoinsieme di colonne.
Alter table quest_tab INMEMORY NO Inmemory (EMP);
Analogamente, per una tabella partizionata:
Alter table quest_tab INMEMORY MODIFY Partition quest_part_1 No Inmemory;
Processi in background:
IMCO: il processo in background IMCO inizia l'aggiunta (pre-popolamento) degli oggetti abilitati all'in-memory con priorità LOW/MEDIUM/HIGH/CRITICAL (bassa/media/alta/critica).
SMCO: questo processo installa processi slave (Wnnn) per implementare queste attività.
Wnnn: i processi Wnnn eseguono le attività di popolamento in-memory e ripopolamento in-memory per la prima o la seconda aggiunta di oggetti abilitati all'in-memory.
Gli oggetti vengono aggiunti all'archivio colonnare in-memory in un elenco ordinato in base alla priorità immediatamente dopo l'apertura del database o dopo essere stati interrogati la prima volta. L'ordine nel quale gli oggetti vengono aggiunti viene controllato con la parola chiave PRIORITY, che ha cinque livelli. Il livello predefinito è NONE, che indica che un oggetto viene aggiunto solo dopo essere stato interrogato la prima volta.
I diversi livelli di priorità vengono controllati con la sottoclausola PRIORITY della clausola INMEMORY.
Livello di priorità Descrizione
CRITICAL L'oggetto viene aggiunto immediatamente dopo l'apertura del database
HIGH L'oggetto viene aggiunto dopo che sono stati aggiunti tutti gli oggetti CRITICAL
MEDIUM L'oggetto viene aggiunto dopo che sono stati aggiunti tutti gli oggetti CRITICAL e HIGH
LOW L'oggetto viene aggiunto dopo che sono stati aggiunti tutti gli oggetti CRITICAL, HIGH e MEDIUM
NONE Gli oggetti vengono aggiunti solo dopo essere stati interrogati la prima volta (impostazione predefinita)
Gli oggetti di dimensioni inferiori a 64 KB non vengono aggiunti nella memoria poiché, dato che la memoria viene allocata in blocchi da 1 MB, occuperebbero una notevole quantità di spazio all'interno dell'archivio colonnare in-memory.
Esempio: alter table quest inmemory priority critical;
Tecniche di compressione dell'in-memory:
L'archivio colonnare in-memory utilizza speciali formati di compressione, ottimizzati per privilegiare la velocità di accesso piuttosto che la riduzione dell'archivio. La velocità del database aumenta nei modi seguenti:
- I formati di compressione consentono al database di ridurre la quantità di memoria elaborata per ciascuna colonna. SQL viene eseguito direttamente sulle colonne compresse.
- Il database utilizza le istruzioni vettoriali SIMD (array) per elaborare un array di valori di colonna in un singolo ciclo di clock della CPU. Il database può memorizzare numerosi valori in un vettore, massimizzando i vantaggi in termini di prestazioni con l'elaborazione vettoriale SIMD.
La compressione in-memory viene specificata utilizzando la parola chiave MEMCOMPRESS, una sottoclausola dell'attributo INMEMORY. I livelli disponibili sono sei, ognuno dei quali offre un diverso livello di compressione e prestazioni.
No Memcompress: i dati vengono aggiunti all'in-memory senza compressione.
Memcompress for DML: utilizzato principalmente per le prestazioni del DML con un livello di compressione minimo.
Memcompress for Query Low: ottimizzato per le prestazioni delle query (impostazione predefinita)
Memcompress for Query High: ottimizzato per le prestazioni delle query e per risparmiare spazio
Memcompress for Capacity Low: consente di risparmiare più spazio rispetto ai livelli Query High e Query Low
Memcompress for Capacity High: ottimizzato per risparmiare spazio e meno per le prestazioni.
Il rapporto di compressione può variare da 2 a 20 volte a seconda dell'opzione scelta, del tipo di dati e del contenuto della tabella.
Esempio: alter table quest inmemory memcompress for query high;
Archivio colonnare in-memory su RAC:
In un ambiente cluster ogni nodo ha un proprio archivio colonnare. Ciascun nodo del cluster deve avere un archivio colonnare in-memory delle stesse dimensioni. Per impostazione predefinita, tutti gli oggetti in memoria vengono distribuiti in tutti gli archivi colonnari in-memory del cluster. La distribuzione degli oggetti in tutti gli archivi colonnari in-memory del cluster viene controllata con due altre sottoclausole dell'attributo INMEMORY: DISTRIBUTE e DUPLICATE (solo Engineered Systems).
Distribute:
Gli oggetti distribuiti nel cluster vengono controllati con la sottoclausola distribute. È possibile distribuire gli oggetti nei seguenti modi:
Distribute by rowed ranage: distribuisce gli oggetti in intervalli di righe in nodi diversi
Distribute by Partition: distribuisce le partizioni nei nodi all'interno del cluster
Distribute by sub partition: distribuisce la partizione secondaria in nodi diversi.
Esempio: alter table quest inmemory distribute by partition;
È importante osservare che il RAC in-memory Oracle è
un'architettura shared-nothing per le query. Ciò significa che se si esegue una query sugli oggetti dei dati in-memory (presupponendo che gli oggetti siano distribuiti in due archivi colonnari in-memory), è possibile accedere solo ai dati che risiedono nel nodo di affinità e che le IMCU (unità di compressione in-memory) non sono condivise in tutte le istanze del cluster.
Pertanto, è possibile impostare
il grado di parallelismo (DOP) su AUTO. Il coordinatore delle query in parallelo identifica le altre istanze della posizione di una IMCU. Se il grado di parallelismo non può essere impostato su AUTO, il coordinatore delle query in parallelo non utilizzerà le altre istanze delle IMCU.
Impostazione del grado di parallelismo su auto:
alter system set parallel_degree_policy=AUTO scope=both sid='*';
Duplicate:
Per aumentare la disponibilità, gli oggetti vengono copiati in tutte le istanze. È possibile utilizzare la sottoclausola duplicate per specificare che la tabella in-memory deve essere archiviata in tutte le istanze all'interno del cluster. Questa opzione non è disponibile per i sistemi non-engineered.
Esempio: alter table quest inmemory duplicate all;
la tabella di ricerca viene archiviata in tutte le istanze.
Monitoraggio degli oggetti in-memory:
Per monitorare gli oggetti in-memory, Oracle ha aggiunto due nuove viste V$:
v$IM_SEGMENTS o v$IM_USER_SEGMENTS e v$IM_COLUMN_LEVEL.
Utilizzando queste viste è possibile conoscere quanti oggetti si trovano attualmente nella memoria IMCOLUMN.
Esempio:
set linesize 256
set pagesize 999
select segment_name,ROUND(SUM(BYTES)/1024/1024/1024,2) "DATA GB",
ROUND(SUM(INMEMORY_SIZE)/1024/1024/1024,2) "IN-MEM GB",
ROUND(SUM(BYTES-BYTES_NOT_POPULATED)*100/SUM(BYTES),2) "% IN_MEM",
ROUND(SUM(BYTES-BYTES_NOT_POPULATED)/SUM(INMEMORY_SIZE),2) "COMP RATIO"
from V$IM_SEGMENTS
group by owner,segment_name
order by SUM(bytes) desc;
SEGMENT_NAME ORIG GB IN-MEM GB % IN_MEM COMP RATIO
H_LINEITEM 317.27 68.2 88.77 4.13
H_PARTSUPP 35.17 21.04 100 1.67
Esempio:
set linesize 256
set pagesize 999
set verify off
col OBJECT format a30
SELECT owner||'.'||table_name OBJECT,
inmemory INMEMORY,inmemory_priority PRIORITY,
inmemory_distribute DISTRIBUTE,inmemory_compression COMPRESSION,
inmemory_duplicate DUPLICATE
FROM all_tables
where owner='QUEST'
ORDER BY inmemory, owner||'.'||table_name;
OBJECT INMEMORY PRIORITY DISTRIBUTE COMPRESSION DUPLICATE
H_NATION ENABLED CRITICAL AUTO FOR QUERY HIGH NO DUPLICATE
H_REGION ENABLED CRITICAL AUTO FOR QUERY HIGH NO DUPLICATE
H_CUSTOMER
H_SUPPLIER
Nell'esempio sopra riportato, si può notare che due delle tabelle, Customer e Supplier, non hanno un valore per la colonna INMEMORY. L'attributo INMEMORY è un attributo a livello di segmento. Customer e Supplier sono entrambe tabelle partizionate e dunque oggetti logici. L'attributo INMEMORY per queste tabelle verrà registrato a livello della partizione o della partizione secondaria in *_TAB_ (SUB) PARTITIONS.
Altre tre colonne, INMEMORY_PRIORITY, INMEMORY_DISTRIBUTE e INMEMORY_COMPRESSION, vengono anch'esse aggiunte alle viste *_TABLES per indicare gli attributi InMemory attualmente impostati per ogni tabella.