您好,登錄后才能下訂單哦!
在我管的系統中,數據庫磁盤經常只剩下20G左右,以前是刪除數據庫服務器中的日志,日志做了定時清理之后,發現表空間經常出現表空間不足的情況,每次都是通過擴充表空間來解決問題,但是加了幾次之后,服務器的磁盤不夠用了,就開始清理數據庫中的數據。清理了數據之后,發現表空間實際占用率很小,用不到那么多的磁盤,于是想到把用到的磁盤釋放出來。
在處理的過程中,發現truncate表只能夠減小表空間占用率,并不能釋放磁盤通過請教別人,了解到有下面方法可以釋放磁盤。
方法一:
查看表空間對應的數據文件大小
select FILE_NAME,FILE_ID,TABLESPACE_NAME,BYTES/1024/1024 mb,BLOCKS from dba_data_files where
TABLESPACE_NAME='TFR_DATA';
查看數據文件中數據處在最大位置
select max(block_id) from dba_extents where file_id=9;
計算表空間實際需要多大空間
select 1354880*8/1024 from dual;
設置表空間大小為該值
ALTER DATABASE DATAFILE '/u01/oradata/FOSSDB/datafile/o1_mf_tfr_data_9ymk9p5n_.dbf' RESIZE 10600M;
這種方法在我之前的文章中寫到過。這種方法也是有缺陷的,表空間中實際沒有很多數據,例如只有100M數據,但是這種方法resize的時候,發現只能夠resize到10G左右,并沒有釋放出很大的空間。
方法二:
縮小數據文件尺寸報ORA-03297的處理辦法
ORA-03297: 文件包含在請求的 RESIZE 值以外使用的數據
最近歷史數據庫磁盤空間不足,而有一個表空間有50個G容量,但是實際只占100m的空間,
使用ALTER TABLE table SHRINK SPACE CASCAD后大部分數據文件可以調整,當試圖調整其中一個數據文件尺寸的時候報
RA-03297: file contains used data beyond requested RESIZE value
說明這個文件不能通過降低hwm來釋放空間了。******************************************
數據庫版本:oracle 10.2.1
--找到數據文件對應的文件號*********
SQL>select file#,name from v$datafile where name like '%BASEINFO.dbf';
5 /data/eucpdb/eucpdb/BASEINFO.dbf
找到文件中最大的塊號
SQL>select max(block_id) from dba_extents where file_id=5 ;************************
1213833
--查看數據庫塊大小
SQL>show parameter db_block_size
db_block_size integer 8192
計算一下文件中最大使用塊占用的位置
SQL>select 1213833*8/1024 from dual;
9483.0703125 M
--為了驗證上面做法的準確性,下面做一個試驗
--調整前數據文件大小為10000M
--現在調整數據庫文件為9500M
SQL>ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 9500M
2 /
數據庫已更改
--調整文件為 9400m
SQL>ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 9400M
2 /
SQL> ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 9400M;
ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 9400M
*
第 1 行出現錯誤:
ORA-03297: 文件包含在請求的 RESIZE 值以外使用的數據
--看來了上面的計算是準確的
解決方法
查看表空間中有哪些對象
select * from DBA_SEGMENTS where TABLESPACE_NAME='BASEINFO';
select * from DBA_tables;
select FILE_NAME,FILE_ID,TABLESPACE_NAME,BYTES/1024/1024 mb,BLOCKS from dba_data_files where
TABLESPACE_NAME='TFR_DATA';
查看FILE_ID
SQL> select segment_name,segment_type,tablespace_name,extent_id,bytes,blocks from dba_extents where file_id=5 and block_id='1213833';
SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENT_ID BYTES BLOCKS
------------------------------ ------------------ ------------------------------ ---------- ---------- ----------
REGISTRYINFO TABLE BASEINFO 25 524288 64
SQL>
SQL> ALTER TABLE eucpmanager.REGISTRYINFO SHRINK SPACE CASCADE;
表已更改。
創建一個新的表空間,把block_id比較高的幾個表移出表空間
SQL> CREATE SMALLFILE TABLESPACE "BASEINFO_BAK" DATAFILE '/data/eucpdb/eucpdb/baseinfo_bak.dbf' SIZE 100M LOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO
2 /
表空間已創建。
SQL> alter user eucpmanager quota unlimited on BASEINFO_BAK;
用戶已更改。使得數據庫中表的所屬用戶能夠操作新建的表空間。否則不能把表移到新的表空間中
把block_id比較高的幾個表移動到新的表空間
SELECT DISTINCT SEGMENT_NAME FROM DBA_EXTENTS WHERE TABLESPACE_NAME='BASEINFO' AND FILE_ID=5 and segment_type='TABLE' ;
SQL> SELECT distinct 'alter table '|| SEGMENT_NAME||' move tablespace baseinfo_bak; ' FROM DBA_EXTENTS WHERE TABLESPACE_NAME='BASEINFO' AND FILE_ID=5 and segment_type='TABLE' ;
'ALTERTABLE'||SEGMENT_NAME||'MOVETABLESPACEBASEINFO_BAK;'
----------------------------------------------------------------------------------------------------------------------------
alter table ENTERPRISESERVICEINFO move tablespace baseinfo_bak;
alter table REGISTRYFEEDETAILEX move tablespace baseinfo_bak;
alter table ENTERPRISEROUTE move tablespace baseinfo_bak;
alter table REGISTRYAUTHINFO move tablespace baseinfo_bak;
alter table ENTERPRISEBASEINFO move tablespace baseinfo_bak;
SQL> alter table ENTERPRISESERVICEINFO move tablespace baseinfo_bak;
alter table REGISTRYFEEDETAILEX move tablespace baseinfo_bak;
alter table ENTERPRISEROUTE move tablespace baseinfo_bak;
alter table REGISTRYAUTHINFO move tablespace baseinfo_bak;
alter table ENTERPRISEBASEINFO move tablespace baseinfo_bak;
表已更改。
SQL>
表已更改。
SQL>
表已更改。
SQL>
表已更改。
告警日志中會出現下面的內容,索引需要重建
Thu Apr 24 14:20:21 2008
Some indexes or index [sub]partitions of table EUCPMANAGER.ENTERPRISEBASEINFO have been marked unusable
把下面的執行結果的語句執行所有重建
SELECT distinct 'alter INDEX '|| SEGMENT_NAME||' REBUILD TABLESPACE BASEINFO_BAK; ' FROM DBA_EXTENTS WHERE TABLESPACE_NAME='BASEINFO' AND FILE_ID=5 and segment_type='INDEX' ;
alter INDEX PK_ENTERPRISEBASEINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX PK_REGISTRYINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX PK_REGISTRYFEEDETAILEX REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;
alter INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO_BAK;
再次修改數據文件大小
SQL> select max(block_id) from dba_extents where file_id=5 ;
MAX(BLOCK_ID)
-------------
3209
SQL> ALTER DATABASE DATAFILE '/data/eucpdb/eucpdb/BASEINFO.dbf' RESIZE 1000m;
數據庫已更改。
數據庫文件的空間已經調整成功了
SQL>
--把挪走的表在挪回來
SQL> alter table ENTERPRISESERVICEINFO move tablespace baseinfo;
alter table REGISTRYFEEDETAILEX move tablespace baseinfo;
alter table ENTERPRISEROUTE move tablespace baseinfo;
alter table REGISTRYAUTHINFO move tablespace baseinfo;
alter table ENTERPRISEBASEINFO move tablespace baseinfo;
alter table registryinfo move tablespace baseinfo;
表已更改。
SQL>
表已更改。
--重建索引
SQL>
SQL>
SQL> ALTER INDEX PK_REGISTRYINFO REBUILD TABLESPACE BASEINFO;
ALTER INDEX AK_REGISTRYCODE_REGISTRYINFO REBUILD TABLESPACE BASEINFO;
ALTER INDEX PK_ENTERPRISEBASEINFO REBUILD TABLESPACE BASEINFO;
ALTER INDEX PK_ENTERPRISESERVICEINFO REBUILD TABLESPACE BASEINFO;
ALTER INDEX UNI_REGISTRYAUTHINFO REBUILD TABLESPACE BASEINFO;
ALTER INDEX PK_REGISTRYFEEDETAILEX REBUILD TABLESPACE BASEINFO;
索引已更改。
SQL> SELECT COUNT(*) FROM DBA_SEGMENTS WHERE TABLESPACE_NAME='BASEINFO_BAK' ;
COUNT(*)
----------
0
已經沒有對象在新建的這個表空間了。現在刪除掉
SQL> drop tablespace baseinfo_bak;
表空間已刪除。
但是,在操作的過程中,出現一個非常難搞的問題,
SELECT COUNT(*) FROM DBA_EXTENDS WHERE TABLESPACE_NAME='USERS' ;
COUNT(*)
----------
0
select max(block_id) from dba_extents where file_id=9;
這樣查看也是什么都沒有,但是resize的時候就是報錯,ORA-03297: 文件包含在請求的 RESIZE 值以外使用的數據。
處理方法:
SQL> SELECT COUNT(*) FROM DBA_SEGMENTS WHERE TABLESPACE_NAME='USERS' ;
這里要查看DBA_SEGMENTS,DBA_TABLES,DBA_INDEX這幾個表,DBA_EXTENTS太小了,不全面,查看的時候發現數據雖然刪除了,但是保留在了回收站中,要在PLSQL命令窗口執行如下命令 purge dba_recyclebin.執行后就能夠resize了。
這是絕對百度不到的,問別人也不好想到這里。還是要經驗呀。
這樣查看表空間中的對象為0,
到此調整已經結束了。
其實調整方法有很多,如用imp/exp等
異常處理
查看一個表屬于哪個用戶
select owner from dba_tables where table_name='表名';
SQL> create tablespace wulili datafile '/u01/app/oracle/oradata/dpweb/wulili.dbf' size 1024M autoextend on;
create tablespace wulili datafile '/u01/app/oracle/oradata/dpweb/wulili.dbf' size 1024M autoextend on
ERROR at line 1:
ORA-01119: error in creating database file '/u01/app/oracle/oradata/dpweb/wulili.dbf'
ORA-27040: file create error, unable to create file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 1
solution:give exact path of datafile inplace of $ORACLE_HOME.
like
Create Tablespace CLOUD_DATA datafile '/u01/app/oradata/cloud_data01.dbf' size 1000M
SQL> alter table tb_auto shrink space;
alter table tb_auto shrink space
*
第 1 行出現錯誤:
ORA-10636: ROW MOVEMENT is not enabled
SQL> alter table tb_auto enable row movement;
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。