بروزرسانی کامل MV به صورت non-atomic

در صورتی که در زمان بروزرسانی mvها، نیازی به در دسترس بودن اطلاعات وجود ندارد، می توان در هنگام بروزرسانی کامل mv، از دستور truncate به جای delete استفاده کرد.

این تغییر سبب می شود تا هیچ فردی در زمان بروز رسانی mv، به اطلاعات آن دسترسی نداشته باشد پس این روش که اصطلاحا non-atomic هم نامیده می شود، خطراتی از قبیل لغو شدن بروزرسانی در حین درج اطلاعات را به همراه دارد که به همین دلیل استفاده کمتری نسبت به شیوه معمول دارد هر چند با استفاده از truncate به جای delete، سرعت بروزرسانی کامل(complete) بسیار افزایش خواهد یافت و کاهش حجم آرشیولاگ ایجاد شده دیتابیس هم از دیگر ثمرات آن می باشد.

برای انجام بروزرسانی کامل به صورت non-atomic، باید از پارامتر ATOMIC_REFRESH در هنگام بروزرسانی استفاده کرد با مقداردهی این پارامتر به false این مهم محقق می یابد. به مثال زیر توجه کنید.

ابتدا جدولی را به عنوان جدول مبنا ایجاد می کنیم:

SQL> create table tbl (id NUMBER(9), f1  VARCHAR2(500), f2  VARCHAR2(500)  );

سپس داده ای را در این جدول درج می کنیم:

BEGIN

  FOR I IN 1 .. 10

  LOOP

    INSERT   INTO tbl SELECT ROWNUM, object_name, status  FROM all_objects ;

      COMMIT;

  END LOOP;

END;

در نهایت برای جدول ساخته شده، mvای ایجاد می کنیم:

SQL>CREATE materialized VIEW mv_rbl  refresh complete AS  SELECT * FROM tbl;

فرض کنید بعد از ایجاد mv، جدول مذکور به صورت زیر update شده است:

SQL>update tbl set f2=’INVALID’ where  f2=’NA’;

commit;

برای انجام مقایسه بین دو شیوه atomic و non-atomic ابتدا بروزرسانی mv را به شیوه رایج انجام می دهیم(ATOMIC_REFRESH =>TRUE):

SQL>exec dbms_mview.refresh(‘MV_RBL‘,’C’, ATOMIC_REFRESH =>TRUE);

37.71 seconds

در حین انجام بروزرسانی، با استفاده از دستور زیر، در می یابیم که اطلاعات mv هیچ گاه به مقدار صفر نرسیده است(یعنی از دستور truncate استفاده نشده):

select count(*) from mv_rbl;

همچنین با فعال کردن تریس 10046 می توان به این نکته رسید:

oradebug event 10046 trace name context forever, level 12

exec dbms_mview.refresh(‘USEF.MV_RBL’,’C’, ATOMIC_REFRESH =>TRUE);

—-

PARSING IN CURSOR #140076244599440 len=28 dep=1 uid=103 oct=7 lid=103 tim=13246925014456 hv=3577189607 ad=’331d17c18′ sqlid=’a95k4pramg577′

 delete from “USEF”.”MV_RBL”

PARSING IN CURSOR #140076245143248 len=76 dep=1 uid=103 oct=2 lid=103 tim=13247005868367 hv=3209396475 ad=’31cec5fe0′ sqlid=’71rd2hkznr07v’

INSERT /*+ BYPASS_RECURSIVE_CHECK */ INTO “USEF”.”MV_RBL” SELECT * FROM tbl

همانطور که می بینید، ابتدا اطلاعات جدول MV_RBL به صورت کامل delete شده و سپس درج اطلاعات بر روی آن صورت می پذیرد.

در ادامه، این بروزرسانی را به صورت non-atomic انجام خواهیم داد:

exec dbms_mview.refresh(‘USEF.MV_RBL’,’C’,ATOMIC_REFRESH => FALSE);

0.904 seconds

PARSING IN CURSOR #140165309001632 len=53 dep=2 uid=103 oct=26 lid=103 tim=13247162930375 hv=235050888 ad=’bb91a738′ sqlid=’dsnthj87055w8′

LOCK TABLE “USEF”.”MV_RBL” IN EXCLUSIVE MODE  NOWAIT

PARSING IN CURSOR #140165309010104 len=50 dep=1 uid=103 oct=85 lid=103 tim=13247162930809 hv=792649949 ad=’e5fe7c50′ sqlid=’c4f5xw4rmxs6x’

 truncate table “USEF”.”MV_RBL” purge snapshot log

PARSING IN CURSOR #140165309010104 len=84 dep=1 uid=103 oct=2 lid=103 tim=13247163859142 hv=161261066 ad=’33d312a58′ sqlid=’14nhrx84tt9ha’

INSERT /*+ BYPASS_RECURSIVE_CHECK APPEND  */ INTO “USEF”.”MV_RBL” SELECT * FROM tbl

همانطور که می بینید، به دلیل استفاده از truncate به جای delete، اطلاعات با سرعت بسیار بیشتری به نسبت حالت قبلی بروز شده اند(تنها در 0.904 ثانیه) البته تعداد رکوردهای مربوط به mv زمانی به صفر رسیده است که به معنی از دسترس خارج شدن اطلاعات mv برای کاربران می باشد.

به طور خلاصه در مورد تفاوت بروزرسانی Non-Atomic و  Atomic می توان گفت:

1.روش Non-Atomic برای undo tablespace سربار زیادی ایجاد نمی کند در صورتی که روش Atomic استفاده بسیار زیادی از undoها دارد.

2.در روش non_atomic اطلاعات در زمان بروزرسانی در دسترس نخواهند بود ولی در روش atomic اطلاعات MV همیشه در دسترس خواهد بود.

3.در روش non_atomic، آمارها بروز می شوند(برخلاف روش atomic).

4.در روش non_atomicه، high water mark جابجا می شود.

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

Comments (2)

پاسخ دادن به مرتضی لغو پاسخ

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