Oracle 12c Ny funktion – Heat Map och Automatisk dataoptimering (ADO)

Ett av de viktigaste målen för ILM (Information LifeCycle Management) policyn är att minska kostnaderna för lagring, samt förbättra prestanda och åtkomsttider, för både aktuell och arkiverad data. Målet är även att lagra uppgifter tillräckligt länge för att uppfylla diverse lagar och förordningar för den berörda datan.

Allt eftersom datat växer kan man, istället för att köpa och installera ytterligare lagring vilket normalt är fallet, använda både storage samt compression tierings modeller för att uppnå sina ILM-mål och strategier.

Storage tiering kan användas till att lagra gammal och oanvänd data på billig lågprislagring, samtidigt som den nuvarande och/eller den mest aktuella datan behålls på snabba högprestanda-diskar.

Med hjälp av komprimering kan nuvarande eller OLTP data komprimeras med  lägre komprimeringsgrad. Den data som sällan accessas, liksom sällan förändras, kan eventuellt komprimeras med högre komprimering och även eventuellt flyttas till billig lågprestandadisk.

I Oracle 12c har man implementerat funktionen Heat Map, som spårar och markerar data, ända ner till rad- och blocknivå,  allt eftersom den genomgår sin ILM.

ADO eller Automatic Data Optimering  jobbar tillsammans med  Heat Map-funktionen och tillåter oss, baserat på statistik om dataanvändning, att skapa olika policys som anger villkoren för när data flyttas eller komprimeras på tabeller, objekt och till och med ner på radnivå (row level).

Realtidsdata access statistik samlas från minnet in i  V$HEAT_MAP_SEGMENT vyn och sedan spolas den regelbundet av DBMS_SCHEDULER_JOBS till  disk som HEAT_MAP_STAT$ som visas  via vyerna   DBA_HEAT_MAP_SEG_HISTOGRAM och DBA_HEAT_MAP_SEGMENT.

Heat Map aktiveras på instansnivå genom att parametern HEAT_MAP sätts till ON.

Låt oss nu titta på ett exempel som visar hur vi kan använda Heat Map och ADO för att utföra compression tiering av data.

Exemplet bygger på Oracle 12c databas tutorials som finns publicerade på Oracle Learning Library.

I det här exemplet kommer vi att skapa en ILM policy som kommer att komprimera tabellen MYOBJECTS om det inte har skett några ändringar på tabellen under de senaste 30 dagarna.

Vi kommer således att jobba med tesen att vilande data kan komprimeras för att spara disk då detta inte kommer att påverka prestandan i vår OLTP databas.

Först måste vi skapa en procedure som simulerar tiden, så att vår tabell kan användas av vår policy trots att det inte passerat 30 dagar:

CREATE OR REPLACE PROCEDURE set_stat (object_id number,
 data_object_id number,
 n_days number,
 p_ts# number,
 p_segment_access number)
 as
 begin
 insert into sys.heat_map_stat$
 (obj#,
 dataobj#,
 track_time,
 segment_access,
 ts#)
 values
 (object_id,
 data_object_id,
 sysdate - n_days,
 p_segment_access,
 p_ts# );
 commit;
 end;
 /

Sedan ger vi SCOTT grant execute till denna procedure, vi slår även på HEAT_MAP på instansnivå.

SQL> grant execute on set_stat to scott;
SQL> alter system set heat_map=on scope=both; 

Efter att vi har slagit på Heat Map tracking så ställer vi in vår HEAT_MAP att börja spara statistik efter 30 dagar, på så sätt vet vi att den statistiken kan användas av Automatic Data Optimizer (ADO)

exec dbms_ilm_admin.set_heat_map_start(start_date => sysdate - 30)

Vi ansluter nu som SCOTT och börjar populera tabellen med data genom att lägga till multipler av den befintliga tabellen all_objects:

SQL> create table myobjects as select * from all_objects;
Table created.

SQL> declare
 sql_test clob;
 begin
 for i in 1..5
 loop sql_test := 'insert /*+ append */ into scott.myobjects select * from scott.myobjects';
 execute immediate sql_test;
 commit;
 end loop;
 end;
 /

Nu ser vi att tabellen är på 320Mb samt innehåller 2360288 rader:

SQL> select sum(bytes)/1048576 from user_segments where
    segment_name='MYOBJECTS';

SUM(BYTES)/1048576
 ------------------
 320

SQL> select count(*) from myobjects;

COUNT(*)
 ----------
 2360288

Nu kan vi verifiera att vår HEAT_MAP har sparat statistik från tabellen SCOTT.MYOBJECTS.

SQL> alter session set nls_date_format='dd-mon-yy hh:mi:ss';

Session altered.

select OBJECT_NAME,SEGMENT_WRITE_TIME , SEGMENT_READ_TIME, FULL_SCAN
 FROM dba_heat_map_segment
 WHERE OBJECT_NAME='MYOBJECTS'
 AND OWNER = 'SCOTT';

OBJECT_NAME
 --------------------------------------------------------------------------------
 SEGMENT_WRITE_TIME SEGMENT_READ_TIME  FULL_SCAN
 ------------------ ------------------ ------------------
 MYOBJECTS
 14-may-14 09:50:19

col "Segment write" format A14
col "Full Scan" format A12
col "Lookup Scan" format a12

 select object_name, track_time "Tracking Time",
 segment_write "Segment write",
 full_scan "Full Scan",
 lookup_scan "Lookup Scan"
 from DBA_HEAT_MAP_SEG_HISTOGRAM
 where object_name='MYOBJECTS'
 and owner = 'SCOTT';

OBJECT_NAME
 --------------------------------------------------------------------------------
 Tracking Time      Segment write  Full Scan    Lookup Scan
 ------------------ -------------- ------------ ------------
 MYOBJECTS
 14-jun-14 09:51:43 NO             YES          NO

Sedan kan vi också verifiera att tabellerna inte redan är komprimerade.

SQL> select compression, compress_for from dba_tables where table_name='MYOBJECTS' and owner='SCOTT';

COMPRESS COMPRESS_FOR
 -------- ------------------------------
 DISABLED

Om tabellen inte är komprimerad kan vi nu skapa en komprimeringspolicy för tabellen SCOTT.MYOBJECTS

ALTER TABLE scott.myobjects ILM ADD POLICY ROW STORE
COMPRESS ADVANCED SEGMENT AFTER 30 DAYS OF NO MODIFICATION;

Verifera att policyn har skapats enligt våra önskemål:

SQL> Select policy_name, action_type, scope, compression_level,
 condition_type, condition_days
 from   user_ilmdatamovementpolicies
 order by policy_name;

POLICY_NAME
 --------------------------------------------------------------------------------
 ACTION_TYPE SCOPE   COMPRESSION_LEVEL              CONDITION_TYPE
 ----------- ------- ------------------------------ ----------------------
 CONDITION_DAYS
 --------------
 P3
 COMPRESSION SEGMENT ADVANCED                       LAST MODIFICATION TIME
 30

 select policy_name, object_name, inherited_from, enabled
 from user_ilmobjects;

POLICY_NAME
 --------------------------------------------------------------------------------
 OBJECT_NAME
 --------------------------------------------------------------------------------
 INHERITED_FROM       ENA
 -------------------- ---
 P3
 MYOBJECTS
 POLICY NOT INHERITED YES

 select * from user_ilmpolicies;
POLICY_NAME
 --------------------------------------------------------------------------------
 POLICY_TYPE   TABLESPACE                     ENABLED
 ------------- ------------------------------ -------
 P3
 DATA MOVEMENT                                YES

NU kan vi använda den procedure som vi skapade tidigare för att simulera att 30 dagar har passerat:

alter session set nls_date_format='dd-mon-yy hh:mi:ss';

declare
 v_obj# number;
 v_dataobj# number;
 v_ts#      number;
 begin
 select object_id, data_object_id into v_obj#, v_dataobj#
 from all_objects
 where object_name = 'MYOBJECTS'
 and owner = 'SCOTT';
 select ts# into v_ts#
 from sys.ts$ a,
 dba_segments b
 where  a.name = b.tablespace_name
 and  b.segment_name = 'MYOBJECTS';
 commit;
 sys.set_stat
 (object_id         => v_obj#,
 data_object_id    => v_dataobj#,
 n_days            => 30,
 p_ts#             => v_ts#,
 p_segment_access  => 1);
 end;
 /

Nu måste vi spola minnet i heat mappen till disk. Det kan göras på flera olika sätt. Ett snabbt men fult sätt är helt enkelt att starta om databasen istället för att vänta på att MMON processen ska göra jobbet.

Efter omstart ser vi att tabellen inte har accessats på över 30 dagar:

Select object_name, segment_write_time
 from dba_heat_map_segment
 where object_name='MYOBJECTS';

 OBJECT_NAME
 --------------------------------------------------------------------------------
 SEGMENT_W
 ---------
 MYOBJECTS
 13-MAY-14

Vanligtvis körs ADO relaterade jobb i ett ”Maintanence Windows”. Istället för att vänta på det så startar vi den manuellt genom att exekvera DBMS_ILM.EXECUTE_ILM proceduren.

SQL> conn scott/tiger
 Connected.
declare
v_executionid number;
begin
dbms_ilm.execute_ILM (ILM_SCOPE      => dbms_ilm.SCOPE_SCHEMA,
                      execution_mode => dbms_ilm.ilm_execution_offline,
                      task_id        => v_executionid);
end;
/

Till sist kan vi kolla om ADO jobbet har startas och om vår ILM policy har flaggats för exekvering.

All denna information hittas i tabellen USER_ILMTASKS.

select task_id, start_time as start_time from user_ilmtasks;
TASK_ID
----------
START_TIME
---------------------------------------------------------------------------
7
14-SEP-14 10.31.20.325062 AM
select task_id, job_name, job_state, completion_time completion from user_ilmresults;
TASK_ID
----------
JOB_NAME
--------------------------------------------------------------------------------
JOB_STATE
-----------------------------------
COMPLETION
---------------------------------------------------------------------------
8
ILMJOB1116
JOB CREATED
select task_id, policy_name, object_name, selected_for_execution, job_name
from user_ilmevaluationdetails
where task_id=11;
TASK_ID
----------
POLICY_NAME
--------------------------------------------------------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
SELECTED_FOR_EXECUTION
------------------------------------------
JOB_NAME
--------------------------------------------------------------------------------
8
P3
MYOBJECTS
TASK_ID
----------
POLICY_NAME
--------------------------------------------------------------------------------
OBJECT_NAME
--------------------------------------------------------------------------------
SELECTED_FOR_EXECUTION
------------------------------------------
JOB_NAME
--------------------------------------------------------------------------------
SELECTED FOR EXECUTION
ILMJOB1116

Eventuella resultat kan hittas i tabellen USER_ILMRESULTS

Select task_id, job_name, job_state, completion_time completion from user_ilmresults;
TASK_ID
----------
JOB_NAME
--------------------------------------------------------------------------------
JOB_STATE
-----------------------------------
COMPLETION
---------------------------------------------------------------------------
11
ILMJOB1118
COMPLETED SUCCESSFULLY
14-JUN-14 11.58.22.628812 AM

 select compression, compress_for FROM user_tables where table_name = 'MYOBJECTS';
COMPRESS COMPRESS_FOR
-------- ------------------------------
ENABLED  ADVANCED

Som vi nu ser så har vi i detta fall sparat 160MB utan att det i princip kommer att påverka vår prestanda då denna tabell troligen är ytterst sparsamt använd.

Select sum(bytes)/1048576 from user_segments where segment_name='MYOBJECTS';
SUM(BYTES)/1048576
------------------
60

Mer information på ämnet kan hittas på: