Oracleを運用中にシュリンクと同等の効果を得る方法

今日はOracleデータベースにおけるシュリンクの代替手順について紹介します。

急にデータベースの遅延が発生して、何が原因か調べたら、データベースのデータ量が増えたことにより、実行計画が変わっていてデータ削除とSHRINKをしなくていけなくなることがあります。

そこで、データの削除を夜間の時間などをみつけて、お客様と調整して、実施してみたものの、
削除した空き領域を有効活用できるようにシュリンクをしたいけど、時間が読めないなどで困った!!なんてことありませんか?

今回、データ削除後のシュリンク対応の代替方法についてご紹介します。
各実行については、当記事をうのみにせずに、Oracleサポートなども活用してご判断をお願いします。

一般的なシュリンク手順について

データの削除をするためにある程度まとまった時間がとれる場合、”データ削除してから、シュリンクする”で基本的には対応可能できますよね。

データ削除するためにも、各テーブルの関係性を意識することは当然です。
ここでは、注意書きだけにしておきますが、あるデータだけ削除したら、整合性くずれて、夜間処理が異常終了してしまったとか、契約のない保守作業のために夜中に電話鳴らないようにご注意ください。

では、ここからデータ削除+シュリンクの手順となります。
大きく以下の手順を実施します。

こちらで紹介するSQL構文
データの削除
delete テーブル名 where 条件
テーブルシュリンク
ALTER TABLE テーブル名 ENABLE ROW MOVEMENT; — 行移動を有効化
ALTER TABLE テーブル名 SHRINK SPACE; — テーブル再編成
統計情報取得
ANALYZE TABLE テーブル名 COMPUTE STATISTICS; –全件を対象とする場合
ANALYZE TABLE テーブル名 ESTIMATE STATISTICS SAMPLE 10 PERCENT; –サンプル範囲をテーブルの10%とする場合

①データの削除

ここは当たり前ですが、普通に削除構文で大丈夫。
delete テーブル名 where 条件

なるべくindexが適用されている条件を指定して消します。
適用されてない条件を指定すると、時間がかかるので注意しましょう。
※業務的に紐づいたテーブルは削除時は条件注意です。

例えば、鏡と明細としているテーブルなどで、”鑑だけ削除”、”明細だけ削除”とならないように整合性をとることを忘れないようにしましょう。

②テーブルシュリンク

その後、テーブルのシュリンク作業に入ります。
シュリンクをしないと使用した領域の解放とデータの整列がされないため、せっかくデータの削除を行っても、削除の効果を充分に得ることができません。

ただ、ここで良く問題が発生します。
シュリンク処理ですが、どのくらい時間がかかるのか、どのくらい処理が進んだのかという点で情報をあまり得ることができません。

お客様の運用がほぼ24時間運用をしているシステムの場合、業務停止を伴うこととなり、作業者からすると、時間との戦いとなります。
ただ、こちらもSQLを実行するだけで解決するため、あまり深く考えずに処理を進めることは可能です。

ちなみに、シュリンクの構文は、
ALTER TABLE テーブル名 ENABLE ROW MOVEMENT; — 行移動を有効化
ALTER TABLE テーブル名 SHRINK SPACE; — テーブル再編成

一つ注意があるとすれば、テーブル更新中でも実行しても大丈夫という記載があることがありますが、途中からテーブルロックにかわることがあります。

④統計情報再取得

テーブル再編成後は、統計情報をとりましょう。
統計情報の取得を行わなければ、INDEXの効率が落ちたりするため、データの分布が大きくかわるようなデータ操作をしたときは、
統計情報を取得することをオススメします。

統計情報を取得するための構文は以下の通りです。

全件対象とする場合
ANALYZE TABLE テーブル名 COMPUTE STATISTICS;

サンプル範囲をテーブルの10%とする場合
ANALYZE TABLE テーブル名 ESTIMATE STATISTICS SAMPLE 10 PERCENT;

シュリンクの代替案となる手順について

シュリンクでデータ削除を行う場合、シュリンク実行時にどのくらい時間を要するのかわからないという課題があります。
そこで、別の方法がないかを検討した方法について紹介します。

以下が大まかな手順となります。
実施することは、データ削除→テーブル領域移動→インデックスのリビルドとなります。

こちらで紹介するSQL構文
同一のテーブル領域へテーブルを作り直す
ALTER TABLE テーブル名 MOVE;  — 通常テーブルの場合
ALTER TABLE テーブル名 MOVE PARTITION パーティション名; –パーティションテーブルの場合
INDEXの再構成構文
ALTER INDEX インデックス名 REBUILD ONLINE; — 通常テーブルの場合
ALTER INDEX インデックス名 REBUILD ONLINE パーティション名; –パーティションテーブルの場合

①データ削除

こちらについては、シュリンク案と同様の注意事項と同様の手順で実施してかまいません。

②テーブル領域移動

Oracleでテーブルの管理を行っている場合、テーブルの領域が指定されています。
今回は、データの削除後に別のテーブル領域を使って、同じテーブルに移動することで、
空き容量の解放およびデータの整理をするというやり方になります。
まっさらなテーブルにimportをしたときと同じ状態となります。

同一のテーブル領域へテーブルを作り直す
ALTER TABLE テーブル名 MOVE;  — 通常テーブルの場合
ALTER TABLE テーブル名 MOVE PARTITION パーティション名; –パーティションテーブルの場合

③インデックスのリビルド

テーブルの領域移動を行うと、Oracle内部で管理されているROWIDがすべて新しい値となります。
そのため、テーブル領域移動をしたテーブルのINDEXはすべて無効化された状態となります。
テーブルのINDEXが無効化された状態で処理を動かした場合、INDEXが利用できない状態であることを通知するORACLEエラーが発生します。

上記のことから、テーブル領域移動を行った後に、テーブルのINDEXのリビルドを行います。

INDEXの再構成構文

ALTER INDEX インデックス名 REBUILD ONLINE; — 通常テーブルの場合
ALTER INDEX インデックス名 REBUILD ONLINE パーティション名; –パーティションテーブルの場合

※パーティションテーブルを利用しているかたは、INDEXがローカル索引か、グローバル索引になっています。
グローバル索引の場合は、通常テーブルの場合と同じ再構成構文を利用しましょう。

まとめ

データベースの運用を行っている場合、必ずデータの蓄積による処理遅延が発生します。
今回その時の対処として、考えられる2つ方法について紹介しました。
シュリンクが一般的な方法ではありますが、大きなデータベースでは処理時間がよめないなど不確定要素が多いです。

テーブル領域移動+リビルドは一般的な方法ではありませんが、構文としては難しい処理をするわけではないため、
テーブルの容量などからある程度の時間を想定することができますよ。

最新情報をチェックしよう!