قابلیت Automatic In-Memory در اوراکل 18c

قبلا در مطلب “ADO و مدیریت in-memory” بیان شد که چگونه می توان در سطوح مختلف(SET INMEMORY، MODIFY INMEMORY و NO INMEMORY) پالیسیهایی را به objectهایی که خصیصه inmmory برای انها فعال  شده است، اضافه کرد.

این پالیسها سبب می شد تا پس از گذشتن مدتی زمانی از ایجاد، آخرین اصلاح و یا آخرین زمان دسترسی، خصیصه inememory برای objectای تنظیم یا حذف شود و یا آنکه سطح فشرده سازی شی در inememory تغییر کند. این قابلیت(“مدیریت in-memory از طریق ADO“) در اوراکل 12cR2 ارائه شده بود.

در نسخه 18c، اوراکل بهبود دیگری را در این زمینه ایجاد کرد. به این صورت که اگر قصد بارگذاری شی جدیدی را در inmemory داشته باشیم ولی فضای inmemory برای این کار کافی نباشد، اوراکل می تواند با کمک قابلیت  Automatic In-Memory که به اختصار، AIM هم شناخته می شود، objectهای که کمتر به آنها رجوع شده را از طریق آمارها شناسایی کند(نیازی به فعال کردن Heat Map نخواهد بود) و آنها را از inmemory خارج کند تا بتواند شی جدید را در inmemory قرار دهد البته با این شرط که شی جدید، بسیار پر استفاده باشد.

پس با این توضیح، زمانی که فضای inmemory به قدری باشد که بتوان همه objectهای با خصیصه inememory را در آن قرار داد، استفاده از قابلیت AIM توجیه ای نخواهد داشت. علاوه بر این نکته، باید در نظر داشت که ویژگی Automatic In-Memory صرفا می تواند objectهای با اولویت NONE را از حافظه خارج کند(INMEMORY PRIORITY =NONE) بنابرین اگر اولویت همه objectها به مقداری غیر از NONE تنظیم شده باشد، باز هم استفاده از این قابلیت اثرگذار نخواهد بود.

در حالت پیش فرض، این قابلیت غیرفعال است و برای فعال کردن آن باید پارامتر INMEMORY_AUTOMATIC_LEVEL را به یکی از دو مقدار LOW و یا MEDIUM تنظیم کرد که مقدار LOW سبب خواهد شد تا AIM صرفا segmentهایی که کمتر فعال هستند را از حافظه خارج کند(EVICT) ولی MEDIUM علاوه بر انجام عملیات EVICT، عملیات POPULATE را هم انجام خواهد داد.

مثال: در این مثال خواهیم دید که حجم inmemory صرفا گنجایش قرار گرفتن سه جدول را به صورت کامل دارا می باشد ولی ما قصد داریم با کمک قابلیت AIM، جدولی که کمتر مورد استفاده قرار گرفته است را بیرون رانده و جداول پر استفاده را در inememory قرار دهیم.

SQL> select segment_name,round(inmemory_size/1024/1024) inmemory_size_MB,round(bytes/1024/1024) SIZE_MB,BYTES_NOT_POPULATED, POPULATE_STATUS from v$im_segments;

SQL> select pool, alloc_bytes, used_bytes, populate_status from v$inmemory_area;

قبل از آنکه قابلیت AIM را فعال کنیم، در چنین شرایطی جدول mytbl5 را فراخوانی می کنیم:

SQL> declare

  2  a number;

  3  begin

  4    for i in 1..10000 loop

  5      select /*+full(a)*/ count(*) into a from mytbl5 a;

  6    end loop;

  7  end;

  8  /

PL/SQL procedure successfully completed

 

SQL> select segment_name,round(inmemory_size/1024/1024) inmemory_size_MB,round(bytes/1024/1024) SIZE_MB,BYTES_NOT_POPULATED, POPULATE_STATUS from v$im_segments;

همانطور که می بینید، جدول mytbl5 به inmemory منتقل نشده است! این تست را پس از فعال کردن قابلیت AIM در سطح low تکرار می کنیم:

SQL>  alter system set “_exadata_feature_on”=true scope=spfile;

System altered.

SQL> alter system set INMEMORY_AUTOMATIC_LEVEL =low scope=spfile;

System altered.

SQL> declare

  2  a number;

  3  begin

  4    for i in 1..10000 loop

  5      select /*+full(a)*/ count(*) into a from mytbl5 a;

  6    end loop;

  7  end;

  8  /

PL/SQL procedure successfully completed

با تنظیم پارامتر INMEMORY_AUTOMATIC_LEVEL خواهیم دید که جدول mytbl5 در حافظه قرار گرفته است:

SQL> select segment_name,round(inmemory_size/1024/1024) inmemory_size_MB,round(bytes/1024/1024) SIZE_MB,BYTES_NOT_POPULATED, POPULATE_STATUS from v$im_segments;

از طریق ویوی DBA_INMEMORY_AIMTASKS می توان Taskهای ایجاد شده توسط قابلیت AIM را مشاهده کرد:

SQL> select * from DBA_INMEMORY_AIMTASKS;

همانطور که می بینید، آخرین TASK اجرا شده شماره 267 می باشد با کمک ویوی DBA_INMEMORY_AIMTASKDETAILS جزییات بیشتری را از این task مشاهده خواهیم کرد:

SQL> select object_name,action,state from DBA_INMEMORY_AIMTASKDETAILS where TASK_ID=267;

نکته پایانی

با کمک پروسیجر AIM_SET_PARAMETER از بسته DBMS_INMEMORY_ADMIN می توان تنظیم کرد که AIM آمارهای چند روز گذشته را ملاک قرار دهد:

SQL> EXEC DBMS_INMEMORY_ADMIN.AIM_SET_PARAMETER ( DBMS_INMEMORY_ADMIN.AIM_STATWINDOW_DAYS, 7 );

PL/SQL procedure successfully completed

همچنین مقدار جاری پارامتر AIM_STATWINDOW_DAYS با کمک پروسیجر aim_get_parameter قابل تعیین است:

SQL> exec DBMS_INMEMORY_ADMIN.aim_get_parameter(DBMS_INMEMORY_ADMIN.AIM_STATWINDOW_DAYS,:a);

PL/SQL procedure successfully completed

a

———

31

 

ارتباط با نویسنده مطلب:vahidusefzadeh@ کانال تخصصی اوراکل و لینوکس: OracleDB@

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.