37-Oracle 23 ai Shrink Tablespace(一键收缩表空间)

小伙伴们有没有经历过,超大表和超大数据的导入后,数据被删除了,然而空间迟迟不释放,存储添置又跟不上,业务空间告警的时候。收缩就很必须了,然而收缩需谨慎,数据大过天。DBMS_SPACE.SHRINK_TABLESPACE是Oracle 23ai新增功能,使得23 ai有了在线一键shrink tablespace的功能,19c及以下还需要手动操作。

一、Shrink技术特性

在Oracle 23ai中,​ 大文件表空间收缩(Shrink Tablespace)​​ 的核心机制是通过数据重组消除存储碎片,关键技术点如下:
  • ​空间碎片整理​
当表被截断(TRUNCATE)或数据删除后,数据文件中会产生不连续的空白空间间隙(GAP)​。收缩操作通过移动段对象将这些碎片整理到文件末尾。
  • 在线段重组​
使用DBMS_SPACE.SHRINK_TABLESPACE时:
  • 自动识别可移动对象(表、索引等)
  • 在线移动段数据(支持DML并发)
  • 强制模式(TS_MODE_SHRINK_FORCE)处理不支持在线移动的对象
  • ​文件截断机制​
碎片整理完成后,Oracle将空白空间从文件尾部截断,实现物理文件收缩。
  • 操作模式​
  • 分析模式(TS_MODE_ANALYZE)​​:计算可回收空间
该模式不会实际移动数据或回收空间,而是分析表空间并返回一个报告,显示可以回收多少空间,以及建议的目标数据文件大小。它只是模拟收缩操作,不会对数据文件做任何修改。
  • 收缩模式(TS_MODE_SHRINK)​​:执行实际空间回收
该模式会实际执行空间回收操作。它将移动表空间中可移动的段(如普通表、索引等),以压缩数据文件中的空间,然后截断数据文件以释放未使用的空间。
  • TS_TARGET_MAX_SHRINK:尽可能多地回收空间(默认)
指定一个具体的数值(以字节为单位)作为目标大小。
  • 强制模式(TS_MODE_SHRINK_FORCE)
它会尝试移动那些在普通收缩模式下无法移动的段(通过离线移动等方式)。该模式会尝试对普通模式下无法移动的对象进行离线移动(Offline Move)。这可能会导致相关对象在移动期间不可用,因此使用时要谨慎。
可被移动对方回收空间
  • 普通堆表(Heap Table)
  • 索引组织表(IOT)
  • 索引(Index)
  • 分区表的分区(Partition)
  • 物化视图(Materialized View)
  • 物化视图日志(Materialized View Log)
不可移动对象​:

某些对象不能被移动,例如:

  • 包含LOB列且LOB存储在单独段中的表(因为LOB段可能位于不同的表空间)
  • 具有活动事务的对象
  • 包含LONG类型的表
  • 系统表空间(SYSTEM, SYSAUX)中的对象(尽管SYSAUX可以收缩,但有特殊限制)
空间回收限制​:即使使用强制模式,仍然可能无法回收所有空间,
  • 表空间中的某些对象无法移动(如上述不可移动对象)
  • 数据文件中的某些空间是正在使用的,无法回收
性能影响​:

收缩操作会移动数据,因此会消耗I/O资源。建议在业务低峰期进行。

依赖关系​:
如果表空间中的对象有依赖关系(例如表上的索引),收缩操作会自动按正确顺序处理这些对象。

二、典型使用场景

  • 批量数据清理后​ - 截断/删除大表后回收空间
  • 存储空间优化​ - 解决文件系统空间不足问题
  • 数据归档场景​ - 历史数据迁移后回收空间
  • 周期性维护​ - 作为数据库健康检查的一部分

 三、Oracle 23ai 实操脚本

-- 1. 创建测试环境
ALTER SYSTEM SET db_create_file_dest='/opt/oracle/oradata/FREE';
--System altered.DROP USER IF EXISTS shrink_user CASCADE;
--User SHRINK_USER dropped.DROP TABLESPACE IF EXISTS shrink_ts INCLUDING CONTENTS AND DATAFILES;
--TABLESPACE SHRINK_TS dropped.CREATE BIGFILE TABLESPACE shrink_ts DATAFILE SIZE 10M AUTOEXTEND ON NEXT 1M;
--TABLESPACE SHRINK_TS created.CREATE USER shrink_user IDENTIFIED BY shrink_userDEFAULT TABLESPACE shrink_tsQUOTA UNLIMITED ON shrink_ts;
--User SHRINK_USER created.GRANT CREATE SESSION, CREATE TABLE TO shrink_user;
GRANT SELECT_CATALOG_ROLE TO shrink_user;
--Grant succeeded.-- 2. 创建测试数据
sqlplus shrink_user/shrink_user@localhost:1521/FREEPDB1
--
[oracle@OL97 customer_orders]$ sqlplus shrink_user/shrink_user@localhost:1521/FREEPDB1
SQL*Plus: Release 23.0.0.0.0 - Production on Sun Jun 15 13:38:32 2025
Version 23.8.0.25.04
Copyright (c) 1982, 2025, Oracle.  All rights reserved.
Connected to:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04
SHRINK_USER@localhost:1521/FREEPDB1>
--
CREATE TABLE sales_data (id      NUMBER,details VARCHAR2(4000),CONSTRAINT sales_pk PRIMARY KEY (id)
);
--Table created.INSERT /*+APPEND*/ INTO sales_data
SELECT ROWNUM, RPAD('X', 4000, 'X')
FROM dual
CONNECT BY LEVEL <= 100000;
COMMIT;
--
100000 rows created.
SHRINK_USER@localhost:1521/FREEPDB1>
Commit complete.
--收集信息
EXEC DBMS_STATS.GATHER_TABLE_STATS(null, 'SALES_DATA');
SHRINK_USER@localhost:1521/FREEPDB1> EXEC DBMS_STATS.GATHER_TABLE_STATS(null, 'SALES_DATA');
PL/SQL procedure successfully completed.-- 3. 检查初始空间分配
SELECT tablespace_name, ROUND(bytes/1024/1024, 2) AS size_mb 
FROM dba_data_files 
WHERE tablespace_name = 'SHRINK_TS';
--
TABLESPACE_NAME                   SIZE_MB
------------------------------ ----------
SHRINK_TS                             908
--
SELECT table_name, blocks,ROUND((blocks*8)/1024, 2) AS size_mb 
FROM user_tables;
--
TABLE_NAME       BLOCKS    SIZE_MB
_____________ _________ __________
SALES_DATA       100507     785.21-- 4. 删表模拟数据清理
TRUNCATE TABLE sales_data;
EXEC DBMS_STATS.GATHER_TABLE_STATS(null, 'SALES_DATA');
-- 删除也可以模拟 模拟空间碎片
DELETE FROM SALES_DATA WHERE id <= 40000;
COMMIT;
--
SHRINK_USER@localhost:1521/FREEPDB1> DELETE FROM SALES_DATA WHERE id <= 40000;
40,000 rows deleted.
-- 5. 分析可回收空间 (SYS权限)
sqlplus / AS SYSDBA
SET SERVEROUTPUT ONBEGINDBMS_SPACE.SHRINK_TABLESPACE(tablespace_name => 'SHRINK_TS',shrink_mode    => DBMS_SPACE.TS_MODE_ANALYZE);
END;
/---- 5. 预收缩空间分析
SELECT segment_name,segment_type,blocks,bytes/1024/1024 size_mb
FROM user_segments;
--
SEGMENT_NAME    SEGMENT_TYPE       BLOCKS    SIZE_MB
_______________ _______________ _________ __________
SALES_DATA      TABLE              101248        791
SALES_PK        INDEX                 256          2-- 6. 执行空间收缩(SYS权限)
BEGINDBMS_SPACE.SHRINK_TABLESPACE('SHRINK_TS');
END;
/
--
[root@OL97 dbs]# su - oracle
[oracle@OL97 ~]$ sql / as sysdba;
SQLcl: Release 25.1 Production on Sun Jun 15 13:43:44 2025
Copyright (c) 1982, 2025, Oracle.  All rights reserved.
Connected to:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.8.0.25.04
SYS@CDB$ROOT> alter session set container =FREEPDB1;
Session altered.
SYS@CDB$ROOT> BEGIN2    DBMS_SPACE.SHRINK_TABLESPACE('SHRINK_TS');3  END;4* /PL/SQL procedure successfully completed.
SYS@CDB$ROOT>-- 7. 验证收缩结果
SELECT tablespace_name, ROUND(bytes/1024/1024, 2) AS size_mb 
FROM dba_data_files 
WHERE tablespace_name = 'SHRINK_TS';
--
TABLESPACE_NAME       SIZE_MB
__________________ __________
SHRINK_TS                 862-- 清理环境
DROP USER shrink_user CASCADE;
DROP TABLESPACE shrink_ts INCLUDING CONTENTS AND DATAFILES;

四、验证要点 

  • 空间回收验证
-- 收缩前后空间对比
SELECT df.tablespace_name,SUM(df.bytes)/1024/1024 allocated_mb,SUM(df.bytes - NVL(fs.free_bytes, 0))/1024/1024 used_mb
FROM dba_data_files df
LEFT JOIN (SELECT file_id, SUM(bytes) AS free_bytes  -- 添加明确别名FROM dba_free_spaceGROUP BY file_id
) fs ON df.file_id = fs.file_id
WHERE df.tablespace_name = 'SHRINK_TS'  -- 添加表别名
GROUP BY df.tablespace_name;  -- 添加表别名
--
TABLESPACE_NAME       ALLOCATED_MB     USED_MB
__________________ _______________ ___________
SHRINK_TS                      862    861.0625
  • 段移动监控​ 
-- 实时监控收缩操作
SELECT sql_id,sid,event,p1 TEXT,p2 BLOCKS_MOVED
FROM v$session
WHERE module = 'SHRINK_TBS';
  • 查询依赖验证​ 
-- 检查未收缩对象
SELECT segment_name, segment_type
FROM dba_segments
WHERE tablespace_name = 'SHRINK_TS'AND blocks > 0
MINUS
SELECT segment_name, segment_type
FROM dba_segments
WHERE tablespace_name = 'SHRINK_TS'AND blocks > 0AND segment_name IN (SELECT object_name FROM dba_objectsWHERE created < SYSDATE - 1/24
);
--
SEGMENT_NAME    SEGMENT_TYPE
_______________ _______________
SALES_DATA      TABLE
SALES_PK        INDEX

五、关键注意事项

  • 在线操作限制​标准模式仅处理支持在线移动的对象,强制模式可能导致短暂锁表
  • 空间预留策略​ALTER TABLESPACE ... AUTOEXTEND OFF 可在收缩前禁用自动扩展
  • 系统表空间支持​SYSAUX表空间可收缩,但SYSTEM表空间不支持
  • 操作监控​通过 V$SESSION_LONGOPS 监控收缩进度:
SELECT sid, serial#, opname, sofar, totalwork 
FROM v$session_longops 
WHERE opname LIKE 'SHRINK%';
  •  最佳操作时间​
  1. - 在业务低峰期执行
  2. - 收缩前进行完整备份
  3. - 优先使用分析模式评估收益

​Oracle 23ai的大文件表空间收缩技术彻底解决了传统表空间空间回收需依赖操作系统的问题,结合OMF(Oracle Managed Files)特性,实现了端到端的自动化存储管理。通过在线重组实现存储空间的高效回收,显著降低存储成本。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/85031.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我自己动手写了一个MySQL自动化备份脚本,基于docker

MySQL自动化备份Docker方案 该方案仅需通过 Docker Compose 就能轻松完成部署。你可以自由配置数据库连接信息&#xff0c;无论是远程数据库&#xff0c;还是本地数据库&#xff0c;都能实现无缝对接。在备份频率设置上&#xff0c;支持按固定秒数间隔执行备份任务&#xff0c…

leetcode23-合并K个升序链表

leetcode 23 思路 遍历所有链表收集节点&#xff1a;将每个链表的节点断开其 next 指针后存入数组对数组进行排序&#xff1a;使用 JavaScript 的内置 sort 方法对节点数组按值排序重新连接排序后的节点&#xff1a;遍历排序后的数组&#xff0c;依次连接每个节点形成新链表…

(十六)GRU 与 LSTM 的门控奥秘:长期依赖捕捉中的遗忘 - 更新机制对比

1 长期依赖捕捉能力的核心差异 1.1 信息传递路径&#xff1a;细胞状态 vs 单一隐藏状态 LSTM的“信息高速公路”机制 LSTM通过独立的细胞状态&#xff08;Cell State&#xff09; 传递长期信息&#xff0c;该状态可视为“直接通路”&#xff0c;允许信息跨越多个时间步而不被中…

HTTP 请求报文 方法

在 HTTP 请求报文 中&#xff0c;方法&#xff08;Method&#xff09; 是用来说明客户端希望对服务器资源执行的操作。它出现在 HTTP 报文的第一行&#xff0c;称为 请求行&#xff0c;格式如下&#xff1a; METHOD Request-URI HTTP-Version例如&#xff1a; GET /index.h…

【深度解析】Java高级并发模式与实践:从ThreadLocal到无锁编程,全面避坑指南!

&#x1f50d; 一、ThreadLocal&#xff1a;线程隔离的利器与内存泄露陷阱 底层原理揭秘&#xff1a; 每个线程内部维护ThreadLocalMap&#xff0c;Key为弱引用的ThreadLocal对象&#xff0c;Value为存储的值。这种设计导致了经典内存泄露场景&#xff1a; // 典型应用&#…

使用存储型 XSS 窃取 cookie 并发送到你控制的服务器

&#x1f9ea; 第一步&#xff1a;准备监听服务接收 cookie 在你的本机&#xff08;非容器&#xff09;或 DVWA 所在主机运行以下 Python 监听代码&#xff0c;用于接收窃取的 cookie&#xff1a; 启动 HTTP 接收服务 # 在本机终端运行&#xff0c;监听 8081 端口&#xff0…

WebDebugX和多工具组合的移动端调试流程构建:一个混合App项目的实践案例

前段时间参与了一个跨平台的医疗服务 App 项目&#xff0c;整体架构采用 Flutter 封装原生模块&#xff0c;部分功能模块嵌套 WebView 加载 H5 页面。开发过程中我们频繁遇到 Web 页面在移动端表现异常的问题&#xff0c;比如样式错乱、请求失败、性能延迟等&#xff0c;而这些…

图形编辑器基于Paper.js教程29:基于图层的所有矢量图元的填充规则实现

背景 在lightburn中&#xff0c;对于填充图层&#xff0c;有这样一个隐藏的逻辑&#xff0c;那就是&#xff0c;在加工时&#xff0c;填充规则是以填充图层的所有元素进行计算的&#xff0c;什么意思那&#xff1f; 如果你在填充图层中画了两个图形&#xff0c;一个圆&#xf…

Python 函数实战指南:提升编程效率的实用技巧

在 Python 编程的世界里&#xff0c;函数是构建高效代码的基石。掌握实用的函数技巧不仅能让代码更加简洁优雅&#xff0c;还能显著提升开发效率。我们一起将结合实际案例&#xff0c;深入剖析 Python 函数的使用技巧&#xff0c;帮助开发者在日常开发中事半功倍。 一、基础函数…

OPenCV CUDA模块图形变换----构建透视变换映射表函数buildWarpPerspectiveMaps()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数用于构建一个透视变换&#xff08;Perspective Transform&#xff09;的映射表&#xff08;xmap / ymap&#xff09;&#xff0c;可用于后…

tcping工具使用指南

tcping是一个用于测试TCP端口连通性的工具&#xff0c;它类似于传统的ping命令&#xff0c;但工作在传输层(TCP)而不是网络层(ICMP)。 基本功能 tcping的主要功能包括&#xff1a; 测试目标主机特定TCP端口是否开放 测量TCP连接建立时间 统计丢包率和响应时间 安装方法 …

CSP 2024 入门级第一轮(88.5)

4. 以下哪个序列对应数字 00 至 88 的 44 位二进制格雷码&#xff08;Gray code&#xff09;&#xff1f;&#xff08; &#xff09; A. 0000, 0001, 0011, 0010, 0110, 0111, 0101, 1000 B. 0000, 0001, 0011, 0010, 0110, 0111, 0100, 0101 C. 0000, 0001, 0011, 0010, …

三菱FX-5U系列入门到精通

第2章 中间继电器 继电器工作模式:线圈得电,常开触点闭合,常闭触点断开。总结:中间继电器线圈电压分为:24VDC 110VAC 220VAC 380VAC PLC控制柜中常用的是24VDC比较多,而动力电柜中或者控制风机水泵的电柜中220VAC比较多。大部分选择24VDC,然后用触点控制220或者380,说白…

简历模板1——王明 | 高级数据挖掘工程师 | 5年经验

王明 | 高级数据挖掘工程师 | 5年经验 &#x1f4f1; (86) 189-xxxx-xxxx | &#x1f4e7; wangmingemail.com | &#x1f4cd; 深圳市 &#x1f4bb; GitHub | &#x1f454; LinkedIn &#x1f4bc; 工作经历 ​科技前沿集团 | 高级数据挖掘工程师 &#x1f4c5; 2021.06 …

【JVM】- 内存模式

Java内存模型&#xff1a;JMM&#xff08;Java Memory Model&#xff09;&#xff0c;定义了一套在多线程环境下&#xff0c;读写共享数据&#xff08;成员变量、数组&#xff09;时&#xff0c;对数据的可见性&#xff0c;有序性和原子性的规则和保障。 原子性 问题分析 【问…

AQS独占模式——资源获取和释放源码分析

AQS资源获取&#xff08;独占模式&#xff09; Node节点类 static final class Node {//标记当前节点的线程在共享模式下等待。static final Node SHARED new Node();//标记当前节点的线程在独占模式下等待。static final Node EXCLUSIVE null;//waitStatus的值&#xff0c…

压测过程中TPS上不去可能是什么原因

进行性能分析 接口没有报错或者错误率低于1%&#xff0c;继续增加并发还是一样&#xff0c;这个时候需要考虑几点 1.是否触发限流&#xff0c;比如waf、Nginx等情况&#xff0c;有没有一些限流的情况&#xff0c;如果触发了限流&#xff0c;请求是没有达到后端的&#xff0c;所…

Golang 解大整数乘法

文章目录 Golang 解大整数乘法问题描述&#xff1a;LeetCode 43. 字符串相乘思路Golang 代码 Golang 解大整数乘法 在初学 C 语言的时候&#xff0c;我们一定接触过“字符串相加”或“字符串相乘”之类的问题&#xff0c;对于初学者而言&#xff0c;这类问题的难度一般来说是比…

web3-区块链的技术安全/经济安全以及去杠杆螺旋(经济稳定)

web3-区块链的技术安全/经济安全以及去杠杆螺旋&#xff08;经济稳定&#xff09; 三个基本设计问题 技术安全 在技术结构中对其进行原子级的、瞬时利用&#xff08;无风险&#xff09; 无风险&#xff0c;因为攻击者的结果还是二进制的&#xff1a; 只会是攻击成功 获利或…

Java多线程通信:wait/notify与sleep的深度剖析(时序图详解)

在Java多线程编程中&#xff0c;线程间的通信与协作是实现复杂并发逻辑的关键。wait()、notify()以及sleep()方法作为线程控制的重要工具&#xff0c;有着各自独特的使用场景与规则。本文将深入探讨wait()和notify()的协作机制&#xff0c;以及sleep()的阻塞特性&#xff0c;同…