一、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;
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;
2、建立一张新的undo_tablespace:
create undo tablespace undotbs02 datafile 'D:\Oracle\oradata\orcl\UNDOTBS02.dbf' size 100m autoextend on next 100m;
--注意:Linux下的目录分隔符要使用正斜杠“/”
3、将系统undo_tablespace指向新的表空间:
alter system set undo_tablespace=undotbs02;
4、删除原来的表空间及数据文件:
drop tablespace undotbs1 including contents and datafiles;
若要禁止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;
我的天,登录、登出的审计数据共计有将近四千万条!!!
关闭登录、登出的审计功能,即关闭创建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,若没有,则表示操作成功。
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;