Resize Datafile时ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
2011-12-29 13:53
465 查看
前些天做测试,为了图方便,在sys用户下建立了一张大表,插入的数据大概几亿条,导致system空间增长了30G左右,后面想删除数据,缩小system空间,因此truncate table,后面又drop table,但是此时只是降低了段的高水位,数据文件还有高水位,因此磁盘空间并没有被释放。
1、先查询可以利用的空闲空间
SQL> select sum(bytes/1024/1024/1024) from dba_free_space where tablespace_name='SYSTEM';
SUM(BYTES/1024/1024/1024)
-------------------------
31.4642944
2、计算datafile可以resize收缩的空间,也就是必须剩余部分其他对象正在使用的空间
select a.file#,a.name,a.bytes/1024/1024 CurrentMB,
ceil(HWM * a.block_size)/1024/1024 ResizeTo,
(a.bytes - HWM * a.block_size)/1024/1024 ReleaseMB,
'alter database datafile '''||a.name||''' resize '||
ceil(HWM * a.block_size/1024/1024) || 'M;' ResizeCMD
from v$datafile a,
(select file_id,max(block_id+blocks-1) HWM
from dba_extents where file_id in
(select b.file# From v$tablespace a ,v$datafile b
where a.ts#=b.ts# and a.name='SYSTEM')
group by file_id) b
where a.file# = b.file_id(+)
and (a.bytes - HWM *block_size)>0
order by 5
/
FILE#
----------
NAME
----------------------------------------------------------------------------------------------
CURRENTMB RESIZETO RELEASEMB
---------- ---------- ----------
RESIZECMD
----------------------------------------------------------------------------------------------
1
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF
1024 545.5 478.5
alter database datafile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF' resize 546M;
3、直接收缩数据文件
SQL> ALTER DATABASE DATAFILE 'D:\oracle\product\10.2.0\oradata\orcl\USERS01.DBF' RESIZE 546m;
正常情况下这样就可以了,但是我在计算datafile可以resize收缩的空间时,发现只能收缩至30G左右,如果收缩太小,出错
SQL> ALTER DATABASE DATAFILE 'D:\oracle\product\10.2.0\oradata\orcl\USERS01.DBF' RESIZE 10240M;
第 1 行出现错误:
ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
文件也有高水位,不是你想RESIZE到多少就多少的,有些有效数据被切掉,当然是不允许的,但是除了原来那张大表,剩余的数据不可能占用怎么大的空间,所以估计是哪个表或其他对象还占用了大量空间
4、找到文件对应的文件号
SQL> select file#,name from v$datafile;
FILE# NAME
---------- --------------------------------------------------------------------------------
1 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF
2 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF
3 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF
4 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF
5 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EXAMPLE01.DBF
6 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XTFDB\UNIEAP.DBF
7 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XTFDB\NEUDOC.DBF
8 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XTFDB\ELARP.DBF
9 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XTFDB\SEAS.DBF
10 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XTFDB\DLMIS.DBF
5、看下找到文件中最大的块号
SQL> select max(block_id) from dba_extents where file_id=1;
SQL> select owner,segment_name,segment_type,tablespace_name,extent_id from dba_extents where block_id=(select max(block_id) from dba_extents);
owner segment_name segment_type tablespace_name extent_id
------ -------------- ------------ --------------- ---------
SYS C_OBJ#_INTCOL# CLUSTER SYSTEM 18
6、主要是C_OBJ#_INTCOL#这个聚簇段占用的块的位置的太大了,接下来要先查出这个聚簇段属于某张表
SQL> select * from dba_clu_columns where cluster_name='C_OBJ#_INTCOL#';
OWNER CLUSTER_NAME CLU_COLUMN_NAME TABLE_NAME TAB_COLUMN_NAME
------------------------------ ------------------------------ ------------------------------ -------------------------- ---------------
SYS C_OBJ#_INTCOL# OBJ# HISTGRM$ OBJ#
SYS C_OBJ#_INTCOL# INTCOL# HISTGRM$ INTCOL#
可以看出来,是属于HISTGRM$表,HISTGRM$系统表,这个表是记录各个业务表的数据分布情况的,网络上查到其基本可以删除
7、截断c_obj#_intcol#
SQL> truncate cluster c_obj#_intcol#;truncate cluster c_obj#_intcol#
第 1 行出现错误:ORA-00701: 无法变更热启动数据库所需的对象
8、截断HISTGRM$表
SQL> truncate table HISTGRM$;
ORA-14512:不能对聚集对象进行操作
ORA-00701:无法改变热启动数据库所需的对象
9、使用move
SQL> ALTER TABLE HISTGRM$ MOVE;
第 1 行出现错误:
ORA-14512: 不能对聚簇对象进行操作
一样的错误
上网查:CLUSTER C_OBJ#_INTCOL#增长导致数据库的SYSTEM 表空间被大量占用,因为这个CLUSTER是一个BOOTSTRAP$对象。由于是BOOTSTRAP$对象,所以无法TRUNCATE.由于这个对象是251>56,因此不是核心BOOTSTRAP$对象,所以我们用得上EVENT 38003了。大意是修改一下event级别,然后重新启动后即可。
10、设置EVENT参数,重启数据库
SQL> alter system set EVENT="38003 trace name context forever, level 10" SCOPE=SPFILE;
系统已更改。
SQL> shutdown immediate;
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup
ORACLE 例程已经启动。
Total System Global Area 612368384 bytes
Fixed Size 1250428 bytes
Variable Size 100666244 bytes
Database Buffers 503316480 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
数据库已经打开。
11、重新截断cluster c_obj#_intcol#
SQL> truncate cluster c_obj#_intcol#;
簇已截断。
12、Resize datafile
SQL> alter database datafile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF' resize 548M;
数据库已更改。
13、测试,确保没有影响
SQL> exec DBMS_STATS.GATHER_TABLE_STATS(ownname=>'scott', tabname=>'emp', estimate_percent=>30, method_opt=>'for all indexed columns size skewonly',cascade=>true, degree=>2);
PL/SQL 过程已成功完成。
14、检查使用exp与expdp是否可以顺利导出数据
我的exp出现如下错误:
C:\Documents and Settings\Administrator>exp scott/tiger file=e:/ymhtest.dmp
EXP-00008: 遇到 ORACLE 错误 600
ORA-00600: 内部错误代码, 参数: [19004], [], [], [], [], [], [],
. . 正在导出表 BONUS
EXP-00008: 遇到 ORACLE 错误 600
ORA-00600: 内部错误代码, 参数: [19004], [], [], [], [], [], [],
. . 正在导出表 COMMIT
EXP-00008: 遇到 ORACLE 错误 600
ORA-00600: 内部错误代码, 参数: [19004], [], [], [], [], [], [],
. . 正在导出表 DEPT
EXP-00008: 遇到 ORACLE 错误 600
ORA-00600: 内部错误代码, 参数: [19004], [], [], [], [], [], [],
. . 正在导出
我的expdp出现如下错误:
ORA-39002: 操作无效
ORA-39070: 无法打开日志文件。
ORA-29283: 文件操作无效
ORA-06512: 在 "SYS.UTL_FILE", line 475
ORA-29283: 文件操作无效
试过很多办法,最终还是无法解决,我的是oracle10.2.0。1的,有人说要打补丁才行,没试过,最后只好还原数据库,所以,要尽量小心。
注意:这是不被支持的方法,建议在生产库中不要轻易实施,如果要实施
1、备份数据库
2、最好操作后要对重要的表进行一次分析,可能影响系统中的一些SQL的执行计划。
1、先查询可以利用的空闲空间
SQL> select sum(bytes/1024/1024/1024) from dba_free_space where tablespace_name='SYSTEM';
SUM(BYTES/1024/1024/1024)
-------------------------
31.4642944
2、计算datafile可以resize收缩的空间,也就是必须剩余部分其他对象正在使用的空间
select a.file#,a.name,a.bytes/1024/1024 CurrentMB,
ceil(HWM * a.block_size)/1024/1024 ResizeTo,
(a.bytes - HWM * a.block_size)/1024/1024 ReleaseMB,
'alter database datafile '''||a.name||''' resize '||
ceil(HWM * a.block_size/1024/1024) || 'M;' ResizeCMD
from v$datafile a,
(select file_id,max(block_id+blocks-1) HWM
from dba_extents where file_id in
(select b.file# From v$tablespace a ,v$datafile b
where a.ts#=b.ts# and a.name='SYSTEM')
group by file_id) b
where a.file# = b.file_id(+)
and (a.bytes - HWM *block_size)>0
order by 5
/
FILE#
----------
NAME
----------------------------------------------------------------------------------------------
CURRENTMB RESIZETO RELEASEMB
---------- ---------- ----------
RESIZECMD
----------------------------------------------------------------------------------------------
1
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF
1024 545.5 478.5
alter database datafile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF' resize 546M;
3、直接收缩数据文件
SQL> ALTER DATABASE DATAFILE 'D:\oracle\product\10.2.0\oradata\orcl\USERS01.DBF' RESIZE 546m;
正常情况下这样就可以了,但是我在计算datafile可以resize收缩的空间时,发现只能收缩至30G左右,如果收缩太小,出错
SQL> ALTER DATABASE DATAFILE 'D:\oracle\product\10.2.0\oradata\orcl\USERS01.DBF' RESIZE 10240M;
第 1 行出现错误:
ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
文件也有高水位,不是你想RESIZE到多少就多少的,有些有效数据被切掉,当然是不允许的,但是除了原来那张大表,剩余的数据不可能占用怎么大的空间,所以估计是哪个表或其他对象还占用了大量空间
4、找到文件对应的文件号
SQL> select file#,name from v$datafile;
FILE# NAME
---------- --------------------------------------------------------------------------------
1 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF
2 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF
3 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF
4 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF
5 D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EXAMPLE01.DBF
6 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XTFDB\UNIEAP.DBF
7 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XTFDB\NEUDOC.DBF
8 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XTFDB\ELARP.DBF
9 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XTFDB\SEAS.DBF
10 E:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XTFDB\DLMIS.DBF
5、看下找到文件中最大的块号
SQL> select max(block_id) from dba_extents where file_id=1;
SQL> select owner,segment_name,segment_type,tablespace_name,extent_id from dba_extents where block_id=(select max(block_id) from dba_extents);
owner segment_name segment_type tablespace_name extent_id
------ -------------- ------------ --------------- ---------
SYS C_OBJ#_INTCOL# CLUSTER SYSTEM 18
6、主要是C_OBJ#_INTCOL#这个聚簇段占用的块的位置的太大了,接下来要先查出这个聚簇段属于某张表
SQL> select * from dba_clu_columns where cluster_name='C_OBJ#_INTCOL#';
OWNER CLUSTER_NAME CLU_COLUMN_NAME TABLE_NAME TAB_COLUMN_NAME
------------------------------ ------------------------------ ------------------------------ -------------------------- ---------------
SYS C_OBJ#_INTCOL# OBJ# HISTGRM$ OBJ#
SYS C_OBJ#_INTCOL# INTCOL# HISTGRM$ INTCOL#
可以看出来,是属于HISTGRM$表,HISTGRM$系统表,这个表是记录各个业务表的数据分布情况的,网络上查到其基本可以删除
7、截断c_obj#_intcol#
SQL> truncate cluster c_obj#_intcol#;truncate cluster c_obj#_intcol#
第 1 行出现错误:ORA-00701: 无法变更热启动数据库所需的对象
8、截断HISTGRM$表
SQL> truncate table HISTGRM$;
ORA-14512:不能对聚集对象进行操作
ORA-00701:无法改变热启动数据库所需的对象
9、使用move
SQL> ALTER TABLE HISTGRM$ MOVE;
第 1 行出现错误:
ORA-14512: 不能对聚簇对象进行操作
一样的错误
上网查:CLUSTER C_OBJ#_INTCOL#增长导致数据库的SYSTEM 表空间被大量占用,因为这个CLUSTER是一个BOOTSTRAP$对象。由于是BOOTSTRAP$对象,所以无法TRUNCATE.由于这个对象是251>56,因此不是核心BOOTSTRAP$对象,所以我们用得上EVENT 38003了。大意是修改一下event级别,然后重新启动后即可。
10、设置EVENT参数,重启数据库
SQL> alter system set EVENT="38003 trace name context forever, level 10" SCOPE=SPFILE;
系统已更改。
SQL> shutdown immediate;
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup
ORACLE 例程已经启动。
Total System Global Area 612368384 bytes
Fixed Size 1250428 bytes
Variable Size 100666244 bytes
Database Buffers 503316480 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
数据库已经打开。
11、重新截断cluster c_obj#_intcol#
SQL> truncate cluster c_obj#_intcol#;
簇已截断。
12、Resize datafile
SQL> alter database datafile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF' resize 548M;
数据库已更改。
13、测试,确保没有影响
SQL> exec DBMS_STATS.GATHER_TABLE_STATS(ownname=>'scott', tabname=>'emp', estimate_percent=>30, method_opt=>'for all indexed columns size skewonly',cascade=>true, degree=>2);
PL/SQL 过程已成功完成。
14、检查使用exp与expdp是否可以顺利导出数据
我的exp出现如下错误:
C:\Documents and Settings\Administrator>exp scott/tiger file=e:/ymhtest.dmp
EXP-00008: 遇到 ORACLE 错误 600
ORA-00600: 内部错误代码, 参数: [19004], [], [], [], [], [], [],
. . 正在导出表 BONUS
EXP-00008: 遇到 ORACLE 错误 600
ORA-00600: 内部错误代码, 参数: [19004], [], [], [], [], [], [],
. . 正在导出表 COMMIT
EXP-00008: 遇到 ORACLE 错误 600
ORA-00600: 内部错误代码, 参数: [19004], [], [], [], [], [], [],
. . 正在导出表 DEPT
EXP-00008: 遇到 ORACLE 错误 600
ORA-00600: 内部错误代码, 参数: [19004], [], [], [], [], [], [],
. . 正在导出
我的expdp出现如下错误:
ORA-39002: 操作无效
ORA-39070: 无法打开日志文件。
ORA-29283: 文件操作无效
ORA-06512: 在 "SYS.UTL_FILE", line 475
ORA-29283: 文件操作无效
试过很多办法,最终还是无法解决,我的是oracle10.2.0。1的,有人说要打补丁才行,没试过,最后只好还原数据库,所以,要尽量小心。
注意:这是不被支持的方法,建议在生产库中不要轻易实施,如果要实施
1、备份数据库
2、最好操作后要对重要的表进行一次分析,可能影响系统中的一些SQL的执行计划。
相关文章推荐
- ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
- ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
- Oracle调整表空间大小——ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
- ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
- ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
- Oracle调整表空间大小——ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
- Oracle调整表空间大小——ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
- Oracle调整表空间大小——ORA-03297: 文件包含在请求的 RESIZE 值以外使用的数据
- 使用create datafile... as ...迁移数据文件到裸设备
- 使用alter database create datafile恢复丢失数据文件
- 使用innodb_data_file_path修改数据文件位置,发生The server quit without updating PID file错误的解决原因及方法。
- 使用alter tablespace create datafile恢复丢失的数据文件
- 如何缩小或者扩大数据文件 How to Resize a Datafile (Doc ID 1029252.6)
- ORACLE 11G收缩表空间报错 ORA-03297: file contains used data beyondrequested RESIZE value
- RESIZE DATAFILE与ORA-03297
- ORA-15041: diskgroup "DATAVG" space exhausted ASM空间假装耗尽不足,resize数据文件和增加数据文件失败
- 调用webapi 错误:使用 HTTP 谓词 POST 向虚拟目录发送了一个请求,而默认文档是不支持 GET 或 HEAD 以外的 HTTP 谓词的静态文件。的解决方案
- Oracle使用dba_data_files查看表空间大小及数据文件位置
- Oracle Data Pump 工具系列:使用 %U 和 filesize 参数将大数据拆分成小文件导出
- Asp.Net MVC 使用FileResult导出Excel数据文件