معتبر ماندن وضعیت ایندکسهای Global در حین انجام عملیات Drop و Truncate پارتیشنها

می دانیم که در اوراکل 11g با حذف و یا truncate کردن پارتیشنهای یک جدول، ایندکسهای GLOBAL مربوط به آن جدول هم در وضعیت unusable قرار می گیرند مگر انکه در حین اجرای دستور alter table .. drop partition از عبارت  update indexes استفاده شود در این صورت، ایندکسهای از نوع global این جدول در صورت وجود، بصورت فوری بازسازی خواهند شد و دستور تا بازسازی کامل این ایندکسها، به کارش خاتمه نخواهد داد.

برای مثال، در قسمت زیر می بینید که حذف پارتیشن p_2000 بهمراه بازسازی ایندکس گلوبال inddd1 زمانی بیشتر از ایجاد ایندکس inddd1 به طول انجامیده است که این زمان برای حذف یک پارتیشن می تواند بسیار زیاد باشد مخصوصا زمانی که با حجم زیادی از دیتا سروکار داریم.

–in 11g

SQL> set timing on;

SQL> create index inddd1 on mtbl(name) global;

Index created.

Elapsed: 00:00:32.68

SQL> alter table mtbl drop partition p_2000 update indexes;

Table altered.

Elapsed: 00:00:37.65

SQL> select status from user_indexes p where p.index_name=’INDDD1′;

STATUS

————————

VALID

در اوراکل 12c، در این رفتار تغییری ایجاد شده که بر اساس ان، با حذف پارتیشن یک جدول، اطلاعات مربوط به این پارتیشن در ایندکس های از نوع global، به صورت فوری حذف نمی شود و در همین حال، این ایندکس در حالت VALID باقی خواهند ماند از این رو، سرعت اجرای دستور drop partition و truncate partition بسیار بهینه خواهد شد:

–12c

SQL> set timing on;

SQL> create index inddd1 on mtbl(name) global;

Index created.

Elapsed: 00:00:24.63

SQL> alter table mtbl drop partition p_2000 update indexes;

Table altered.

Elapsed: 00:00:00.13

SQL> select status from user_indexes p where p.index_name=’INDDD1′;

STATUS

————————

VALID

اوراکل، اطلاعاتی از ایندکس که مربوط به پارتیشن حذف شده می باشد را به عنوان ORPHANED ENTRIES می شناسد به همین جهت، به ویوی DBA_INDEXES ستونی را با عنوان ORPHANED_ENTRIES اضافه کرده که اگر مقدار این ستون برای ایندکسی برابر با Y باشد، به این معنی خواهد بود که ایندکس مورد نظر، حاوی اطلاعاتی از پارتیشن حذف شده می باشد و نیاز به عملیات cleanup دارد.

در همین زمینه جابی با نام PMO_DEFERRED_GIDX_MAINT_JOB وجود دارد که عملیات cleanup ایندکسها را هر روز ساعت دو صبح انجام میدهد.

FREQ=DAILY; BYHOUR=02; BYMINUTE=0; BYSECOND=0

این جاب پروسیجر cleanup_gidx_internal از بسته dbms_part را اجرا می کند:

“dbms_part.cleanup_gidx_internal(noop_okay_in => 1);”

در ادامه با کمک پروسیچر فوق، ایندکس indd1 را cleanup می کنیم:

SQL>  create index inddd1 on mtbl(name) global;

Index created.

SQL> alter table mtbl drop partition p_2000 update indexes;

Table altered

SQL>select index_name,bytes/1024/1024 SIZE_MB, num_rows,s.blocks,leaf_blocks,orphaned_entries from dba_indexes i, dba_segments s

 where i.index_name = s.segment_name and segment_name = ‘INDDD1’

SQL> alter session force parallel ddl parallel 10;

Session altered.

SQL>  exec dbms_part.cleanup_gidx(‘USEF’, ‘MTBL’);

PL/SQL procedure successfully completed.

Elapsed: 00:02:07.57

با کمک دستور زیر می بینید که فضایی از ایندکس ازاد نشده است:

SQL> select index_name,bytes/1024/1024 SIZE_MB, num_rows,s.blocks,leaf_blocks,orphaned_entries from dba_indexes i, dba_segments s where i.index_name = s.segment_name and segment_name = ‘INDDD1’;

همانطور که می بینید، حجم ایندکس برابر 344 مگابایت می باشد در صورتی که جدول مربوطه هیچ دیتایی ندارد:

SQL> SELECT COUNT(*) FROM MTBL;

0

با بازسازی ایندکس، فضای مربوطه ازاد خواهد شد:

SQL> alter index inddd1 rebuild;

Index altered.

Elapsed: 00:00:00.46

نکته: بسته dbms_part در سطوح مختلفی قابل اجرا می باشد:

در سطح دیتابیس:

SQL> exec dbms_part.cleanup_gidx();

در سطح اسکیما:

SQL> exec dbms_part.cleanup_gidx(‘USEF’);

برای اجرای عملیات cleanup برای یک ایندکس مشخص، می توان از دستور زیر استفاده کرد:

SQL> ALTER INDEX inddd1 COALESCE CLEANUP PARALLEL 10;

Index altered.

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

Comment (1)

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

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