一、Oracle 压缩表占用空间

在使用Oracle的过程中,如果存储的数据量过多,就会造成表空间占用内存过大的情况,可能几个G甚至几百个G。

此时可以通过删除部分无用数据,然后压缩表占用空间的方法来释放内存。

 

1、查看数据库表内存使用情况:

select segment_name as TABLENAME, segment_type, BYTES/1024/1024 MB from user_segments order by MB desc;

索引缓存如何删除 索引表空间清理_索引缓存如何删除

 

2、将占用空间大的表中无用的数据、或者是比较早的数据删除。

 

3、数据删除后,还需要缩减该表的空间:

--缩减表空间,必须启用 row movement 功能
alter table 表名 enable row movement;

--执行缩减表空间命令
alter table 表名 shrink space;

 

4、如果该表存在索引,那么需要重建索引

--查看当前表下的索引
select * from user_indexes where table_name = '表名';

--重建索引
alter index 索引名 rebuild;

 

5、之后使用下列命令查看表空间可以释放的内存:

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 --拼接释放空间SQL命令
from 
	v$datafile a,
	(SELECT file_id, MAX(block_id + blocks - 1) HWM
		FROM DBA_EXTENTS
		GROUP BY file_id
	) b
where a.file# = b.file_id(+) and (a.bytes - HWM * a.block_size) > 0;

索引缓存如何删除 索引表空间清理_表空间占用_02

 

6、拿到释放空间执行的命令执行即可,resize 后边跟的是调整后的表空间大小,建议调整为整数。

 

7、如果确定某张表已经不用,可以删除这张表:

drop命令:用drop删除表,不但会删除表中的数据,连表结构也被删除了!但该命令不会释放空间

--删除表
drop table 表名;

--从回收站中清空该表的信息
purge table 表名;

--也可以直接清空回收站
purge recyclebin;

truncate命令:用truncate删除表数据,只是删除表中的数据,表结构不会被删除!系统一次性删除数据,效率比较高,并且释放空间

truncate table 表名;

 

 

二、Oracle UNDOTBS01.dbf 占用空间过大解决

在无法使用第一种方法压缩占用空间的情况下,可以使用本方法。

 

UNDOTBS01.dbf是oracle系统undo_tablespace使用的,其作用为:
        回退事务、读一致性、事务恢复、倒叙查询(FlashBack Query)

 

1、先查看在使用UNDOTBS01.dbf的undo_tablespace表名:

使用sqlplus连接数据库,输入命令

show parameter undo;

索引缓存如何删除 索引表空间清理_索引缓存如何删除_03

 

2、建立一张新的undo_tablespace:

create undo tablespace undotbs02 datafile 'D:\Oracle\oradata\orcl\UNDOTBS02.dbf' size 100m autoextend on next 100m;
--注意:Linux下的目录分隔符要使用正斜杠“/”

索引缓存如何删除 索引表空间清理_内存_04

 

3、将系统undo_tablespace指向新的表空间:

alter system set undo_tablespace=undotbs02;

索引缓存如何删除 索引表空间清理_索引缓存如何删除_05

 

4、删除原来的表空间及数据文件:

drop tablespace undotbs1 including contents  and datafiles;

索引缓存如何删除 索引表空间清理_Oracle_06

 

若要禁止undo_tablespace自动增长

alter database datafile 'D:\Oracle\oradata\orcl\UNDOTBS02.dbf' autoextend off;

 

三、压缩表占用空间测试:

1、建立一个用于测试的表空间:

create tablespace test01 datafile 'D:\Oracle\oradata\orcl\TEST01.dbf' size 100m autoextend on next 10m;
--注意:Linux下的目录分隔符要使用正斜杠“/”

2、建立测试用户:

create user test01 identified by test01 default tablespace test01;

3、给用户赋予权限:

grant dba to test01;

4、使用test01用户接入数据库

5、建立测试表:

DROP TABLE "TEST01";
CREATE TABLE "TEST01" (
"ID" NUMBER(11) NULL ,
"DATACODE" VARCHAR2(255 BYTE) NULL ,
"DATATIME" VARCHAR2(30 BYTE) NULL ,
"CHECKTIME" NUMBER(11) NULL ,
"SHOULDARRIVE" NUMBER(11) NULL ,
"REALARRIVE" NUMBER(11) NULL ,
"ARRIVALRATE" NUMBER(11) NULL ,
"ALARMCODE" VARCHAR2(20 BYTE) NULL ,
"CREATETIME" TIMESTAMP(6)  NULL ,
"CLOB" CLOB NULL 
)
LOGGING
NOCOMPRESS
NOCACHE;

CREATE INDEX "TEST01"
ON "TEST01" ("DATACODE" ASC, "DATATIME" ASC, "CHECKTIME" ASC)
LOGGING
VISIBLE;

6、插入数据,五百万条,我用PL\SQL插入,PL\SQL可以使用循环语句:

declare
  i number := 1;
begin
  for i in 1..5000000 loop
    INSERT INTO TEST01 
           ("ID", "DATACODE", "DATATIME", "CHECKTIME", "SHOULDARRIVE", "REALARRIVE", "ARRIVALRATE", "ALARMCODE", "CREATETIME", "CLOB") 
    VALUES 
           (i, 'X7005_50_Min', '201902010050', '51', '25', '0', '0', NULL, TO_TIMESTAMP(' 2019-02-01 01:41:04:572000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), NULL);
  end loop;
end;

7、之后按照第一节说的那样做就行。

 

四、补充知识

1、表空间、数据文件

查看当前数据库下有哪些数据文件(.dbf)及其所属的表空间

select file_name,tablespace_name from dba_data_files;

查看有那些表空间

select tablespace_name from dba_tablespaces;

查看指定表空间下的数据文件

select file_name from dba_data_files where tablespace_name = '表空间名';

查看数据库下全部的表的占用空间

select tablespace_name, owner, segment_name as tablename, segment_type, bytes/1024/1024 MB from dba_segments order by MB desc;

 

2、审计数据清理

Oracle 11g 默认是开启审计功能的,这样,长时间运行访问Oracle,会产生大量审计数据,造成SYSTEM表空间爆满。

通常是记录用户登录与登出的审计数据较多,我们可以使用下列命令看一下:

select action_name,count(*) total from sys.dba_audit_trail group by action_name order by total desc;

索引缓存如何删除 索引表空间清理_索引缓存如何删除_07

我的天,登录、登出的审计数据共计有将近四千万条!!!

关闭登录、登出的审计功能,即关闭创建session的审计功能,命令如下:

noaudit connect;

注:noaudit是撤销审计功能,audit是开启审计功能。本命令以为撤销对connect(即数据库连接,也就是session)的审计功能。

 

然后使用下列命令查看是否成功撤销登录、登出的审计功能:

select user_name, audit_option, success, failure from sys.dba_stmt_audit_opts where audit_option like '%CREATE%';

如果结果中没有CREATE SESSION,若没有,则表示操作成功。

索引缓存如何删除 索引表空间清理_undotbs_08

 

3、Oracle临时表空间清理(TEMP01.dbf)

Oracle临时表空间主要用来做查询和存放一些缓冲区数据。临时表空间的主要作用:索引create或rebuild、Order by 或 group by、Distinct 操作、Union 或 intersect 或 minus、Sort-merge joins、analyze。

重启数据库可以释放临时表空间,但在生产环境中通常是不允许重启的,而一直保持问题sql语句的执行,temp表空间会一直增长。

第一步:建立一个新的临时表空间。

create temporary tablespace temp02 tempfile 'D:\oracle\oradata\orcl\temp02.dbf' size 1024m autoextend on next 100m;
--注意:Linux下的目录分隔符要使用正斜杠“/”

第二步:改变缺省临时表空间

alter database default temporary tablespace temp02;

第三步:删除原来的临时表空间及数据文件

drop tablespace temp including contents and datafiles;