در اوراکل 11g، جابجا کردن پارتیشنهای یک جدول، سبب ایجاد کندی در دستورات DMLای که بر روی ان پارتیشن اجرا می شوند، خواهد شد. در قسمت زیر، این مسئله را مشاهده می کنید:
–session 1:
SQL> select sid,serial# from v$session where sid=sys_context(‘USERENV’, ‘SID’) ;
SID SERIAL#
———- ———-
303 46939
SQL> alter table usef.mytbl move partition p_2010;
Runing…
–session 2:
SQL> insert into usef.mytbl values(1,TO_date(‘1-1-2009’, ‘DD-MM-YYYY’));
Waiting…
–session 3:
SQL> SELECT DECODE(request, 0, ‘Blocker: ‘, ‘Waiter: ‘) || sid sid, lmode,request,type FROM V$LOCK
WHERE (id1, id2, type) IN
(SELECT id1, id2, type FROM V$LOCK WHERE request > 0)
ORDER BY id1, request;
SID LMODE REQUEST TYPE
————— ———- ———- ——
Blocker: 303 6 0 TM
Waiter: 68 0 3 TM
از اوراکل نسخه 12cR1 می توان پارتیشنهای یک جدول را بصورت انلاین جابجا کرد با این کار اجرای همزمان دستورات DMLای بر روی پارتیشنی که در حال جابجایی است، امکان پذیر خواهد شد:
SQL*Plus: Release 12.1.0.2.0 Production on Sun Dec 15 10:53:14 2019
–session 1:
SQL> select sid,serial# from v$session where sid=sys_context(‘USERENV’, ‘SID’) ;
SID SERIAL#
———- ———-
425 2685
SQL> alter table usef.mytbl move partition p_2010;
Runing…
–session 2:
SQL> select sid,serial# from v$session where sid=sys_context(‘USERENV’, ‘SID’) ;
SID SERIAL#
———- ———-
65 28245
SQL> insert into usef.mytbl values(1,TO_date(‘1-1-2009’, ‘DD-MM-YYYY’));
1 row created.
البته در سناریوی فوق، دستور alter table در session 1، برای مدت زمان کوتاهی نیاز دارد تا جدول mytbl را به صورت انحصاری در اختیار بگیرد به همین دلیل، تا زمانی که session 2 دستور commit یا rollback را صادر نکند، session شماره 1 به کارش خاتمه نخواهد داد.
با جابجایی انلاین پارتیشنها، ایندکسها maintain شده و درنهایت در وضعیت valid باقی خواهند ماند البته این مسئله سبب بالا رفتن زمان اجرای دستور alter table خواهد شد و همچنین حجم ایندکسهای از نوع global به شدت افزایش خواهد یافت:
محاسبه زمان جابجایی افلاین یک پارتیشن به همراه بازسازی ایندکسهای آن:
SQL*Plus: Release 12.1.0.2.0 Production on Sun Dec 15 10:53:14 2019
SQL> set timing on
SQL> select status from dba_indexes p where p.index_name=’IND1′;
STATUS
————————
VALID
Elapsed: 00:00:00.05
SQL> alter table usef.mytbl move partition p_2010;
Table altered.
Elapsed: 00:00:30.48
SQL> select status from dba_indexes p where p.index_name=’IND1′;
STATUS
————————
UNUSABLE
Elapsed: 00:00:00.00
SQL> alter index usef.IND1 rebuild;
Index altered.
Elapsed: 00:01:08.11
SQL> select bytes/1024/1024 from dba_segments where segment_name=’IND1′;
BYTES/1024/1024
—————
912
محاسبه زمان جابجایی آنلاین یک پارتیشن:
SQL> select status from dba_indexes p where p.index_name=’IND1′;
STATUS
————————
VALID
SQL> alter table usef.mytbl move partition p_2010 online;
Table altered.
Elapsed: 00:09:53.96
SQL> select status from dba_indexes p where p.index_name=’IND1′;
STATUS
————————
VALID
SQL> select bytes/1024/1024 from dba_segments where segment_name=’IND1′;
BYTES/1024/1024
—————
2359
همانطور که می بینید، جابجایی جدول به همراه نگهداشت ایندکس global، حدودا 10 دقیقه زمان برده است. علاوه بر ان، حجم ایندکس ind1 از 912 مگابایت به 2359 تغییر کرده است این اتفاق در ضورت رخ داده است که دیتایی به جدول اضافه نشده است. البته با بازسازی این ایندکس، مجددا حجم ان به مقدار قبلی برمی گردد:
SQL> alter index usef.IND1 rebuild;
Index altered.
SQL> select bytes/1024/1024 from dba_segments where segment_name=’IND1′;
BYTES/1024/1024
—————
912
Comment (1)