当前位置: 首页 > news >正文

分享一个Oracle表空间自动扩容与清理脚本

一、基础环境准备(首次执行)
-- 1. 创建表空间监控表(存储使用率、容量等信息)
create table monitor_tablespace_rate (tbs_name varchar2(50),        -- 表空间名total_gb number,              -- 总容量(GB)used_gb number,               -- 已使用(GB)free_gb number,               -- 剩余空间(GB)rate number,                  -- 使用率(%)maxextend_gb number,          -- 最大可扩展容量(GB)last_check_time date default sysdate  -- 最后检查时间
);
comment on table monitor_tablespace_rate is '表空间使用率监控表';-- 2. 创建审计日志清理记录表(跟踪清理操作)
create table audit_clean_log (clean_time date default sysdate,  -- 清理时间aud_size_before number,           -- 清理前AUD$表大小(GB)aud_size_after number,            -- 清理后AUD$表大小(GB)clean_result varchar2(100)        -- 清理结果
);
comment on table audit_clean_log is 'AUD$表清理日志';-- 3. 创建AWR快照清理记录表
create table awr_clean_log (clean_time date default sysdate,  -- 清理时间dbid number,                      -- 数据库IDmin_snap_id number,               -- 清理的最小快照IDmax_snap_id number,               -- 清理的最大快照IDclean_count number,               -- 清理的快照数量clean_result varchar2(100)        -- 清理结果
);
comment on table awr_clean_log is 'AWR快照清理日志';
二、核心存储过程(自动扩容+清理)
-- 创建存储过程:自动扩容表空间+清理审计日志及AWR快照
create or replace procedure proc_tbs_auto_manage
as-- 扩容相关变量v_tbs_name varchar2(50);v_rate number;v_file_name varchar2(200);v_new_file_name varchar2(200);v_file_num number;v_sql varchar2(500);-- 清理相关变量v_aud_size_before number;  -- AUD$表清理前大小(GB)v_aud_size_after number;   -- 清理后大小(GB)v_dbid number;             -- 数据库IDv_min_snap_id number;      -- 最小快照IDv_max_snap_id number;      -- 最大快照IDv_snap_count number;       -- 快照数量
begin-- ---------------------------- 步骤1:更新表空间监控数据-- --------------------------truncate table monitor_tablespace_rate;insert into monitor_tablespace_rate(tbs_name, total_gb, used_gb, free_gb, rate, maxextend_gb)select d.tablespace_name as tbs_name,round(d.tot_gb, 2) as total_gb,round(d.tot_gb - f.free_gb, 2) as used_gb,round(f.free_gb, 2) as free_gb,round((d.tot_gb - f.free_gb)/d.max_gb * 100, 2) as rate,  -- 使用率(%)round(d.max_gb, 2) as maxextend_gbfrom (-- 表空间总容量及最大可扩展容量select tablespace_name,sum(bytes)/(1024*1024*1024) as tot_gb,  -- 总容量(GB)sum(decode(maxbytes, 0, bytes, maxbytes))/(1024*1024*1024) as max_gb  -- 最大可扩展容量from dba_data_files group by tablespace_name) dleft join (-- 表空间剩余空间select tablespace_name,sum(bytes)/(1024*1024*1024) as free_gb  -- 剩余空间(GB)from dba_free_space group by tablespace_name) f on d.tablespace_name = f.tablespace_namewhere d.tablespace_name not like '%UNDO%'  -- 排除UNDO表空间and d.tablespace_name not like '%TEMP%';  -- 排除临时表空间-- ---------------------------- 步骤2:自动扩容表空间(使用率>85%时)-- --------------------------for tbs in (select tbs_name, rate from monitor_tablespace_rate where rate > 85) loopv_tbs_name := tbs.tbs_name;v_rate := tbs.rate;-- 获取该表空间现有数据文件信息(用于生成新文件名)select max(file_id), max(file_name) into v_file_num, v_file_name from dba_data_files where tablespace_name = v_tbs_name;-- 生成新数据文件路径(在原路径后加序号,如原路径/data/ts1.dbf→/data/ts1_2.dbf)v_file_num := v_file_num + 1;v_new_file_name := substr(v_file_name, 1, instr(v_file_name, '.', -1)) || v_file_num || '.dbf';-- 执行扩容:新增1GB数据文件,开启自动扩展v_sql := 'alter tablespace ' || v_tbs_name || ' add datafile ''' || v_new_file_name || '''' || ' size 1G autoextend on next 500M maxsize unlimited';execute immediate v_sql;-- 输出日志dbms_output.put_line('['||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')||'] '||v_tbs_name||' 扩容成功,新增文件:'||v_new_file_name);end loop;-- ---------------------------- 步骤3:清理SYSTEM表空间AUD$审计表(大小>5GB时)-- ---------------------------- 检查AUD$表当前大小(GB)select nvl(sum(bytes)/(1024*1024*1024), 0) into v_aud_size_before from dba_segments where segment_name = 'AUD$' and owner = 'SYS';if v_aud_size_before > 5 then  -- 阈值:超过5GB则清理-- 11g+推荐使用DBMS_AUDIT_MGMT清理(避免直接TRUNCATE)begin-- 初始化清理(若未初始化)dbms_audit_mgmt.init_cleanup(audit_trail_type => dbms_audit_mgmt.audit_trail_aud_std,default_cleanup_interval => 24);-- 执行清理dbms_audit_mgmt.clean_audit_trail(audit_trail_type => dbms_audit_mgmt.audit_trail_aud_std,use_last_arch_timestamp => false);-- 记录清理后大小select nvl(sum(bytes)/(1024*1024*1024), 0) into v_aud_size_after from dba_segments where segment_name = 'AUD$' and owner = 'SYS';-- 写入清理日志insert into audit_clean_log(aud_size_before, aud_size_after, clean_result)values(v_aud_size_before, v_aud_size_after, '清理成功');dbms_output.put_line('['||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')||'] AUD$表清理完成,清理前:'||v_aud_size_before||'GB,清理后:'||v_aud_size_after||'GB');exceptionwhen others theninsert into audit_clean_log(aud_size_before, aud_size_after, clean_result)values(v_aud_size_before, 0, '清理失败:'||sqlerrm);dbms_output.put_line('['||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')||'] AUD$表清理失败:'||sqlerrm);end;end if;-- ---------------------------- 步骤4:清理SYSAUX表空间AWR快照(保留最近7天,删除更早的)-- ---------------------------- 获取数据库IDselect dbid into v_dbid from v$database;-- 获取7天前的快照ID范围select min(snap_id), max(snap_id), count(1) into v_min_snap_id, v_max_snap_id, v_snap_countfrom dba_hist_snapshot where dbid = v_dbid and end_interval_time < sysdate - 7;  -- 保留最近7天if v_snap_count > 0 then  -- 存在需清理的快照begin-- 删除指定范围的AWR快照dbms_workload_repository.drop_snapshot_range(low_snap_id => v_min_snap_id,high_snap_id => v_max_snap_id,dbid => v_dbid);-- 写入清理日志insert into awr_clean_log(dbid, min_snap_id, max_snap_id, clean_count, clean_result)values(v_dbid, v_min_snap_id, v_max_snap_id, v_snap_count, '清理成功');dbms_output.put_line('['||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')||'] AWR快照清理完成,共清理'||v_snap_count||'个快照(ID范围:'||v_min_snap_id||'-'||v_max_snap_id||')');exceptionwhen others theninsert into awr_clean_log(dbid, min_snap_id, max_snap_id, clean_count, clean_result)values(v_dbid, v_min_snap_id, v_max_snap_id, v_snap_count, '清理失败:'||sqlerrm);dbms_output.put_line('['||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')||'] AWR快照清理失败:'||sqlerrm);end;end if;commit;
end;
/
三、定时任务配置(自动化执行)
-- 1. 创建定时任务:每小时执行一次存储过程
variable jobno number;
begindbms_job.submit(job => :jobno,what => 'proc_tbs_auto_manage;',  -- 执行的存储过程next_date => sysdate,  -- 首次执行时间:立即执行interval => 'sysdate + 1/24'  -- 执行频率:每小时一次);commit;
end;
/-- 2. 查看定时任务状态(记录Job号,用于后续管理)
select job, next_date, next_sec, failures, broken 
from user_jobs 
where what = 'proc_tbs_auto_manage;';-- 示例输出(Job号为123):
-- JOB        NEXT_DATE          NEXT_SEC      FAILURES B
-- ---------- ------------------ ------------- ---------- -
-- 123        2024-08-16 15:30:00 15:30:00      0          N-- 3. 手动执行任务(测试用)
begindbms_job.run(123);  -- 替换为实际Job号commit;
end;
/-- 4. 暂停定时任务
begindbms_job.broken(123, true);  -- 替换为实际Job号commit;
end;
/-- 5. 重启定时任务
begindbms_job.broken(123, false);  -- 替换为实际Job号dbms_job.run(123);commit;
end;
/-- 6. 删除定时任务(如需停用)
begindbms_job.remove(123);  -- 替换为实际Job号commit;
end;
/
四、脚本说明与扩展建议
  1. 功能说明

    • 自动监控表空间使用率,当使用率超过85%时,自动新增1GB数据文件并开启自动扩展;
    • 定期清理SYSTEM表空间中超过5GB的AUD$审计表(11g+安全清理);
    • 定期清理SYSAUX表空间中超过7天的AWR快照,保留近期性能数据。
  2. 扩展建议

    • 根据实际环境调整阈值(如扩容阈值85%、AUD$清理阈值5GB、AWR保留7天);
    • 新增邮件告警功能(通过UTL_MAIL),在扩容或清理失败时通知管理员;
    • 对临时表空间(TEMP)单独添加监控与扩容逻辑(参考数据文件逻辑,使用dba_temp_files);
    • 定期备份清理日志表(audit_clean_log、awr_clean_log),避免日志表过大。
  3. 注意事项

    • 执行脚本需SYSDBA权限;
    • 新增数据文件路径需确保数据库用户有写入权限;
    • 清理操作前建议备份关键数据(如AUD$表、AWR快照)。
http://www.dtcms.com/a/333967.html

相关文章:

  • 告别重复纹理:用Substance Designer构建UE5程序化地貌材质系统
  • 设计模式之静态代理
  • 基于Python3.10.6与jieba库的中文分词模型接口在Windows Server 2022上的实现与部署教程
  • 跑实验记录
  • HTTP 通信中的认证方式
  • macOS 中查看当前生效 shell 及配置文件的方法
  • Boost搜索引擎项目(详细思路版)
  • 数字化与人工智能的崛起及其社会影响研究报告
  • Navicat 为 SQLite 数据库设置密码指南
  • 学习游戏制作记录(制作系统与物品掉落系统)8.16
  • AT89C52单片机介绍
  • 《设计模式》代理模式
  • Day56 Java面向对象10 方法重写
  • 《Python学习之字典(一):基础操作与核心用法》
  • duiLib 实现鼠标拖动状态栏时,窗口跟着拖动
  • 拒绝造轮子(C#篇)使用SqlSugar实现数据库的访问
  • Windows MCP.Net:基于.NET的Windows桌面自动化MCP服务器深度解析
  • 玩转tokenizer
  • huggingface TRL中的对齐算法: KTO
  • PMP-项目管理-十大知识领域:成本管理-估算预算、控制成本、避免超支
  • 免费下载 Landsat 系列遥感影像——地理空间数据云
  • 《吃透 C++ 类和对象(中):const 成员函数与取地址运算符重载解析》
  • ALBEF/BLIP/BLIP2/Instruct BLIP/X Instruct BLIP
  • 从废弃到珍宝——旧物二手回收小程序系统的价值发现之旅
  • 曲面/线 拟合gnuplot
  • 新手向:Python列表、元组、集合和字典的用法对比
  • 谷歌手机刷机和面具ROOT保姆级别教程
  • 基于 LoRA的广义知识蒸馏(GKD)训练
  • 软考 系统架构设计师系列知识点之杂项集萃(125)
  • 给纯小白的 Python 操作 Excel 笔记