Van toepassing op:
Oracle database – 12.1.0.2
Auteur:
Mahesh Reddy M
Inleiding:
Met de introductie van In-Memory in Oracle Database 12c kan een enkele database nu efficiënt ondersteuning bieden voor gemengde workloads. Hierbij worden optimale prestaties geleverd voor transacties en tegelijk realtime analyses en rapportering ondersteund. Met In-Memory kunnen zowel datamarts als datawarehouses meer ad-hoc analyses leveren, waardoor eindgebruikers de mogelijkheid krijgen om in het belang van de bedrijfsefficiëntie meerdere query's in te dienen in dezelfde tijd die nu nog nodig is om slechts één query uit te voeren. Met deze functies kunt u kolommen, tabellen, partities en gematerialiseerde weergaven in het geheugen opslaan in een kolomopmaak in plaats van in de gewoonlijke rij-opmaak. Het in het geheugen opslaan van data in de kolomopmaak (in een IM-kolomarchief) was de belangrijkste nieuwe functie in de 12.1.0.2-patchset.
Oracle Database 12c In-Memory-architectuur:
Gewoonlijk wordt data alleen in RIJ-opmaak opgeslagen, terwijl bij de Database In-Memory-functie data alleen in kolomopmaak wordt opgeslagen. Dus biedt Oracle Database 12c ondersteuning voor de architectuur van twee typen opmaak.
- Wanneer data worden opgevraagd voor lees-/schrijfbewerkingen (datamanipulatie), worden deze geladen in de traditionele rij-opslag (buffercache)
- Wanneer data worden opgevraagd voor alleen-lezen bewerkingen, worden ze opgenomen/ingevuld in een nieuw In-Memory-kolomarchief. Deze invulling/populatie omvat uiteraard een transformatie van de rij- naar de kolomopmaak.
- Wanneer een transactie met invoegingen, updates of verwijderingen wordt uitgevoerd, worden de nieuwe data direct en tegelijk weergegeven in zowel de rij-opmaak als de In-Memory-kolomopmaak. Daarom zijn beide opslagarchieven transactioneel consistent
Het In-Memory-kolomarchief:
In-Memory in Database maakt gebruik van een In-Memory-kolomarchief, een nieuw component van de System Global Area (SGA), genaamd de In-Memory-ruimte. Data in het IM-kolomarchief bevinden zich niet in de traditionele rij-opmaak maar in een nieuwe kolomopmaak. Het IM-kolomarchief vervangt de buffercache niet, maar fungeert als aanvulling, zodat de data nu in het geheugen kunnen worden opgeslagen in zowel een rij- als een kolomopmaak.
De In-Memory-ruimte is een statische pool binnen de SGA waarvan de grootte wordt bepaald door de initialisatieparameter INMEMORY_SIZE (standaard 0). De huidige grootte van de In-Memory-ruimte is zichtbaar in V$SGA
Het IM-kolomarchief wordt onderverdeeld in twee pools:
- Pool van 1 MB - Hier worden de werkelijke data in kolomopmaak opgeslagen
- Pool van 64K - Hier worden de metadata over de objecten opgeslagen.
We kunnen zien hoeveel geheugen beschikbaar is in elke pool met behulp van onderstaande 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 |
Tabel 1: Geheugen beschikbaar in elke pool
IM-kolomarchief inschakelen:
Als een statische pool, gaan wijzigingen in de INMEMORY_SIZE-parameter pas van kracht nadat de database-instantie opnieuw is opgestart. Dit wordt ook niet beïnvloed of bepaald door het automatische geheugenbeheer (AMM). De In-Memory-ruimte moet minimaal 100 MB groot zijn.
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.
We kunnen de In-Memory-instellingen zien met behulp van de onderstaande opdracht
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
We kunnen ook de inmemory_size-parameter instellen op CDB- en PDB-niveau. Als u deze parameter instelt op PDB-niveau, hoeft u de instantie of PDB niet opnieuw te starten. De som van alle PDB-waarden is minder dan of gelijk aan de CDB-waarde.
We kunnen de In-Memory-optie in-en uitschakelen op PDB-niveau zoals hieronder wordt weergegeven.
Maak verbinding met PDB en voer de volgende opdracht uit
Uitschakelen:
Alter system set inmemory_size=0; or
Alter system reset inmemory_size;
Inschakelen:
Alter system set inmemory_size=20G;
In-Memory-prioriteitsniveaus:
In het IM-kolomarchief moeten de voor prestaties meest essentiële data in de database worden opgenomen. Data die minder essentieel zijn voor de prestaties kunnen zich elders op een flash of schijf bevinden. Als uw database klein genoeg is, kunt u natuurlijk al uw tabellen in het IM-kolomarchief invullen. In-Memory in Database voegt een nieuw INMEMORY-kenmerk toe voor tabellen en gematerialiseerde weergaven.
We kunnen het INMEMORY-kenmerk inschakelen voor
tabelruimte, tabel, (sub)partitie en gematerialiseerde weergave.
Als u dit kenmerk inschakelt op tabelruimte-niveau, worden alle tabellen en gematerialiseerde weergaven in de tabelruimte standaard ingeschakeld voor opslag in het IM-kolomarchief.
alter tablespace quest INMEMORY;
Als u dit kenmerk op tabelniveau inschakelt, worden alle kolommen van de tabel ingevuld in het IM-kolomarchief. Het is echter mogelijk om slechts een subset van kolommen in te vullen in het IM-kolomarchief.
Alter table quest_tab INMEMORY NO Inmemory (EMP);
Dit doen we op dezelfde wijze voor de gepartitioneerde tabel
Alter table quest_tab INMEMORY MODIFY Partition quest_part_1 No Inmemory;
Achtergrondprocessen:
IMCO: Het IMCO-achtergrondproces initieert een populatie (prepopulatie) van objecten waarvoor In-Memory is ingeschakeld met de prioriteit LOW/MEDIUM/HIGH/CRITICAL.
SMCO: SMCO spawnt op dynamische wijze de slave-processen (Wnnn) om deze taken uit te voeren.
Wnnn: Wnnn-processen voeren taken voor In-Memory-populatie en -herpopulatie uit voor populatie of herpopulatie van objecten waarvoor In-Memory is ingeschakeld.
Objecten worden in het IM-kolomarchief ingevuld, hetzij in een geprioriteerde lijst direct nadat de database is geopend of nadat ze voor de eerste keer gescand zijn/hiervoor een query is ingediend. De volgorde waarin de objecten worden ingevuld, wordt bepaald door het trefwoord PRIORITY, dat vijf niveaus heeft. De standaard-PRIORITEIT is NONE, wat betekent dat een object alleen wordt ingevuld nadat het voor de eerste keer is gescand.
Verschillende prioriteitsniveaus bepaald door het subcomponent PRIORITY van het component INMEMORY
Prioriteitsniveau Beschrijving
CRITICAL Object wordt onmiddellijk na het openen van de database ingevuld
HIGH Object wordt ingevuld nadat al de objecten met KRITIEKE prioriteit zijn ingevuld
MEDIUM Object wordt ingevuld nadat alle objecten met KRITIEKE en HOGE prioriteit zijn ingevuld.
LOW Object wordt ingevuld nadat alle objecten met KRITIEKE, HOGE en GEMIDDELDE prioriteit zijn ingevuld.
NONE Objecten worden alleen ingevuld nadat ze voor de eerste keer zijn gescand (standaard)
Objecten die kleiner zijn dan 64 KB worden niet in het geheugen ingevuld omdat deze een aanzienlijke hoeveelheid ruimte in het IM-kolomarchief zouden verspillen omdat geheugen wordt toegewezen in segmenten van 1 MB.
Bijv.: alter table quest inmemory priority critical;
In-Memory-compressietechnieken:
Het IM-kolomarchief maakt gebruikt van speciale typen compressie-opmaak die zijn geoptimaliseerd voor toegangssnelheid in plaats van voor storagereductie. De database verhoogt de snelheid op de volgende manieren:
- De compressie-opmaak stelt de database in staat om de hoeveelheid geheugen die voor elke kolom moet worden verwerkt, te verlagen. SQL wordt rechtstreeks uitgevoerd op de gecomprimeerde kolommen.
- De database maakt gebruik van SIMD-vector- (array) instructies voor het verwerken van een array van kolomwaarden in een enkele CPU-klokcyclus. In de database kunnen veel waarden worden opgeslagen in een vector, waardoor met SIMD-vector-verwerking prestatievoordelen worden gemaximaliseerd.
In-Memory-compressie wordt gespecificeerd met behulp van het sleutelwoord MEMCOMPRESS, een subcomponent van het kenmerk INMEMORY. Er zijn zes niveaus, die elk een verschillend niveau van compressie en prestaties bieden.
No Memcompress: De data wordt opgenomen in het geheugen zonder compressie.
Memcompress for DML: Dit is voornamelijk voor DML-prestaties en minimale compressie.
Memcompress for Query Low: Geoptimaliseerd voor queryprestaties (standaard).
Memcompress for Query High: Geoptimaliseerd voor queryprestaties én ruimtebesparing
Memcompress for Capacity Low: Meer ruimtebesparend dan Query High en Low
Memcompress for Capacity High: Geoptimaliseerd voor ruimtebesparing en iets mindere prestaties.
Compressieverhoudingen kunnen variëren van 2X - 20X, afhankelijk van de gekozen compressieoptie, het dataype en de inhoud van de tabel.
Bijv.: alter table quest inmemory memcompress for query high;
In-Memory-kolomarchief op RAC:
In de clusteromgeving heeft elk knooppunt zijn eigen kolomarchief. Elk knooppunt in het cluster moet gelijk zijn aan de grootte van het IM-kolomarchief. Standaard worden alle objecten die ingevuld zijn in het geheugen verdeeld over alle IM-kolomarchieven in het cluster. De verdeling van objecten over de IM-kolomarchieven in een cluster wordt bepaald door twee aanvullende subcomponenten van het kenmerk INMEMORY: DISTRIBUTE en DUPLICATE (alleen Engineered-systemen).
Distribute:
De verdeling van de objecten over het cluster wordt bepaald door het subcomponent distribute. U kunt de objecten op de volgende manieren verdelen
Distribute by rowed ranage - Hiermee verdeelt u de objecten per rij over verschillende knooppunten
Distribute by partition - Hiermee verdeelt u de partities over knooppunten in het cluster
Distribute by sub partition - Hiermee verdeelt u de subpartitie over verschillende knooppunten.
Bij.: alter table quest inmemory distribute by partition;
Hierbij is het belangrijk te vermelden dat Oracle In-Memory RAC een
'share-nothing'-architectuur is voor query's. Dit houdt in dat als u een query indient voor In-Memory-dataobjecten (aangenomen dat objecten zijn verdeeld in twee IM-kolomarchieven), u alleen toegang hebt tot de data die zich bevindt in het affiniteitsknooppunt. Dit betekent dat de IMCU's (In-Memory Compression Units) niet worden gedeeld over de instanties in het cluster.
U kunt dus de
Degree of parallelism (DOP) instellen op AUTO. De parallelle-query-coördinator identificeert de andere instanties van de IMCU-locatie. Als u de DOP niet kunt instellen op AUTO, zal de parallelle-query-coördinator geen gebruikmaken van de andere IMCU-instanties.
set the degree of parallel to auto
alter system set parallel_degree_policy=AUTO scope=both sid='*';
Duplicate:
Om de beschikbaarheid te verhogen, worden objecten naar alle instanties gekopieerd. U kunt de subcomponent duplicate gebruiken om op te geven dat de In-Memory-tabel wordt opgeslagen in alle instanties binnen het cluster. Voor non-engineered systemen werkt deze optie niet.
Bijv.: alter table quest inmemory duplicate all;
de query-tabel wordt opgeslagen in alle instanties.
In-Memory-objecten controleren:
Voor het controleren van In-Memory-objecten, introduceert Oracle twee nieuwe V$weergaven, nl.
v$IM_SEGMENTS of v$IM_USER_SEGMENTS en v$IM_COLUMN_LEVEL.
Met behulp van deze weergaven kunnen we zien hoeveel objecten momenteel zijn ingevuld in het IM-kolomarchief.
BIJV.:
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
BIJV.:
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
In het bovenstaande voorbeeld ziet u dat twee van de tabellen – Customer en Supplier – geen waarde hebben voor de INMEMORY-kolom. Het kenmerk INMEMORY is een kenmerk op segmentniveau. Zowel Customer als Supplier zijn gepartitioneerde tabellen en dus logische objecten. Het kenmerk INMEMORY voor deze tabellen wordt geregistreerd op het niveau van de partitie of subpartitie in *_TAB_ (SUB) PARTITIONS.
Drie extra kolommen – INMEMORY_PRIORITY, INMEMORY_DISTRIBUTE en INMEMORY_COMPRESSION – zijn ook toegevoegd aan de * _TABLES-weergaven om de huidige INMEMORY-kenmerken voor elke tabel aan te geven.