از پایگاه داده Oracle 23ai به بعد، میتوانیم از بسته DBMS_SPACE برای کوچک کردن یک bigfile tablespace برای بازیابی فضای بلااستفاده استفاده کنیم.
برای اجرای برخی از تست ها به یک tablespace نیاز داریم. از نسخه ۲۳AI فایل ها در tablespace ها از به صورت پیش فرض از نوع BIgfile هستند، بنابراین نیازی به تعیین صریح آن نداریم.
onn sys/SysPassword1@//localhost:1521/freepdb1 as sysdba
— Create a tablespace and user for the test.
drop user if exists reclaim_user cascade;
drop tablespace if exists reclaim_ts including contents and datafiles;
create tablespace reclaim_ts datafile size 10m autoextend on next 1m;
create user reclaim_user identified by reclaim_user default tablespace reclaim_ts quota unlimited on reclaim_ts;
grant create session, create table to reclaim_user;
grant select_catalog_role to reclaim_user;
— Create and populate two tables in the test schema.
conn reclaim_user/reclaim_user@//localhost:1521/freepdb1
create table t1 (
id number,
col1 varchar2(4000),
col2 varchar2(4000),
constraint t1_pk primary key (id)
);
create table t2 (
id number,
col1 varchar2(4000),
col2 varchar2(4000),
constraint t2_pk primary key (id)
);
insert /*+append*/ into t1
select rownum, rpad(‘x’, 4000, ‘x’), rpad(‘x’, 4000, ‘x’)
from dual
connect by level <= 100000;
commit;
insert /*+append*/ into t2
select rownum, rpad(‘x’, 4000, ‘x’), rpad(‘x’, 4000, ‘x’)
from dual
connect by level <= 100000;
commit;
exec dbms_stats.gather_table_stats(null, ‘t1’);
exec dbms_stats.gather_table_stats(null, ‘t2’);
اندازه فایل داده مرتبط با tablespace و جداول را بررسی می کنیم.
select tablespace_name, blocks, bytes/1024/1024 as size_mb
from dba_data_files
where tablespace_name = ‘RECLAIM_TS’;
TABLESPACE_NAME BLOCKS SIZE_MB
—————————— ———- ———-
RECLAIM_TS ۴۲۷۵۲۰ ۳۳۴۰
SQL>
column table_name format a10
select table_name, blocks, (blocks*8)/1024 as size_mb
from user_tables
where table_name in (‘T1’, ‘T2’)
order by 1;
TABLE_NAME BLOCKS SIZE_MB
———- ———- ———-
T1 ۲۰۰۶۹۶ ۱۵۶۷٫۹۳۷۵
T2 ۲۰۰۶۹۴ ۱۵۶۷٫۹۲۱۸۸
SQL>
ما جدول اول را Truncate می کنیم و قبل از شروع segment های جدول، یک gap در فایل داده باقی می گذاریم.
truncate table t1;
exec dbms_stats.gather_table_stats(null, ‘t1’);
جهت دریافت خدمات مشاوره، آموزش و نگهداری پایگاه داده اوراکل با ما در ارتباط باشد
ما یک تجزیه و تحلیل انجام می دهیم تا ببینیم با انجام یک Shrink چقدر فضای ذخیره می کنیم. ما رویه SHRINK_SPACE را در بسته DBMS_SPACE فراخوانی میکنیم که نام tablespace ومقدار کوچک شدن TS_MODE_ANALYZE ارسال میشود.
conn sys/SysPassword1@//localhost:1521/freepdb1 as sysdba
set serveroutput on
execute dbms_space.shrink_tablespace(‘RECLAIM_TS’, shrink_mode => dbms_space.ts_mode_analyze);
——————-ANALYZE RESULT——————-
Total Movable Objects: 2
Total Movable Size(GB): 1.56
Original Datafile Size(GB): 3.39
Suggested Target Size(GB): 3.19
Process Time: +00 00:00:00.053777
PL/SQL procedure successfully completed.
SQL>
فکر نمیکند بتوانیم فضای زیادی را ذخیره کنیم، که مشکوک به نظر میرسد زیرا یک جدول را truncate کردهایم، که تقریباً نیمی از فضای فایل داده را اشغال میکند.
ما با فراخوانی رویه SHRINK_SPACE با نام tablespace یک عملیات Shrink را اجرا می کنیم.
set serveroutput on
execute dbms_space.shrink_tablespace(‘RECLAIM_TS’);
——————-SHRINK RESULT——————-
Total Moved Objects: 2
Total Moved Size(GB): 1.56
Original Datafile Size(GB): 3.26
New Datafile Size(GB): 1.63
Process Time: +00 00:00:30.586722
PL/SQL procedure successfully completed.
SQL>
علیرغم آنچه تجزیه و تحلیل گفت، ما فایل داده مرتبط را به تقریباً نصف اندازه اصلی آن کاهش داده ایم.
دستور قبلی معادل فراخوانی رویه با حالت کوچک کردن TS_MODE_SHRINK و اندازه هدف TS_TARGET_MAX_SHRINK است.
در اینجا برخی از اطلاعات اضافی در مورد کوچک کردن جدول های فایل بزرگ وجود دارد.