همانطور که می دانید، LOBها از اوراکل نسخه 11g به دو فرمت BasicFile و SecureFile قابل ایجاد هستند که به دلیل مزیتهای SecureFile(قابلیتهایی نظیر compression، deduplication و encryption)، اوراکل از نسخه 12cء، LOBها را به صورت پیش فرض با این فرمت(SecureFile) ایجاد می کند.
البته تا قبل از اوراکل 21cء، BasicFile LOBها هم مزیتی را نسبت به SecureFile داشتند که عملیات shrink به صورت انلاین برای این نوع از LOBها(BasicFile) قابل انجام بود در صورتی که برای آزاد کردن فضای استفاده نشده SecureFile، به ناچار باید LOB را بازسازی کرد(با روشهایی چون alter table move و expdp/impdp و … که همه این روشها نیاز به downtime نسبتا زیاد دارند).
در نسخه 21c، به عنوان یک قابلیت جدید، اوراکل به صورت خودکار عملیات shrink این دسته از LOBها(SecureFile) را بر اساس توصیه های Oracle Segment Advisor انجام می دهد و البته DBA هم می تواند به صورت دستی SecureFile LOBها را shrink کند.
با دنبال کردن سناریوی زیر، بیشتر با این قابلیت آشنا خواهیم شد.
***در ابتدا جدولی که حاوی ستونی با فرمت CLOB SecureFile هست را ایجاد می کنیم:
SQL> create table tbl_Secure_Lob(id number,description clob) LOB(description) STORE AS SECUREFILE;
Table created
ده هزار رکورد را در این جدول درج می کنیم:
SQL> begin
2 for i in 1..10000 loop
3 insert into tbl_Secure_Lob values(i,rpad(‘test ‘,4000,’test, ‘));
4 end loop;
5 commit;
6 end;
7 /
حجم جدول و LOB را بررسی می کنیم:
SQL> select bytes/1024/1024 SIZE_MB,blocks from user_segments where segment_name = (select segment_name from user_lobs v where v.table_name=’TBL_SECURE_LOB’);
SIZE_MB BLOCKS
———- ———-
88.3125 11304
SQL> select bytes/1024/1024 SIZE_MB from user_segments where segment_name =’TBL_SECURE_LOB’;
SIZE_MB
———-
0.625
پنج هزار رکوردی که ابتدا در این جدول درج شده اند را حذف می کنیم:
SQL> delete TBL_SECURE_LOB where id<=5000;
5000 rows deleted
Executed in 0.426 seconds
SQL>commit;
پرس و جوی زیر نشان می دهد که حذف رکوردها اثری در حجم مصرفی جدول و LOB نداشته است و فضای استفاده نشده، آزاد نمی شود:
SQL> select bytes/1024/1024 SIZE_MB,blocks from user_segments where segment_name = (select segment_name from user_lobs v where v.table_name=’TBL_SECURE_LOB’);
SIZE_MB BLOCKS
———- ———-
88.3125 11304
برای آزاد کردن فضای استفاده نشده SecureFile می توان از دستور زیر استفاده کرد:
SQL> ALTER TABLE TBL_SECURE_LOB MODIFY LOB(description) (SHRINK SPACE);
Table altered
Executed in 24.897 seconds
با اجرای این دستور خواهیم دید که فضای LOB تقریبا به نصف رسیده است:
SQL> select bytes/1024/1024 SIZE_MB,blocks from user_segments where segment_name = (select segment_name from user_lobs v where v.table_name=’TBL_SECURE_LOB’);
SIZE_MB BLOCKS
———- ———-
49.25 6304
جزییات این عملیات از طریق ویوی v$securefile_shrink قابل مشاهده است:
SQL> SELECT c.lob_objd,c.shrink_status,c.blocks_moved,c.blocks_freed FROM v$securefile_shrink c;
LOB_OBJD SHRINK_STATUS BLOCKS_MOVED BLOCKS_FREED
———- ————– ———— ————
76321 COMPLETE 1082 1082
البته به عنوان قابلیتی دیگر می توان همزمان با shrink کردن فضای جدول tbl_Secure_Lob، با استفاده از عبارت cascade، تمامی SecureFile LOBها را هم shrink کرد:
SQL> ALTER TABLE tbl_Secure_Lob SHRINK SPACE CASCADE;
ORA-10636: ROW MOVEMENT is not enabled
SQL> alter TABLE tbl_Secure_Lob enable row movement;
Table altered
SQL> ALTER TABLE tbl_Secure_Lob SHRINK SPACE CASCADE;
Table altered
Executed in 19.291 seconds