Dotyczy:
Baza danych Oracle — 12.1.0.2
Autor:
Mahesh Reddy M
Wprowadzenie:
Po wprowadzeniu opcji In-Memory bazy danych Oracle 12c pojedyncza baza danych może teraz efektywnie obsługiwać mieszane obciążenia, zapewniając optymalną wydajność transakcji, wspierając jednocześnie analizę i raportowanie w czasie rzeczywistym. Funkcja In-Memory obsługuje zarówno składnice danych, jak i hurtownie danych w celu zapewnienia bardziej doraźnych analiz, dzięki czemu użytkownicy końcowi mogą wysyłać wiele zapytań biznesowych w czasie potrzebnym na wykonanie jednego zapytania. Funkcja ta umożliwia przechowywanie kolumn, tabel, partycji i zmaterializowanych widoków w pamięci w formacie kolumnowym, a nie w typowym formacie wiersza. Przechowywanie kolumnowe In-Memory (przechowywanie kolumnowe IM) to jedna z głównych funkcji zestawu poprawek 12.1.0.2.
Architektura bazy danych Oracle 12c In-Memory:
Dane tradycyjnie są przechowywane tylko w formacie wierszowym, natomiast opcja In-Memory przechowuje dane wyłącznie w formacie kolumnowym. Baza danych Oracle 12c obsługuje więc architekturę w dwóch formatach.
- Po wysłaniu żądania danych dla operacji odczytu/zapisu (manipulacje danymi) dane są ładowane do tradycyjnego magazynu wierszowego (buforowana pamięć podręczna)
- W przypadku żądania danych w celu wykonania operacji tylko do odczytu są one zapełniane w postaci nowego magazynu kolumnowego In-Memory. To zapełnianie danych obejmuje oczywiście transformację z formatu wierszowego na kolumnowy.
- Przy każdej transakcji obejmującej operacje wstawiania, aktualizacji lub usuwania, nowe dane będą wyświetlane od razu i jednocześnie pojawią się zarówno w magazynie wierszowym, jak i w magazynie kolumnowym In-Memory. Z tego względu oba magazyny są spójne transakcyjnie
Magazyn kolumnowy In-Memory:
Baza danych In-Memory wykorzystuje magazyn kolumnowy, będący nowym elementem składowym globalnego obszaru pamięci SGA (System Global Area), zwanym obszarem In-Memory. Dane w magazynie kolumnowym IM nie są przechowywane w tradycyjnym formacie wierszowym, a zamiast tego korzystają z nowego formatu kolumnowego. Magazyn kolumnowy IM nie zastępuje buforowanej pamięci podręcznej, ale stanowi jej uzupełnienie, dzięki czemu dane są teraz przechowywane w pamięci zarówno w formacie wierszowym, jak i kolumnowym
Obszar In-Memory to statyczna pula w pamięci SGA, której rozmiar jest zależny od parametru INMEMORY_SIZE (domyślnie 0). Bieżący rozmiar obszaru In-Memory jest widoczny w widoku V$SGA
Magazyn kolumnowy IM jest dalej podzielony na dwie pule:
- Pula o rozmiarze 1 MB — przechowywanie faktycznych danych w formacie kolumnowym
- Pula o rozmiarze 64 KB — przechowywanie metadanych dotyczących obiektów.
Ilość pamięci dostępnej w poszczególnych pulach można wyświetlić za pomocą poniższego zapytania
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 |
Tabela 1: Pamięć dostępna w poszczególnych pulach
Włączanie magazynu kolumnowego IM:
Tak jak w przypadku puli statycznej, wszelkie zmiany parametru INMEMORY_SIZE zostaną wprowadzone dopiero po ponownym uruchomieniu instancji bazy danych. Funkcja automatycznego zarządzania pamięcią (AMM) nie ma na nią wpływu i nie może jej kontrolować. Minimalny rozmiar obszaru In-Memory to 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.
Używając poniższego zapytania, można wyświetlić ustawienia obszaru In-Memory
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
Parametr inmemory_size można również ustawić na poziomie CDB i PDB. W przypadku ustawienia tego parametru na poziomie PDB nie ma potrzeby ponownego uruchamiania instancji lub PDB. Suma wszystkich PDB jest mniejsza lub równa wartości CDB.
Opcję In-Memory na poziomie PDB można włączyć i wyłączyć, jak pokazano poniżej
Połącz się z PDB, a następnie wykonaj poniższe polecenie
Wyłączanie:
Alter system set inmemory_size=0; or
Alter system reset inmemory_size;
Włączanie:
Alter system set inmemory_size=20G;
Poziomy priorytetu In-Memory:
Magazyn kolumnowy IM powinien zostać zapełniony danymi o najważniejszym znaczeniu dla wydajności w bazie danych. Dane o mniejszym znaczeniu dla wydajności mogą być przechowywane w pamięci flash lub na dysku o mniejszym koszcie. Oczywiście, jeśli baza danych jest odpowiednio mała, wszystkie dane z tabel można wprowadzić do magazynu kolumnowego IM. Baza danych In-Memory dodaje nowy atrybut INMEMORY dla tabel i zmaterializowanych widoków.
Atrybut INMEMORY można włączyć na poziomie
obszaru tabeli, tabeli, partycji (podrzędnej) i zmaterializowanego widoku.
W przypadku włączenia tego atrybutu na poziomie obszaru tabeli wszystkie widoki i zmaterializowane widoki w obszarze tabeli będą domyślnie włączone dla magazynu IMCOLUMN.
alter tablespace quest INMEMORY;
Włączenie tego atrybutu na poziomie tabeli oznacza, że wszystkie kolumny tabeli powinny zostać wprowadzone do magazynu IMCOLUMN. Magazyn IMCOLUMN można także zapełnić tylko podzbiorem kolumn.
Alter table quest_tab INMEMORY NO Inmemory (EMP);
Podobnie w przypadku tabeli partycjonowanej
Alter table quest_tab INMEMORY MODIFY Partition quest_part_1 No Inmemory;
Procesy w tle:
IMCO: proces w tle IMCO inicjuje wypełnianie (wstępne wypełnianie) obiektów obsługujących opcję In-Memory o priorytecie ważności LOW/MEDIUM/HIGH/CRITICAL.
SMCO: proces SMCO dynamicznie duplikuje procesy podrzędne (Wnnn) w celu wykonania tych zadań.
Wnnn: procesy Wnnn przetwarzają zadania zapełniania In-Memory i ponownego zapełniania In-Memory w celu zapełnienia lub ponownego zapełniania obiektów obsługujących opcję In-Memory.
Obiekty są wprowadzane do magazynu kolumnowego IM w postaci listy z priorytetem natychmiast po otworzeniu bazy danych lub po przeskanowaniu obiektów (wykonaniu zapytania) po raz pierwszy. Kolejność wypełniania obiektów zależy od słowa kluczowego PRIORITY, który ma pięć poziomów. Domyślną wartością PRIORITY jest NONE (BRAK), co oznacza, że obiekt jest wypełniany tylko po pierwszym przeskanowaniu
Inne poziomy priorytetu kontrolowane przez klauzulę podrzędną PRIORITY klauzuli INMEMORY
Poziom priorytetu Opis
CRITICAL Obiekt jest wypełniany bezpośrednio po otworzeniu bazy danych
HIGH Obiekt jest wypełniany po wypełnieniu wszystkich obiektów o priorytecie CRITICAL
MEDIUM Obiekt jest wypełniany po wypełnieniu wszystkich obiektów o priorytecie CRITICAL i HIGH
LOW Obiekt jest wypełniany po wypełnieniu wszystkich obiektów o priorytecie CRITICAL, HIGH i MEDIUM
NONE Obiekty są wypełniane po pierwszym przeskanowaniu (ustawienie domyślne)
Obiekty o rozmiarze mniejszym niż 64 KB nie są umieszczane w pamięci, gdyż zajęłyby znaczną ilość miejsca w magazynie kolumnowym IM, ponieważ pamięć jest przydzielona we fragmentach o rozmiarze 1 MB.
Przykład: alter table quest inmemory priority critical;
Techniki kompresji In-Memory:
Magazyn kolumnowy IM wykorzystuje specjalne formaty kompresji zoptymalizowane pod kątem szybkości dostępu, a nie redukcji zajmowanego miejsca. Szybkość działania bazy danych jest zwiększana w następujące sposoby:
- Formaty kompresji umożliwiają bazie danych zmniejszenie ilości pamięci przetwarzanej dla poszczególnych kolumn. Zapytania SQL są wykonywane bezpośrednio na skompresowanych kolumnach.
- Baza danych wykorzystuje instrukcje wektorowe (tablicowe) SIMD do przetwarzania tablicy wartości kolumn w jednym cyklu zegara procesora. Baza danych może przechowywać wiele wartości w postaci wektora, co maksymalizuje korzyści płynące z przetwarzania wektorowego SIMD.
Kompresja In-Memory jest określana za pomocą słowa kluczowego MEMCOMPRESS, klauzuli podrzędnej atrybutu INMEMORY. Istnieje sześć poziomów, z których każdy zapewnia inny poziom kompresji i wydajności.
No Memcompress: dane w opcji In-Memory są wypełniane bez kompresji.
Memcompress for DML: poziom przeznaczony głównie do zwiększania wydajności DML i minimalnej kompresji.
Memcompress for Query Low: poziom zoptymalizowany od kątem wydajności zapytań (ustawienie domyślne).
Memcompress for Query High: poziom zoptymalizowany od kątem wydajności zapytań i oszczędzania miejsca
Memcompress for Capacity Low: wyższy poziom oszczędzania miejsca w porównaniu do poziomu Query High i Low
Memcompress for Capacity High: poziom zoptymalizowany pod kątem oszczędzania miejsca i trochę mniejszej wydajności.
Stopień kompresji może mieć wartości z zakresu od 2X do 20X, w zależności od wybranej opcji kompresji, typu danych i zawartości tabeli.
Przykład: alter table quest inmemory memcompress for query high;
Magazyn kolumnowy IM w RAC:
W środowisku klastrowym każdy węzeł ma własny magazyn kolumnowy. Każdy węzeł klastra powinien utrzymywać taki sam rozmiar magazynu kolumnowego IM. Domyślnie wszystkie obiekty umieszczane w pamięci zostaną rozproszone po wszystkich magazynach kolumnowych IM w klastrze. Rozpraszanie obiektów po magazynach kolumnowych IM w klastrze jest kontrolowane przez dwie dodatkowe klauzule podrzędne atrybutu INMEMORY: DISTRIBUTE i DUPLICATE (tylko systemy techniczne).
Rozpraszanie:
Obiekty rozproszone w klastrze są kontrolowane przez klauzulę podrzędną DISTRIBUTE. Możliwe jest rozpraszanie obiektów w następujący sposób:
Distribute by rowed range — rozpraszanie obiektów w postaci wierszy do różnych węzłów
Distribute by partition— rozpraszanie partycji do węzłów w klastrze
Distribute by sub partition — rozpraszanie partycji podrzędnych do różnych węzłów.
Przykład: alter table quest inmemory distribute by partition;
W tym miejscu warto zwrócić uwagę na fakt, że Oracle In-Memory RAC to
architektura typu shared-nothing dla zapytań. Oznacza to, że podczas wykonywania zapytania na obiektach danych In-Memory (przyjmując, że obiekty te są rozproszone w dwóch magazynach kolumnowych IM) dostęp można uzyskać tylko do danych w pokrewnym węźle; jednostki kompresji In-Memory (IMCU) nie są współdzielone przez instancje w klastrze.
Dlatego też
poziom równoległości (DOP) można ustawić na AUTO (Automatyczny). Koordynator zapytań równoległych identyfikuje inne instancje jednostek IMCU. Jeśli poziomu DOP nie można ustawić na AUTO, koordynator zapytań równoległych nie będzie korzystać z innych wystąpień jednostek IMCU.
Ustawianie poziomu równoległości na automatyczny
alter system set parallel_degree_policy=AUTO scope=both sid='*';
Powielanie:
Aby zwiększyć dostępność, obiekty są kopiowane do wszystkich instancji. Za pomocą klauzuli podrzędnej DUPLICATE można sprawdzić, czy tabela In-Memory jest przechowywana we wszystkich instancjach w klastrze. Ta opcja nie działa w systemach nieinżynieryjnych.
Przykład: alter table quest inmemory duplicate all;
Tabela quest jest przechowywana we wszystkich instancjach.
Monitorowanie obiektów In-Memory:
W celu monitorowania obiektów In-Memory firma Oracle wprowadziła dwa nowe widoki V$
v$IM_SEGMENTS or v$IM_USER_SEGMENTS i v$IM_COLUMN_LEVEL.
Za pomocą tych widoków można sprawdzić, ile obiektów znajduje się aktualnie w magazynie IMCOLUMN.
EX:
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
EX:
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
W powyższym przykładzie dwie tabele — Customer i Supplier — nie mają wartości w kolumnie INMEMORY. Atrybut INMEMORY to atrybut na poziomie segmentu. Customer i Supplier są tabelami partycjonowanymi, a co za tym idzie obiektami logicznymi. Atrybut INMEMORY dla tych tabel zostanie zapisany na poziomie partycji lub partycji podrzędnej w *_TAB_ (SUB) PARTITIONS.
Do widoków *_TABLES dodano także trzy dodatkowe kolumny — INMEMORY_PRIORITY, INMEMORY_DISTRIBUTE i INMEMORY_COMPRESSION — wskazujące bieżące atrybuty In-Memory dla każdej tabeli.