{"id":343,"date":"2017-10-15T21:29:46","date_gmt":"2017-10-15T19:29:46","guid":{"rendered":"http:\/\/blog.sqlora.com\/de\/?p=343"},"modified":"2018-04-06T13:56:22","modified_gmt":"2018-04-06T11:56:22","slug":"ilm-storage-tiering","status":"publish","type":"post","link":"https:\/\/blog.sqlora.com\/de\/ilm-storage-tiering\/","title":{"rendered":"ILM storage tiering"},"content":{"rendered":"<p>Information Lifecycle Management ist zwar kein neuer Begriff in der Version 12c, wurde aber um zwei sehr praktische Features  bereichert: Heat Map and ADO (Automatic Data Optimization).  das letztere erlaubt es, die Regeln (Policies) f\u00fcr Datensegmente zu definieren, die wiederum aus Bedingungen und Aktionen bestehen.  Die Bedingungen werden grunds\u00e4tzlich anhand der mit Heat Map gesammelten Informationen \u00fcberpr\u00fcft und dann werden die definierten Aktionen ausgef\u00fchrt: Daten komprimieren (compression tiering) oder Daten verschieben (storage tiering). &#8222;Grunds\u00e4tzlich&#8220;, weil man zum einen benutzerdefinierte Bedingungen (PL\/SQL-Funktionen) verwenden kann, die nicht zwingend auf die Heat Map Informationen zur\u00fcckgreifen, und zum zweiten, weil es eine Art Unklarheit herrscht, wie und ob man die Bedingungen f\u00fcr Storage Tiering auch angeben kann.  <!--more--><\/p>\n<p>In 12.1 war das Syntaxdiagram f\u00fcr die ILM-Klausel irref\u00fchrend, da es suggeriert, dass man Policies basieren auf Bedingungen definieren kann. <\/p>\n<p><a href=\"http:\/\/blog.sqlora.com\/en\/wp-content\/uploads\/sites\/2\/2017\/10\/syntax_ilm-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.sqlora.com\/en\/wp-content\/uploads\/sites\/2\/2017\/10\/syntax_ilm-1.png\" alt=\"\" width=\"1017\" height=\"286\" class=\"alignnone size-full wp-image-451\" \/><\/a><\/p>\n<p>Offensichtlich war das ein Bug in der Dokumentation. Das hat einfach nicht funktioniert:<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSCOTT&gt; ALTER TABLE scott.employee\r\n  2  ILM ADD POLICY TIER TO low_cost_store\r\n  3  SEGMENT AFTER 10 DAYS OF NO MODIFICATION;\r\nSEGMENT AFTER 10 DAYS OF NO MODIFICATION\r\n        *\r\nERROR at line 3:\r\nORA-01735: invalid ALTER TABLE option \r\n\r\nSCOTT&gt; ALTER TABLE scott.employee ILM ADD POLICY TIER TO low_cost_store;\r\n\r\nTable altered.\r\n<\/pre>\n<p>Au\u00dfer benutzerdefinierter Bedingungen mit Hilfe der PL\/SQL-Funktionen hat nur die einfachste Form ohne Bedingung funktioniert. Die Entscheidung, wann das Verschieben der Datensegmente starten soll, h\u00e4ngt hier alleine vom verf\u00fcgbaren freien Platz im Tablespace. ADO-Parameter <strong>TBS_PERCENT_USED<\/strong> und <strong>TBS_PERCENT_FREE<\/strong> steuern dabei das Verhalten. <a href=\"http:\/\/www.oracle.com\/technetwork\/database\/automatic-data-optimization-wp-12c-1896120.pdf\" rel=\"noopener\" target=\"_blank\">Oracle&#8217;s White Paper<\/a> erkl\u00e4rt das Verhalten so:<\/p>\n<p><em>The justification for making storage tiering dependent on &#8222;space pressure&#8220; is exactly as you might imagine, the belief that organizations will want to keep as much data as possible on their high performance (and most expensive) storage tier, and not move data to a lower performance storage tier until it is absolutely required. The exception to the storage pressure requirement are storage tiering policies with the &#8218;READ ONLY&#8216; option, these are triggered by a heat-map based condition clause.<\/em><\/p>\n<p>Ich pers\u00f6nlich kann die Argumentation nicht 100% nachvollziehen. Auch wenn sich das logisch anh\u00f6rt, warum hat man die Option weggelassen, die Bedingungen \u00e4hnlich wie f\u00fcr Compression Tiering angeben zu k\u00f6nnen? Schlie\u00dflich sollte man es in der Lage sein, \u00fcber PL\/SQL-Funktionen selber zu programmieren. Aber der letzte Satz hat mich hellh\u00f6rig gemacht: geht da doch was? Hat sich die Dokumentation ge\u00e4ndert?<\/p>\n<p>&nbsp;<br \/>\nDie 12.2 Dokumentation bietet eine korrigierte Version des Sysntaxdiagrams f\u00fcr Storage Tiering (jetzt auch separat vom Compression Tiering):<\/p>\n<p><a href=\"http:\/\/blog.sqlora.com\/en\/wp-content\/uploads\/sites\/2\/2017\/10\/syntax_new_ilm.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.sqlora.com\/en\/wp-content\/uploads\/sites\/2\/2017\/10\/syntax_new_ilm.png\" alt=\"\" width=\"1134\" height=\"266\" class=\"alignnone size-full wp-image-453\" \/><\/a><\/p>\n<p>&nbsp;<br \/>\nLaut dem soll es wirklich m\u00f6glich sein, Bedingungen angeben zu k\u00f6nnen, aber nur f\u00fcr den Fall, dass die Daten in ein Read-Only Tablespace verschoben werden.<br \/>\nFunktioniert es wirklich so wie beschrieben? Wir probieren es und nehmen als Grundlage  <a href=\"http:\/\/www.oracle.com\/webfolder\/technetwork\/tutorials\/obe\/db\/12c\/r1\/ilm\/ilm_tiering\/ilm_tiering.html\" rel=\"noopener\" target=\"_blank\">Oracle&#8217;s Beispiel<\/a>.<\/p>\n<p>Als erstes legen wir den Tablespace, in den die Daten verschoben werden und setzten ihn auf Read-Only. Wichtig: dieser Tablespace wird zum Verschieben der Daten auf Read-Write umgestellt und dann wieder zur\u00fcck auf Read-Only. Aus diesem Grund braucht der Benutzer SCOTT die ALTER TALESPACE Rechte. <\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSYS&gt; create tablespace low_cost_store\r\n  2  datafile &#039;&amp;_data_path\/lowcoststore01.dbf&#039; size 1M ;\r\n\r\nTablespace created.\r\n\r\nSYS&gt; \r\nSYS&gt; alter tablespace low_cost_store read only;\r\n\r\nTablespace altered.\r\n\r\nSYS&gt; \r\nSYS&gt; grant alter tablespace, select any dictionary to scott;\r\n\r\nGrant succeeded.\r\n\r\nSYS&gt; ---------------------------------------------------------\r\nSYS&gt; -- Table EMPLOYEE is stored in default tablespace USERS\r\nSYS&gt; ---------------------------------------------------------\r\nSYS&gt; SELECT owner, segment_name, tablespace_name\r\n  2    FROM dba_segments\r\n  3   WHERE segment_name = &#039;EMPLOYEE&#039;;\r\n\r\nOWNER\t   SEGMENT_NAME \tTABLESPACE_NAME\r\n---------- -------------------- ------------------------------\r\nSCOTT\t   EMPLOYEE             USERS\r\n\r\n<\/pre>\n<p>&nbsp;<br \/>\nNun erstellen wir die Policy zum Verschieben der Daten nach zehn Tagen ohne \u00c4nderungen und lassen es \u00fcber Data Dictionary verifizieren. Bemerkenswert hier: wir haben ACTION_TYPE=&#8220;STORAGE&#8220; und trotzdem ist CONDITION_TYPE gesetzt.<br \/>\n&nbsp;<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n\r\nSCOTT&gt; -- Storage tiering with condition only to move to read-only tablespace\r\nSCOTT&gt; ALTER TABLE scott.employee\r\n  2  ILM ADD POLICY TIER TO low_cost_store READ ONLY\r\n  3  SEGMENT AFTER 10 DAYS OF NO MODIFICATION;\r\n\r\nTable altered.\r\n\r\nSCOTT&gt; \r\nSCOTT&gt; ----------------------------------------------------------------------------\r\nSCOTT&gt; -- Show ILM policy information\r\nSCOTT&gt; ----------------------------------------------------------------------------\r\nSCOTT&gt; SELECT policy_name, action_type, scope, tier_tablespace, condition_type, condition_days\r\n  2    FROM user_ilmdatamovementpolicies;\r\n\r\nPOLICY_NAME ACTION_TYPE SCOPE\tTIER_TABLESPACE  CONDITION_TYPE         CONDITION_DAYS\r\n----------- ----------- ------- ---------------- ---------------------- --------------\r\nP162\t    STORAGE     SEGMENT LOW_COST_STORE   LAST MODIFICATION TIME \t    10\r\n\r\nSCOTT&gt; \r\nSCOTT&gt; SELECT policy_name, object_name, object_type, enabled\r\n  2    FROM user_ilmobjects;\r\n\r\nPOLICY_NAME OBJECT_NAME \t OBJECT_TYPE\t    ENABLED\r\n----------- -------------------- ------------------ -------\r\nP162\t    EMPLOYEE\t\t TABLE\t\t    YES\r\n \r\n<\/pre>\n<p>&nbsp;<br \/>\nAls n\u00e4chstes machen wir den Trick mit dem Setzten der ILM Evaluierungszeit auf die Sekunden statt Tage, wir im Oracle&#8217;s Beispiel gezeigt, lassen Heat Map Informationen auf die Platte schreiben und warten mehr als zehn Sekunden:<br \/>\n&nbsp;<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\n\r\nSYS&gt; -- 1. Switch ILM unit to seconds\r\nSYS&gt; EXECUTE dbms_ilm_admin.customize_ilm(DBMS_ILM_ADMIN.POLICY_TIME, DBMS_ILM_ADMIN.ILM_POLICY_IN_SECONDS);\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSYS&gt; -- 2. set start date\r\nSYS&gt; EXECUTE DBMS_ILM_ADMIN.SET_HEAT_MAP_START(start_date =&gt; sysdate - 50);\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSYS&gt; EXECUTE dbms_ilm.flush_all_segments;\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSYS&gt; EXECUTE  dbms_lock.sleep(15);\r\n\r\nPL\/SQL procedure successfully completed. \r\n\r\n<\/pre>\n<p>&nbsp;<br \/>\nDann f\u00fchren wir den ILM-Job manuell aus und sehen, was passiert. Die Tabelle wurde in den neuen Tablespace <em><strong>low_cost_store<\/strong><\/em> verschoben. ILM-Task wurde ausgef\u00fchrt wie erwartet.<br \/>\n&nbsp;<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSCOTT&gt; ----------------------------------------------------------------------------------------------------\r\nSCOTT&gt; -- Run ILM data movement task\r\nSCOTT&gt; ----------------------------------------------------------------------------------------------------\r\nSCOTT&gt; declare\r\n  2  v_executionid number;\r\n  3  begin\r\n  4    dbms_ilm.execute_ILM (ILM_SCOPE =&gt; dbms_ilm.SCOPE_SCHEMA,\r\n  5  \t\t execution_mode =&gt; dbms_ilm.ilm_execution_offline,\r\n  6  \t\t task_id   =&gt; v_executionid);\r\n  7  end;\r\n  8  \/\r\n\r\nPL\/SQL procedure successfully completed.\r\n\r\nSCOTT&gt; ----------------------------------------------------------------------------------------------------\r\nSCOTT&gt; -- Table EMPLOYEE is now moved to tablespace LOW_COST_STORE\r\nSCOTT&gt; --------------------------------------------------------------------------------------------------\r\nSCOTT&gt; select tablespace_name, segment_name\r\n  2  from user_segments\r\n  3  where segment_name=&#039;EMPLOYEE&#039;;\r\n\r\nTABLESPACE_NAME \t       SEGMENT_NAME\r\n------------------------------ --------------------\r\nLOW_COST_STORE\t\t       EMPLOYEE\r\n\r\n1 row selected.\r\n\r\nSCOTT&gt; ----------------------------------------------------------------------------------------------------\r\nSCOTT&gt; -- Show ILM task results\r\nSCOTT&gt; --------------------------------------------------------------------------------------------------\r\nSCOTT&gt; SELECT task_id, to_char(start_time, &#039;dd\/mm\/yyyy hh24:mi:ss&#039;) as start_time\r\n  2  FROM user_ilmtasks;\r\n\r\n   TASK_ID START_TIME\r\n---------- -------------------\r\n       162 12\/10\/2017 14:50:24\r\n\r\n1 row selected.\r\n\r\nSCOTT&gt; select task_id, job_name, job_state, to_char(completion_time, &#039;dd\/mm\/yyyy hh24:mi:ss&#039;) completion\r\n  2  from user_ilmresults;\r\n\r\n   TASK_ID JOB_NAME\t   JOB_STATE\t\t\t       COMPLETION\r\n---------- --------------- ----------------------------------- ------------------------------\r\n       162 ILMJOB4148\t   COMPLETED SUCCESSFULLY\t       12\/10\/2017 14:50:26\r\n\r\n1 row selected. \r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Ich habe es auch in 12.1.0.1 getestet &#8211; es geht! Es war offensichtlich kein Enhancement oder Bugfix vom Release  12.1.0.2 oder 12.2.0.1, sondern einfach ein Bug der Dokumentation. Und \u00fcbrigens die Dokumentation wurde nun auch r\u00fcckwirkend f\u00fcr 12.1 korrigiert!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Information Lifecycle Management ist zwar kein neuer Begriff in der Version 12c, wurde aber um zwei sehr praktische Features bereichert: Heat Map and ADO (Automatic Data Optimization). das letztere erlaubt es, die Regeln (Policies) f\u00fcr Datensegmente zu definieren, die wiederum aus Bedingungen und Aktionen bestehen. Die Bedingungen werden grunds\u00e4tzlich anhand der mit Heat Map gesammelten [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,1,3,22],"tags":[46,48,49,47,50],"class_list":["post-343","post","type-post","status-publish","format-standard","hentry","category-12c","category-allgemein","category-oracle","category-trivadis","tag-information-lifecycle-management","tag-storage-tiering","tag-ado","tag-ilm","tag-policy"],"_links":{"self":[{"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/posts\/343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/comments?post=343"}],"version-history":[{"count":13,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/posts\/343\/revisions"}],"predecessor-version":[{"id":385,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/posts\/343\/revisions\/385"}],"wp:attachment":[{"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/media?parent=343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/categories?post=343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.sqlora.com\/de\/wp-json\/wp\/v2\/tags?post=343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}