セグメントの縮小とHMWの引き下げで表領域にスペースを作る

覚えるべきキーワード
・セグメント
・データブロック
・未使用領域
・HMW
・断片化
・セグメントアドバイザ
・自動セグメント領域管理
・セグメントアドバイザ
・SHRINK SPACE句

DML操作を続けると、時間経過に伴い、セグメントは使用済データブロックと空きデータブロックが混在するようになります。いわゆる、データの断片化(フラグメンテーション)です。通常、INSERT実行後のデータはデータブロックに順序良く格納されます。そして、ブロックサイズを越えそうになると、新しいデータブロックに移動してINSERTを続けます。

※1個目に少し未領域(白い個所)があるが、これは入れようとしたデータが未領域のサイズより大きかったため、データを入れずに2個目のデータブロックに言移動したことを意味している。

データブロックの後戻りはしないので、例えば1個目のデータブロックが満杯になれば、2個目、3個目と進みますが、再度1個目に戻るということはありません。今までデータを入れたことがあるデータブロックの最高位置をHMWと呼びますが、この例だと3個目のデータブロックがHMWになります。

データ断片化の理由

このデータ断片化が起こる直接的な理由はUPDATEとDELETEにあります。一度データブロックに入れたデータをDELETEすれば、データサイズは0になります。また、データを小さい値にUPDATEすればデータサイズは小さくなります。このようにUPDATEやDELETE実行を繰り返すと、今までぎっしり詰まっていたデータブロックに空きスペースが発生し始めます。空いたスペースに戻る仕組みがOracleにあれば良いのですが、現状はそのような仕組みになっていません。そのためUPDATEやDELETEを頻繁に繰り返す表領域は空きスペースが多い表領域となります。これはスペースをムダ使いしており、とてももったいないです。


このような場合、セグメント縮小を実行すれば、データを前方部分にギュッと集められるので、空きスペースを極力なくしてくれます。

セグメント縮小の判断はセグメントアドバイザ、もしくは自分で行う

セグメント縮小が必要か否かの判断はセグメントアドバイザによって行う、もしくはSQLを実行して、取得した数値をもとに自力で判断する2通りがあります。実行タイミングが難しいと思うので、個人的にはセグメントアドバイザに判断してもらった方が良いと思います。

セグメントアドバイザを利用する方法

セグメントアドバイザを利用すると、スペースを無駄遣いしているオブジェクト(表や索引)を確認できます。データベースが自動でデータ取得してくれるので、簡単かつ正確です。
ただし、セグメントアドバイザを使うには条件があります。それは、自動セグメント領域管理を備えたローカル管理表領域のセグメントでなければならないということです。
自動セグメント領域管理になってなければ、segment_space_managementをautoにしてください。セグメントアドバイザは定期的に自動実行され、セグメントを分析してくれます。セグメントアドバイザ分析後にセグメントアドバイザ推奨と表示されたら、セグメント縮小が必要な合図です。

自分で判断する方法

自分で判断する場合はセグメント状況の情報を取得します。

データ自体はこれで取得できるはずですが、断片化の判断はご設定されている表領域サイズ次第なので、ここでは一概に具体的な判断基準を明言できません。
このようなことからも、セグメントアドバイザを使って判断した方が良いと思います。

SHRINK SPACE句でセグメント縮小

セグメントの縮小を行うには前提条件があります。それは自動セグメント領域管理であること。です。まずは自動セグメント領域管理になっているかチェックします。

①自動セグメント領域管理のチェック
dept_all表領域のdeptテーブルがその対象テーブルだとします。

これでsegment_space_managementがautoになっていれば、OKです。
(セグメントアドバイザが使えるのであれば、自動セグメント領域管理になっています)
②行管理を有効化する
セグメント縮小を実行すると、格納されているデータのROWIDが変更する可能性があるので、行の変更を有効にしておきます。

まずは有効化の確認。

enableであることを確認します。もし、disableなら、以下のSQLで行管理を有効化します。

③HMW以下の領域圧縮とHMWの位置引下げ・未使用領域の開放
いよいよセグメントを縮小します。順序は、HMW以下の領域圧縮後にHMWの位置引下げ・未使用領域の開放の二段階ですが、これは1つのSQLで実行できます。SHRINK SPACE句を使います。

※表だけでなく、索引も対象にする場合はALTER TABLE dept SHRINK SPACE CASCADE;と書きます。

これでHMW以下の領域圧縮とHMWの位置引下げ・未使用領域の開放ができました。
セグメントが圧縮され、表領域は余裕ができるはずです。

セグメント管理はDBAによってとても重要な業務です。場合によってはデータを壊しかねません。一方でセグメント管理の経験があるシステムエンジニア(SE)は現場でも重宝されます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です