
目次
はじめに
こんにちは。Oracle Databaseの検証チームです。
今回は、Oracle Database 23aiの新機能である「BIGFILE表領域の縮小機能」をご紹介いたします。
過去のOracle Database 23aiの記事はこちら!
今回の執筆者はOracle Cloud Infrastructure Foundations 2022 Certified Associate 、Oracle Cloud Data Management 2022 Foundations Certified Associateを取得しました!に登場した社員です。

BIGFILE表領域の縮小機能について
従来の表領域縮小について
表領域のサイズを縮小させる際の従来の方法としては、ALTER DATABASE DATAFILE RESIZE文を使用します。
例えば、BIGFILE表領域のデータファイル「+DATA/CDB23_TKY/DATAFILE/test_tbs.dbf」がサイズ200MBであったとして、
下記のコマンドを実行することで100MBにデータファイルを縮小することができます。
SQL> ALTER DATABASE DATAFILE '+DATA/CDB23_TKY/DATAFILE/test_tbs.dbf' resize 100M;
Database altered.
しかし、たとえ表領域の使用量が100MB未満であっても、
データがデータファイルの100MBの位置以降に格納されている場合は上記のコマンドで縮小できず、下記のようなエラーとなります。
SQL> ALTER DATABASE DATAFILE '+DATA/CDB23_TKY/DATAFILE/test_tbs.dbf' resize 100M;
ALTER DATABASE DATAFILE '+DATA/CDB23_TKY/DATAFILE/test_tbs.dbf' resize 100M
*
ERROR at line 1:
ORA-03297: File contains used data beyond requested RESIZE value.
Help: https://docs.oracle.com/error-help/db/ora-03297/
その際は100MB以降に格納されているセグメントをEXPORT/IMPORTし、
テーブルセグメントやインデックスセグメントをMOVE、REBUILDするなどして、
データファイルの100MB以前の領域にセグメントを移動させるようなメンテナンス作業を実施したうえで、
ALTER DATABASE DATAFILE RESIZE文を実行する必要がありました。
Oracle Database 23aiの新機能によるBIGFILE表領域縮小について
Oracle Database 23aiの新機能である「BIGFILE表領域の縮小機能」を使用することで、
前述のようなメンテナンス作業を実施せずとも、BIGFILE表領域の縮小を実行することができます。
今回は実際にこの機能を検証してみました。
BIGFILE表領域の縮小機能の検証
従来の方法での表領域の縮小を試す
現在、サイズ200MBのBIGFILE表領域「TEST_TBS」があり、
そのデータファイルは「+DATA/CDB23_TKY/DATAFILE/test_tbs.dbf」で、
表領域の使用量は下記のように8MB程度の状況です。
SQL> SELECT
2 A.TABLESPACE_NAME "TABLESPACE"
3 , ROUND(SUM(BYTES) / 1024 / 1024, 0) "SIZE(MB)"
4 , ROUND(SUM(BYTES - nvl(c1,0)) / 1024 / 1024, 0) "USED(MB)"
5 , ROUND(SUM(nvl(c1,0)) / 1024 / 1024, 0) "FREE(MB)"
6 , ROUND((SUM(BYTES - nvl(c1,0)) / 1024) / (SUM(BYTES) / 1024) * 100, 2) as "USED(%)"
7 FROM
8 DBA_DATA_FILES A ,
9 ( SELECT
10 TABLESPACE_NAME
11 ,FILE_ID
12 ,SUM(BYTES) c1
13 FROM DBA_FREE_SPACE
14 GROUP BY TABLESPACE_NAME, FILE_ID ) B
15 WHERE A.TABLESPACE_NAME = B.TABLESPACE_NAME(+)
16 AND A.TABLESPACE_NAME = 'TEST_TBS'
17 GROUP BY A.TABLESPACE_NAME;
TABLESPACE SIZE(MB) USED(MB) FREE(MB) USED(%)
------------------------------ ---------- ---------- ---------- ----------
TEST_TBS 200 8 192 4.03
この表領域のサイズを100MBに縮小するため、
ALTER DATABASE DATAFILE RESIZE文を使用して縮小を試みます。
SQL> ALTER DATABASE DATAFILE '+DATA/CDB23_TKY/DATAFILE/test_tbs.dbf' resize 100M; ALTER DATABASE DATAFILE '+DATA/CDB23_TKY/DATAFILE/test_tbs.dbf' resize 100M * ERROR at line 1: ORA-03297: File contains used data beyond requested RESIZE value. Help: https://docs.oracle.com/error-help/db/ora-03297/
すると上記のようにエラーになりましたので、データファイルに格納されている一番後ろのデータ位置を確認します。
SQL> SELECT round(max(BLOCK_ID + BLOCKS - 1)*8192/1024/1024) "HWM(MB)" 2 FROM DBA_EXTENTS 3 WHERE TABLESPACE_NAME = 'TEST_TBS'; HWM(MB) ---------- 185
これより、100MB以降の位置にデータが格納されていたため、縮小できなかったことがわかりました。
新機能によるBIGFILE表領域縮小を試す
続いて、新機能による表領域の縮小を試みます。
コマンドは以下の通りです。
DBMS_SPACE.SHRINK_TABLESPACE (ts_name, shrink_mode, target_size);
それぞれのパラメータ以下の通りです。
- ts_name:表領域名
- shrink_mode:実行する縮小モード
- target_size:目標の表領域サイズ(バイト数で指定、指定しない場合は縮小可能な限り小さいサイズに縮小)
shrink_modeは
「TS_MODE_SHRINK」を指定することでオンラインでのオブジェクトを移動して縮小します。
「TS_MODE_SHRINK_FORCE」を指定することでオンラインでのオブジェクト移動を試みますが失敗するとオフラインでの移動を試みて縮小します。
「TS_MODE_ANALYZE」を指定すると縮小は実施せずにBIGFILE表領域の分析を実施します。
それでは実際に100MBに縮小を試みます。
SQL> SET SERVEROUTPUT ON SQL> EXECUTE DBMS_SPACE.SHRINK_TABLESPACE('TEST_TBS', DBMS_SPACE.TS_MODE_SHRINK, 104857600); -------------------SHRINK RESULT------------------- Total Moved Objects: 1 Total Moved Size(GB): 0 Original Datafile Size(GB): .2 New Datafile Size(GB): .1 Process Time: +00 00:00:06.327535 PL/SQL procedure successfully completed.
問題なくコマンドが実行できましたので、表領域のサイズを確認します。
SQL> SELECT
2 A.TABLESPACE_NAME "TABLESPACE"
3 , ROUND(SUM(BYTES) / 1024 / 1024, 0) "SIZE(MB)"
4 , ROUND(SUM(BYTES - nvl(c1,0)) / 1024 / 1024, 0) "USED(MB)"
5 , ROUND(SUM(nvl(c1,0)) / 1024 / 1024, 0) "FREE(MB)"
6 , ROUND((SUM(BYTES - nvl(c1,0)) / 1024) / (SUM(BYTES) / 1024) * 100, 2) as "USED(%)"
7 FROM
8 DBA_DATA_FILES A ,
9 ( SELECT
10 TABLESPACE_NAME
11 ,FILE_ID
12 ,SUM(BYTES) c1
13 FROM DBA_FREE_SPACE
14 GROUP BY TABLESPACE_NAME, FILE_ID ) B
15 WHERE A.TABLESPACE_NAME = B.TABLESPACE_NAME(+)
16 AND A.TABLESPACE_NAME = 'TEST_TBS'
17 GROUP BY A.TABLESPACE_NAME;
TABLESPACE SIZE(MB) USED(MB) FREE(MB) USED(%)
------------------------------ ---------- ---------- ---------- ----------
TEST_TBS 100 8 92 8.06
表領域のサイズが100MBに縮小されていることが確認できました。
また、データファイルに格納されている一番後ろのデータ位置を確認したところ、
下記のように12MBまで下がっており、セグメントが移動されていることが確認できました。
SQL> SELECT round(max(BLOCK_ID + BLOCKS - 1)*8192/1024/1024) "HWM(MB)"
2 FROM DBA_EXTENTS
3 WHERE TABLESPACE_NAME = 'TEST_TBS';
HWM(MB)
----------
12
おわりに
今回はOracle Database 23aiの新機能である「BIGFILE表領域の縮小機能」を紹介、検証してみました。
この機能を使用する際は、ぜひ上記を参考に使用していただけますと幸いです。
最後までお読みいただきありがとうございました。
Oracle Databaseに関してお困りごとがあれば、ぜひ当社へご相談ください。

投稿者プロフィール

23ai2025年3月14日【Oracle 23ai 新機能】BIGFILE表領域の縮小機能を使ってみました
Oracle Cloud2025年3月3日OCIで簡単なWebサーバを作ってみた!
Oracle Exadata2025年2月28日Exadata X11Mについて(機器構成)
Oracle2025年1月31日Oracle Enterprise Manager 24aiをインストールしてみました