溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

分區(qū)表或分區(qū)索引的BLOCK_ID很大導致DATAFILE無法RESIZE的解決方法

發(fā)布時間:2020-06-05 07:56:41 來源:網(wǎng)絡 閱讀:684 作者:平山 欄目:關系型數(shù)據(jù)庫

一 前言

最近發(fā)現(xiàn)磁盤空間有3T的性能機器出現(xiàn)了磁盤空間不足的現(xiàn)象,該機器主要部署ORACLE數(shù)據(jù)庫,所以,猜測很可能是表空間數(shù)據(jù)文件變更導致的。接下來,就需要一步步的排查問題了,最終確認是ORACLE BLOCK_ID惹的禍。


二 定位磁盤空間占用情況

首先需要確定是哪些文件占用空間,使用du -sh * ,果不其然,有個表空間增加了20個數(shù)據(jù)文件,而且每個數(shù)據(jù)文件設置30G,Word天,誰這么狠,居然找不到元兇,好吧,那我就任意處置了,不能影響后面的性能測試。


三 刪除數(shù)據(jù)文件

既然發(fā)現(xiàn)這么多數(shù)據(jù)文件,當然想直接drop掉,于是,不以為然的執(zhí)行alter tablespace TEST drop datafile '/oradata/dat20.dbf';先把最后一個干掉,結果執(zhí)行報錯“ORA-03262: THE FILE IS NON-EMPTY”,呵,居然有數(shù)據(jù),直接刪不掉。于是,就想查詢這個表空間的表,把數(shù)據(jù)TRUNCATE掉,但又考慮到該表空間TABLE就有上千張,而且不能確定哪張表可刪,不能太魯莽,事實證明,真和數(shù)據(jù)無關。


四 退而求其次-RESIZE 數(shù)據(jù)文件釋放空間

既然不能drop 數(shù)據(jù)文件,那就resize它,就不信拿不回空間。于是,先查下可以釋放多少空間出來,先執(zhí)行如下命令:

select d.file_name,d.file_id,d.bytes/1024/1024 as d_byte,sum(f.bytes/1024/1024) as free_byte 

from dba_data_files d,dba_free_space f 

where d.file_id=f.file_id and d.file_id=67 

group by d.file_name,d.file_id,d.bytes/1024/1024;

輸出顯示67號數(shù)據(jù)文件可用空間29.9G,看到這里,心里暗罵,是誰這么不靠譜,亂加亂設數(shù)據(jù)文件。不過,都是小問題,resize成1G就行了。于是,又興沖沖的趕緊執(zhí)行ALTER DATABASE DATAFILE '/oradata/hisdat20.dbf' RESIZE 1G; 居然又報錯了,

“ORA-03297:file contains used data beyond requested RESIZE value”,看到這個報錯,開始意識到可能問題沒有這么簡單。


五 shrink space降低高水位

既然實際數(shù)據(jù)很少,resize卻不能成功,就表明是某些數(shù)據(jù)塊位于數(shù)據(jù)文件的末端,那就先降降HWM高水位,對表空間的表進行操作,主要命令如下:

alter table test_table enable row movement;

alter table test_table shrink space; ---降低高水位,釋放空間

alter table test_table disable row movement;


當然,這樣一個個的執(zhí)行不顯示,需要批量執(zhí)行,命令如下:

SELECT DISTINCT 'alter table ' || segment_name || ' enable row movement;'||

                'alter table ' || segment_name || ' shrink space;'||

                'alter table ' || segment_name || ' disable row movement;'

 FROM dba_extents

 WHERE tablespace_name = 'TEST'

 AND segment_type = 'TABLE'


降低HWM后,再次執(zhí)行RESIZE操作,報錯依舊,好吧,既然這樣都沒搞定,需要認真研究下了。


六 找到真兇和解決方法

通過上述嘗試,發(fā)現(xiàn)數(shù)據(jù)文件可用空間充足,但對ORACLE而言,數(shù)據(jù)文件使用了30G,所以RESIZE到1G會報錯失敗,盡快進行了降高水位或TRUNCATE操作都無濟于事。于是,排查和解決思路是這樣的:

1)查詢數(shù)據(jù)文件的最大BLOCK_ID

select max(block_id) from dba_extents where file_id=67;


2)確定該BLOCK_ID與哪個表或索引有關

SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, TABLESPACE_NAME, A.PARTITION_NAME FROM DBA_EXTENTS A WHERE FILE_ID = 67 AND block_id = 3839929;

查詢后,發(fā)現(xiàn)最大的BLOCK_ID都是與分區(qū)表或分區(qū)索引有關的。


3)針對最大BLOCK_ID出現(xiàn)在分區(qū)表的處理方法

對分區(qū)表出現(xiàn)最大BLOCK_ID的情況,采用先降分區(qū)表高水位,然后MOVE表空間,命令如下:

alter table TEST_TABLE MODIFY PARTITION P101101 shrink space;---注意降低高水位并不能降低數(shù)據(jù)文件中block_id大小

alter table TEST_TABLE move partition P101101 tablespace TEST;---move操作數(shù)據(jù)移動表空間最前面的空閑block,注意需要重建索引


4)針對最大BLOCK_ID出現(xiàn)在索引分區(qū)的處理方法

對索引分區(qū)出現(xiàn)最大BLOCK_ID的情況,重建分區(qū)索引即可,命令如下:

ALTER INDEX IDX_TEST_TABLE REBUILD PARTITION P201201


5)處理完后,再次執(zhí)行RESIZE操作,數(shù)據(jù)文件大小修改成功。


最后,因為同個文件號上可能出現(xiàn)多個分區(qū)表,分區(qū)索引需要處理的情況,建議像第五步寫成批量執(zhí)行,提高效率。


關于shrink space降低高水位,可以參考博文Oracle delete操作隱藏著你可能不知道的秘密


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI