web-dev-qa-db-ja.com

テーブルコンテンツ(行)を削除するテーブルスペースの空き領域

理論的な質問があります。先週、1つのデータベースでこのエラーが見つかりました。一部のWSデータを保存しようとしたときに、アプリからエラーが発生しました。

ORA-01691: unable to extend lob segment RS2.SYS_LOB0000501482C00010$$ by 128 in tablespace RS2QDDA1

Sysdba権限を持っているdbaがない場合は、次のように議論します。

  • このテーブルスペースに格納されているいくつかのタブラのデータを削除すると、テーブルスペースに空きスペースができますか?そして、アプリケーションで動作するように戻すことができます。

一部のテーブルから古い行を削除するようにパージバッチを構成しているため、これは問題になりますが、実行時に失敗し、ORA-01691: unable to extend lob segment RS2.SYS_LOB0000501482C00010$$ by 128 in tablespace RS2QDDA1の前に定義された同じエラーメッセージがスローされます。

1

このオブジェクトに含まれるデータの nature を理解しないと、しっかりしたアドバイスを提供することは困難です。

これが通常のテーブルであれば、はい。そこから行を削除し、それによってテーブルスペース内のスペースを解放します。
deleteステートメントの結果、 more データがこのオブジェクトに書き込まれるという事実から、これは標準ではないと思います。おそらく、削除を含むすべてを記録するある種の「監査」機能です。つまり、 only オプションは、テーブルスペースにデータファイルを追加するか、基礎となるディスク領域を拡張することで、テーブルスペースに作業領域を与えることです。

あなたのDBAなしでなしのどちらかの操作を実行することを考えていますか?

私の推奨事項:しないでください。

Oracleデータベースについては、私たちが望んでいるほど簡単ではありません。そのため、自分が何をしているかを理解している(そして、問題が発生したときに何をすべきかを知っている)誰かが必要です。

さらに、あなたはできるにさえすべきではありません!

DBAがこの操作 attempt に対しても十分な権限を与えている場合、データベースセキュリティに関する概念がほとんどないかまったくない(または、寛大に言うと、非常に高い over -開発された信頼感)。

2
Phill W.

注意が必要なのは、テーブル(インデックス、マテリアライズドビューなど)に割り当てられる領域が増えるほど[〜#〜] insert [〜#〜]データがこれらのテーブルに割り当てられることです。 [〜#〜] delete [〜#〜]の場合、そのスペースは解放されますこれらの割り当て内。つまり、新しい行を同じテーブルに挿入すると、スペースが再利用されます。しかし、それは他のオブジェクトで再利用されない(他のテーブルなど)になります。

同じことがインデックスにも当てはまります。さらに、定期的なバランシングにより、インデックスは常に大きくなります(ノードの分割とノードの作成が増える)。インデックスは、削除のために縮小することもありません。

テーブルから行を削除してスペースを解放し、他のオブジェクト(テーブル、インデックス)がそのスペースを再利用できるようにしたい場合は、うまくいきません。唯一の例外は、テーブルを完全に空にする場合です。この場合、以下を使用します。

TRUNCATE TABLE my_big_table;

の代わりに

DELETE FROM my_big_table;
COMMIT;

注意:ROLLBACKTRUNCATE操作はできません!したがって、適切なデータベースとスキーマで適切なテーブルを選択してください。

TRUNCATEは、そのテーブルに割り当てられたすべてのスペースを解放し、誰でも利用できるようにする効果があります。 DELETEはブロックから行をワイプするだけで、そのスペースのみを同じテーブルで使用できるようにします。

テーブルのデータを保持したい場合は、不要になった行を削除した後、残りの行から新しいテーブルを作成し、元のテーブルを削除して、新しいテーブルの名前を元の名前に変更し、すべての制約とインデックスを追加します。 。これにより、古いテーブルで使用されていたスペースが他のテーブルまたはインデックスで使用できるようになります。

これにより、ファイルシステムで使用可能なスペースが作成されることはありません。テーブルスペースが同じスペースを占有することを意味します。そのレベルでスペースを利用できるようにする必要がある場合は、そのテーブルスペースに対応するデータファイルを縮小することで実現できます。

ALTER DATABASE DATAFILE 'your file name' RESIZE n GB;

ただし、最後に未使用のブロックを削除することで、つまりhigh Watermarkまでファイルを縮小できます。縮小できないようにするには、データファイルの最後に1つのブロックを使用するだけで1つの小さなテーブルを作成するだけで十分です。これを使用して、データファイルをどれだけ縮小できるかを確認できます。

-- Check possible shrinkage
select file_name, hwm, blocks total_blocks, blocks-hwm+1 shrinkage_possible
from dba_data_files a,
     ( select file_id, max(block_id+blocks) hwm
         from dba_extents
        group by file_id ) b
where a.file_id = b.file_id;

Phillが説明したように、通常のユーザーとしてこれらのことを行うことは許可されていないことに注意してください。それらを実行できるのはDBAだけです。したがって、スペースの問題については、DBAにアプローチすることが最善です。

1
Albert Godfrind