Oracle回收表空间

查询表空间使用率

--查看数据库表空间使用率
select total.tablespace_name "表空间",
       round(total.MB, 2) || 'M' "总量",
       round(total.MB - free.MB, 2) || 'M' "已使用",
       round((1 - free.MB / total.MB) * 100, 2) || '%' "使用率",
       total.file_id "文件ID",
       total.file_name "文件名"
  from (select tablespace_name, sum(bytes) / 1024 / 1024 MB
          from dba_free_space
         group by tablespace_name) free,
       (select tablespace_name,
               sum(bytes) / 1024 / 1024 MB,
               file_name,
               file_id
          from dba_data_files
         group by tablespace_name, file_name, file_id) total
 where free.tablespace_name = total.tablespace_name
 order by total.MB desc, (total.MB - free.MB) desc;

重置表空间大小

--重置表空间大小
alter database datafile '/oradata/xxx.DBF' resize 1000m;

查询表空间中的block_id

--查询出大的block_id
select ext.segment_name   "名称",
       ext.partition_name "分区",
       ext.segment_type   "类型",
       ext.blocks         "块数",
       ext.block_id       "块ID"
  from dba_extents ext, dba_segments seg
 where ext.file_id = seg.header_file
   and ext.segment_name = seg.segment_name
   and ext.file_id = 13
 order by ext.block_id desc;

整理表空间

alter tablespace 表空间 coalesce;

收缩表的使用空间

--收缩表使用空间
select re_sql "脚本"
  from (SELECT DISTINCT 'alter table ' || owner || '.' || segment_name ||
                        ' enable row movement;' as re_sql,
                        segment_name,
                        1 as idx
          FROM dba_extents
         WHERE tablespace_name = '表空间'
           AND segment_type = 'TABLE'
        union all
        SELECT DISTINCT 'alter table ' || owner || '.' || segment_name ||
                        ' shrink space;' as re_sql,
                        segment_name,
                        2 as idx
          FROM dba_extents
         WHERE tablespace_name = '表空间'
           AND segment_type = 'TABLE'
              
           AND segment_type = 'TABLE'
        union all
        SELECT DISTINCT 'alter table ' || owner || '.' || segment_name ||
                        ' disable row movement;' as re_sql,
                        segment_name,
                        3 as idx
          FROM dba_extents
         WHERE tablespace_name = '表空间'
           AND segment_type = 'TABLE')
 order by segment_name, idx

清空回收站

-- 清除用户回收站 
purge recyclebin; 
-- 清除全库回收站 
purge dba_recyclebin;

 创建新表空间用来存储移动的数据

--创建一个临时表空间
create tablespace 新表空间 datafile '/oradata/xxx.dbf' size 1000m autoextend on next 50m;

移动数据到新的表空间

--file_id为上述查出来的文件ID
--需要移动的表数据
select DISTINCT 'alter table ' || owner || '.' || segment_name ||
                ' move tablespace 新表空间;' "脚本"
  from dba_extents
 where segment_type = 'TABLE'
   and file_id = 15;

--需移动lob
select distinct 'alter table '||lob.owner||'.'||lob.table_name||' move lob('||lob.column_name||') store as (tablespace 新表空间);' "脚本"
  from DBA_LOBS lob, dba_extents ext 
 where 1=1
 and lob.owner = ext.owner
 and lob.segment_name = ext.segment_name
  and ext.file_id = 15
 and  ext.segment_type = 'LOBSEGMENT';
  
--需移动的索引数据 
select DISTINCT 'alter index ' || owner || '.' || segment_name ||
                ' rebuild tablespace 新表空间;' "脚本"
  from dba_extents
 where segment_type = 'INDEX'
   and file_id = 15;
   
--需移动的分区表数据 
select DISTINCT 'alter table ' || owner || '.' || segment_name ||
                ' move partition ' || partition_name ||
                ' tablespace 新表空间;' "脚本"
  from dba_extents
 where segment_type = 'TABLE PARTITION'
   and file_id = 15;
   
--需移动的分区表索引数据 
select DISTINCT 'alter index ' || owner || '.' || segment_name ||
                ' rebuild partition ' || partition_name ||
                ' tablespace 新表空间;' "脚本"
  from dba_extents
 where segment_type = 'INDEX PARTITION'
   and file_id = 15;
   

再将数据移动回原空间

--file_id为上述查出来的新表空间的文件ID
--需要移动的表数据
select DISTINCT 'alter table ' || owner || '.' || segment_name ||
                ' move tablespace 原表空间;' "脚本"
  from dba_extents
 where segment_type = 'TABLE'
   and file_id = 17;

--需移动lob
select distinct 'alter table '||lob.owner||'.'||lob.table_name||' move lob('||lob.column_name||') store as (tablespace 新表空间);' "脚本"
  from DBA_LOBS lob, dba_extents ext 
 where 1=1
 and lob.owner = ext.owner
 and lob.segment_name = ext.segment_name
  and ext.file_id = 17
 and  ext.segment_type = 'LOBSEGMENT';
  
--需移动的索引数据 
select DISTINCT 'alter index ' || owner || '.' || segment_name ||
                ' rebuild tablespace 原表空间;' "脚本"
  from dba_extents
 where segment_type = 'INDEX'
   and file_id = 17;
   
--需移动的分区表数据 
select DISTINCT 'alter table ' || owner || '.' || segment_name ||
                ' move partition ' || partition_name ||
                ' tablespace 原表空间;' "脚本"
  from dba_extents
 where segment_type = 'TABLE PARTITION'
   and file_id = 17;
   
--需移动的分区表索引数据 
select DISTINCT 'alter index ' || owner || '.' || segment_name ||
                ' rebuild partition ' || partition_name ||
                ' tablespace 原表空间;' "脚本"
  from dba_extents
 where segment_type = 'INDEX PARTITION'
   and file_id = 17;
   

查询出可重置的大小

--file_id为空表空间文件ID
--查询出可重置大小并执行
select a.file# "文件ID",
       a.name "名称",
       a.bytes / 1024 / 1024 "总量",
       ceil(HWM * a.block_size) / 1024 / 1024 "实际",
       (a.bytes - HWM * a.block_size) / 1024 / 1024 "未使用",
       'alter database datafile ''' || a.name || ''' resize ' ||
       ceil(HWM * a.block_size / 1024 / 1024) || 'M;' "脚本"
  from v$datafile a,
       (select file_id, max(block_id + blocks - 1) HWM
          from dba_extents
         where file_id = '13'
         group by file_id) b
 where a.file# = b.file_id(+)
   and (a.bytes - HWM * block_size) > 0
 order by 5;

猜你喜欢

转载自blog.csdn.net/wyanyi/article/details/131866453