刪除表內容的表空間可用空間(行)
我有一個理論問題,上週我們在一個數據庫中發現了這個錯誤。我們的應用程序在嘗試保存一些 WS 數據時給出了錯誤。
ORA-01691: unable to extend lob segment RS2.SYS_LOB0000501482C00010$$ by 128 in tablespace RS2QDDA1
在沒有擁有 de sysdba 權限的 dba 的情況下,我們進行了討論:
- **如果我們刪除儲存在這個表空間中的一些表的數據,表空間會有空閒空間嗎?**並且可以重新為該應用程序工作。
我們質疑這一點,因為我們配置了一個清除批處理以從某些表中刪除舊行,但它在執行時間上失敗並拋出之前定義的相同錯誤消息
ORA-01691: unable to extend lob segment RS2.SYS_LOB0000501482C00010$$ by 128 in tablespace RS2QDDA1
如果不了解此對象包含的數據的性質,就很難提供可靠的建議。
如果這是一張普通的桌子,那麼是的;您將從其中刪除行,從而釋放表空間中的空間。刪除語句導致更多
數據寫入該對象 的事實讓我認為它是非標準的;也許是某種記錄所有內容的“審計”功能 - 包括刪除。這意味著您唯一的選擇是通過向表空間添加更多數據文件或擴展底層磁碟空間來為表空間提供更多空間。考慮在沒有DBA 的情況下執行任一操作?
我的建議:不要。
Oracle 數據庫很少像我們希望的那樣簡單明了,因此您需要知道自己在做什麼(並且知道出現問題時該怎麼做)的人。
此外,你甚至不應該能夠!
如果您的 DBA 已授予您足夠的權限甚至可以嘗試此操作,那麼他們需要進行頭腦檢查,對數據庫安全性知之甚少或根本沒有概念(或者,最慷慨的是,高度過度發展的信任感)。
需要注意的一點是:當您將數據插入到這些表中時,表(也包括索引、物化視圖……)會被分配更多空間。當您刪除時,該空間僅在這些分配內被釋放。這意味著當您將新行插入同一個表時,該空間將被重用。但它不會被其他對象(例如其他表)重用。
索引也是如此:此外,索引總是由於定期平衡而增長(導致節點分裂和更多節點創建)。索引也永遠不會因刪除而縮小。
如果您想通過從表中刪除行來釋放空間,那麼其他對象(表、索引)可以重用該空間……好吧,您不能。唯一的例外是如果您想完全清空一個表。在這種情況下,請使用:
TRUNCATE TABLE my_big_table;
代替
DELETE FROM my_big_table; COMMIT;
注意:你不能
ROLLBACK
手術TRUNCATE
!因此,請確保在正確的數據庫和架構中選擇正確的表!
TRUNCATE
具有釋放分配給該表的所有空間的效果,使其可供所有人使用。DELETE
僅擦除塊上的行,僅使該空間可用於同一張表。如果要保留表中的數據,則在刪除不再需要的行後,從剩餘行創建新表,刪除原始表,將新表重命名為原始名稱並添加所有約束和索引. 這將使舊表使用的空間可用於其他表或索引。
這不會在文件系統上騰出可用空間。這意味著您的表空間仍將佔用相同的空間。如果您需要在該級別提供可用空間,您可以通過縮小與該表空間對應的數據文件來實現:
ALTER DATABASE DATAFILE 'your file name' RESIZE n GB;
然而,這只允許您通過在末尾刪除未使用的塊來縮小文件,即降低到high watermark。一張小表在數據文件的末尾只使用一個塊就足夠了,使其不可收縮。您可以使用以下方法了解可以縮小數據文件的程度:
-- 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 聯繫您的空間問題。