Ich hätte nie gedacht, dass ich oft über Information Lifecycle Management schreiben werde, da ich eigentlich ein Entwickler bin und kein DBA. Ich denke, ILM ist schon ein Thema, das mehr für die DBA’s Relevanz hat. Auf der anderen Seite ist es immer eine gute Sache, wenn Entwickler und DBA’s die Arbeit von einander verstehen, oder? In unserem Training „12c New Features für Entwickler“, von dem ich einer der Referenten bin, geben wir einen Einblick in die ILM Features. Das ist auch der Grund, warum ich mittlerweile schon den dritten Post darüber schreibe: um einige unklar dokumentierte Fragen auch für mich selber zu klären.
Nachdem wir uns in vorherigen Beiträgen die ADO Bedingungen für Storage Tiering Policies sowie die Verwendung von benutzerdefinierten ILM ADO Bedingungen mit PL/SQL angeschaut haben, wollte ich die Frage klären, ob es möglich ist, die Storage und Compression Policies für ein Datensegment zu mischen? Es könnte durchaus Sinn ergeben, z.B. Daten auf ein kostengünstigeren Datenträger zu verschieben und gleichzeitig zu komprimieren. Ich bin schon paar Mal über die Aussage gestolpert, das wäre nicht möglich. Es ist aber sehr einfach zu prüfen. So geht das:
Wir starten mit demselben Setup, wie in vorherigen Beiträgen über ILM ( 1 and 2) und definieren beide Policies für die Tabelle EMPLOYEE1: wir möchten Daten nach zehn Tagen ohne Zugriff zum Tablespace LOW_COST_STORE verschieben und gleichzeitig komprimieren (basic). Um den Komprimierungseffekt zu bestätigen, zeigen wir die initiale Größe des Datensegments an.
SYS> SELECT owner, segment_name, tablespace_name, bytes, blocks 2 FROM dba_segments 3 WHERE segment_name = 'EMPLOYEE1'; OWNER SEGMENT_NAME TABLESPACE_NAME BYTES BLOCKS ------- ------------- ----------------- -------- -------- SCOTT EMPLOYEE1 USERS 327680 40 SCOTT> ALTER TABLE scott.employee1 2 ILM ADD POLICY ROW STORE COMPRESS BASIC 3 SEGMENT AFTER 10 DAYS OF NO ACCESS; Table altered. SCOTT> SCOTT> -- Storage tiering with condition only to move to read-only tablespace SCOTT> ALTER TABLE scott.employee1 2 ILM ADD POLICY TIER TO low_cost_store READ ONLY 3 SEGMENT AFTER 10 DAYS OF NO ACCESS; Table altered. SCOTT> SELECT policy_name, action_type, scope, tier_tablespace, condition_type, condition_days 2 FROM user_ilmdatamovementpolicies; POLICY_NAME ACTION_TYPE SCOPE TIER_TABLESPACE CONDITION_TYPE CONDITION_DAYS ----------- ----------- ------- ----------------- ----------------- -------------- P307 COMPRESSION SEGMENT LAST ACCESS TIME 10 P308 STORAGE SEGMENT LOW_COST_STORE LAST ACCESS TIME 10 SCOTT> SCOTT> SELECT policy_name, object_name, object_type, enabled 2 FROM user_ilmobjects; POLICY_NAME OBJECT_NAME OBJECT_TYPE ENABLED ----------- -------------------- ------------------ ------- P307 EMPLOYEE1 TABLE YES P308 EMPLOYEE1 TABLEE YES
Zumindest keine Fehlermeldung, die Policies sind da und sind aktiviert. Scheint zu funktionieren. Aber werden die gewünschten Aktionen wirklich ausgeführt? Wir setzen den Parameter für die Zeiteinheiten auf die Sekunden, setzen die Startzeit, lassen die Heat Map Information auf die Platte schreiben und warten mehr als 10 Sekunden:
SCOTT> ---------------------------------------------------------------------------------------------------- SCOTT> -- Triggering the Table to Move to Low Cost Storage SCOTT> ---------------------------------------------------------------------------------------------------- SCOTT> -- 1. Switch ILM unit to seconds SCOTT> EXECUTE dbms_ilm_admin.customize_ilm(DBMS_ILM_ADMIN.POLICY_TIME, DBMS_ILM_ADMIN.ILM_POLICY_IN_SECONDS); PL/SQL procedure successfully completed. SCOTT> -- 2. set start date SCOTT> EXECUTE DBMS_ILM_ADMIN.SET_HEAT_MAP_START(sysdate -50); PL/SQL procedure successfully completed. SCOTT> EXECUTE dbms_ilm.flush_all_segments; PL/SQL procedure successfully completed. SCOTT> EXECUTE dbms_lock.sleep(15); PL/SQL procedure successfully completed.
Nun führen wir ILM manuell aus und schauen, was passiert:
SCOTT> declare 2 v_executionid number; 3 begin 4 dbms_ilm.execute_ILM (ILM_SCOPE => dbms_ilm.SCOPE_SCHEMA, 5 execution_mode => dbms_ilm.ilm_execution_offline, 6 task_id => v_executionid); 7 end; 8 / PL/SQL procedure successfully completed. SCOTT> ------------------------------------------------------------------------------ SCOTT> -- Table EMPLOYEE1 is now moved to tablespace LOW_COST_STORE and compressed SCOTT> ------------------------------------------------------------------------------ SCOTT> select tablespace_name, segment_name, bytes, blocks 2 from user_segments 3 where segment_name='EMPLOYEE1'; TABLESPACE_NAME SEGMENT_NAME BYTES BLOCKS ----------------- -------------- -------- ---------- LOW_COST_STORE EMPLOYEE1 131072 16 SCOTT> SELECT compression, compress_for 2 FROM user_tables WHERE table_name = 'EMPLOYEE1'; COMPRESS COMPRESS_FOR -------- ------------------------------ ENABLED BASIC
Und voilá, die Tabelle wurde verschoben und dabei komprimiert. Achten Sie darauf, wie die Große des Segments um fast zwei drittel zurückging. Die ILM Ausführungsinformationen im Data Dictionary bestätigen das:
SCOTT> SELECT task_id, to_char(start_time, 'dd/mm/yyyy hh24:mi:ss') as start_time, u.STATE 2 FROM user_ilmtasks u; TASK_ID START_TIME STATE ---------- ------------------- --------- 276 31/10/2017 17:14:38 COMPLETED SCOTT> SCOTT> select task_id, job_name, job_state, to_char(completion_time, 'dd/mm/yyyy hh24:mi:ss') completion, 2 from user_ilmresults; TASK_ID JOB_NAME JOB_STATE COMPLETION ---------- ------------ ------------------------ ------------------------------ 276 ILMJOB4438 COMPLETED SUCCESSFULLY 31/10/2017 17:14:39 SCOTT> SCOTT> select task_id, policy_name, object_name, selected_for_execution from user_ilmevaluationdetails; TASK_ID POLICY_NAME OBJECT_NAME SELECTED_FOR_EXECUTION ---------- ----------- --------------- ------------------------------------------ 276 P307 EMPLOYEE1 SELECTED FOR EXECUTION 276 P308 EMPLOYEE1 SELECTED FOR EXECUTION
Offensichtlich hat es funktioniert. Natürlich müssen die Policies bestimmten Regeln folgen und keine widersprechliche Bedingungen bzw. Aktionen haben. Eine Übersicht ist z.B. hier zu finden.