多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Oracle表空间监控SQL脚本与扩容方案

Oracle表空间监控SQL脚本与扩容方案 1. 项目概述作为一名Oracle DBA数据库巡检是我们日常工作中最基础也最重要的任务之一。表空间使用情况检查又是巡检中最关键的环节它直接关系到数据库的稳定运行。今天我要分享的这个SQL脚本是我在金融行业做了8年DBA后总结出来的表空间检查方案它能快速定位表空间使用率异常、自动识别需要扩容的表空间并给出精确的扩容建议。这个脚本最大的特点是实时性强直接查询数据字典视图获取最新表空间状态预警精准设置双重阈值警告阈值和紧急阈值建议明确不仅显示使用率还计算需要扩容的具体空间量兼容性好在Oracle 11g/12c/19c上均可运行2. 核心需求解析2.1 为什么表空间监控如此重要表空间是Oracle数据库存储结构的逻辑单元当表空间使用率达到100%时会导致应用无法写入新数据系统表空间满会造成数据库宕机临时表空间满会导致排序操作失败在我处理过的生产事故中约30%的数据库故障都是由表空间耗尽引起的。特别是SYSTEM、SYSAUX这些系统表空间一旦爆满后果不堪设想。2.2 巡检脚本需要解决的具体问题一个专业的表空间检查脚本应该能够区分永久表空间、临时表空间和UNDO表空间识别自动扩展和非自动扩展表空间的不同风险计算表空间碎片率预测表空间耗尽时间基于历史增长趋势生成可直接执行的扩容语句3. 脚本设计与实现3.1 核心数据字典视图脚本主要查询以下数据字典DBA_TABLESPACES -- 表空间基本信息 DBA_DATA_FILES -- 数据文件信息 DBA_FREE_SPACE -- 剩余空间信息 V$TEMPFILE -- 临时文件信息 DBA_TEMP_FREE_SPACE -- 临时表空间剩余 V$UNDOSTAT -- UNDO空间使用统计3.2 完整SQL脚本SELECT d.tablespace_name 表空间名, d.status 状态, d.contents 类型, d.extent_management 管理方式, d.allocation_type 分配类型, d.segment_space_management 段管理, NVL(a.bytes/1024/1024,0) 总大小(MB), NVL(a.bytes-NVL(f.bytes,0),0)/1024/1024 已使用(MB), NVL(f.bytes/1024/1024,0) 剩余空间(MB), ROUND(NVL((a.bytes-NVL(f.bytes,0))/a.bytes*100,0),2) 使用率(%), CASE WHEN ROUND(NVL((a.bytes-NVL(f.bytes,0))/a.bytes*100,0),2) 90 THEN 紧急 WHEN ROUND(NVL((a.bytes-NVL(f.bytes,0))/a.bytes*100,0),2) 80 THEN 警告 ELSE 正常 END 状态, CASE WHEN d.contents TEMPORARY THEN -- 临时表空间建议扩容语句 WHEN d.bigfile YES THEN ALTER TABLESPACE ||d.tablespace_name|| RESIZE || CEIL(a.bytes*1.2/1024/1024)||M; -- Bigfile表空间扩容20% ELSE ALTER DATABASE DATAFILE ||f.file_name|| RESIZE || CEIL((a.bytes*1.2)/1024/1024)||M; -- 数据文件扩容20% END 扩容建议 FROM dba_tablespaces d, (SELECT tablespace_name, SUM(bytes) bytes, MAX(file_name) file_name FROM dba_data_files GROUP BY tablespace_name) a, (SELECT tablespace_name, SUM(bytes) bytes, MAX(file_name) file_name FROM dba_free_space GROUP BY tablespace_name) f WHERE d.tablespace_name a.tablespace_name() AND d.tablespace_name f.tablespace_name() AND NOT (d.extent_management LOCAL AND d.contents TEMPORARY) UNION ALL -- 临时表空间单独处理 SELECT d.tablespace_name 表空间名, d.status 状态, d.contents 类型, d.extent_management 管理方式, d.allocation_type 分配类型, d.segment_space_management 段管理, NVL(a.bytes/1024/1024,0) 总大小(MB), NVL(a.bytes-NVL(f.bytes,0),0)/1024/1024 已使用(MB), NVL(f.bytes/1024/1024,0) 剩余空间(MB), ROUND(NVL((a.bytes-NVL(f.bytes,0))/a.bytes*100,0),2) 使用率(%), CASE WHEN ROUND(NVL((a.bytes-NVL(f.bytes,0))/a.bytes*100,0),2) 90 THEN 紧急 WHEN ROUND(NVL((a.bytes-NVL(f.bytes,0))/a.bytes*100,0),2) 80 THEN 警告 ELSE 正常 END 状态, -- 临时表空间建议: CREATE TEMPORARY TABLESPACE ||d.tablespace_name|| _TEMP TEMPFILE DATA SIZE ||CEIL(a.bytes*1.5/1024/1024)|| M REPLACE ||d.tablespace_name||; 扩容建议 FROM dba_tablespaces d, (SELECT tablespace_name, SUM(bytes) bytes FROM dba_temp_files GROUP BY tablespace_name) a, (SELECT tablespace_name, SUM(free_space) bytes FROM dba_temp_free_space GROUP BY tablespace_name) f WHERE d.tablespace_name a.tablespace_name() AND d.tablespace_name f.tablespace_name() AND d.extent_management LOCAL AND d.contents TEMPORARY ORDER BY 使用率(%) DESC;3.3 关键功能解析多表空间类型支持通过UNION ALL合并永久表空间和临时表空间的查询特殊处理UNDO表空间在Oracle 12c需要单独监控AUTOEXTEND智能阈值判断CASE WHEN ROUND(NVL((a.bytes-NVL(f.bytes,0))/a.bytes*100,0),2) 90 THEN 紧急 WHEN ROUND(NVL((a.bytes-NVL(f.bytes,0))/a.bytes*100,0),2) 80 THEN 警告 ELSE 正常 END这种阶梯式判断比固定阈值更实用自动生成扩容语句对Bigfile表空间生成ALTER TABLESPACE语句对普通表空间生成ALTER DATABASE DATAFILE语句对临时表空间建议新建替换方案4. 使用技巧与优化建议4.1 生产环境部署方案建议通过以下方式定期执行# 每天8:00和20:00各执行一次 0 8,20 * * * oracle_user /path/to/check_tablespace.sh # check_tablespace.sh内容 #!/bin/bash export ORACLE_HOME/u01/app/oracle/product/19.0.0/dbhome_1 export PATH$ORACLE_HOME/bin:$PATH sqlplus -S / as sysdba /script/check_tablespace.sql /log/tablespace_$(date %Y%m%d%H%M).log4.2 结果邮件报警配置在脚本中添加以下代码实现邮件报警SET SERVEROUTPUT ON SPOOL /tmp/tablespace_alert.log -- 执行主查询 check_tablespace.sql SPOOL OFF -- 只发送报警级别的结果 !grep -E 紧急|警告 /tmp/tablespace_alert.log | mailx -s 表空间报警 $(date %Y-%m-%d) dba-teamcompany.com4.3 历史趋势分析建议创建历史记录表CREATE TABLE tbs_monitor_history ( check_time TIMESTAMP, tablespace_name VARCHAR2(30), total_mb NUMBER, used_mb NUMBER, pct_used NUMBER, status VARCHAR2(10) );然后在脚本最后添加-- 保存本次检查结果 INSERT INTO tbs_monitor_history SELECT SYSTIMESTAMP, 表空间名, 总大小(MB), 已使用(MB), 使用率(%), 状态 FROM (/* 主查询语句 */); COMMIT;5. 常见问题处理5.1 查询不到临时表空间信息可能原因没有DBA_TEMP_FREE_SPACE视图的查询权限Oracle版本低于10g解决方案-- 使用替代查询 SELECT tf.tablespace_name, tf.bytes/1024/1024 total_mb, (tf.bytes-NVL(uf.bytes,0))/1024/1024 used_mb, NVL(uf.bytes,0)/1024/1024 free_mb FROM (SELECT tablespace_name, SUM(bytes) bytes FROM v$tempfile GROUP BY tablespace_name) tf, (SELECT tablespace_name, SUM(bytes_free) bytes FROM v$temp_space_header GROUP BY tablespace_name) uf WHERE tf.tablespace_name uf.tablespace_name();5.2 SYSTEM表空间异常增长典型症状SYSTEM表空间每天增长超过100MB使用率持续上升排查步骤检查AUD$表大小SELECT segment_name, bytes/1024/1024 MB FROM dba_segments WHERE tablespace_nameSYSTEM ORDER BY bytes DESC;检查回收站对象SELECT * FROM dba_recyclebin WHERE ts_nameSYSTEM;检查无效对象SELECT * FROM dba_objects WHERE statusINVALID AND tablespace_nameSYSTEM;5.3 表空间碎片化严重诊断方法SELECT tablespace_name, COUNT(*) fragments, MAX(block_id) - MIN(block_id) 1 total_blocks, SUM(bytes)/1024/1024 total_mb, (MAX(block_id) - MIN(block_id) 1 - COUNT(*)) / (MAX(block_id) - MIN(block_id) 1) * 100 fragmentation_pct FROM dba_free_space GROUP BY tablespace_name HAVING COUNT(*) 10 ORDER BY 5 DESC;处理方案对非自动管理的表空间ALTER TABLESPACE tablespace_name COALESCE;对自动管理的表空间建议重建-- 创建中转表空间 CREATE TABLESPACE tbs_temp DATAFILE DATA SIZE 10G; -- 移动所有段 EXEC DBMS_REDEFINITION.CAN_REDEF_TABLE(schema,table);6. 脚本增强建议6.1 添加ASM磁盘组空间检查对于使用ASM存储的数据库建议添加SELECT name 磁盘组, total_mb/1024 总大小(GB), free_mb/1024 剩余空间(GB), ROUND((total_mb-free_mb)/total_mb*100,2) 使用率(%) FROM v$asm_diskgroup;6.2 预测表空间耗尽时间基于历史数据预测WITH hist AS ( SELECT tablespace_name, check_time, used_mb, LAG(used_mb,1) OVER (PARTITION BY tablespace_name ORDER BY check_time) prev_used FROM tbs_monitor_history WHERE check_time SYSDATE-30 ) SELECT tablespace_name, AVG(used_mb - prev_used) daily_growth_mb, (total_mb - used_mb) / NULLIF(AVG(used_mb - prev_used),0) days_remaining FROM hist h JOIN (SELECT tablespace_name, SUM(bytes)/1024/1024 total_mb FROM dba_data_files GROUP BY tablespace_name) d ON h.tablespace_name d.tablespace_name GROUP BY h.tablespace_name, total_mb, used_mb;6.3 集成到OEM中创建OEM自定义指标BEGIN DBMS_SERVER_ALERT.SET_THRESHOLD( metrics_id DBMS_SERVER_ALERT.TABLESPACE_PCT_USED, warning_operator DBMS_SERVER_ALERT.OPERATOR_GE, warning_value 80, critical_operator DBMS_SERVER_ALERT.OPERATOR_GE, critical_value 90, observation_period 1, consecutive_occurrences 1, instance_name NULL, object_type DBMS_SERVER_ALERT.OBJECT_TYPE_TABLESPACE, object_name NULL); END; /
返回列表