Oracle数据库巡检脚本与操作手册:从采集到判定的完整落地指南

发布时间:2026/10/9 12:36:47
Oracle数据库巡检脚本与操作手册:从采集到判定的完整落地指南
简介这是一套面向Oracle DBA与运维人员的数据库巡检实践资料针对日常巡检中检查项繁杂、缺乏统一脚本与解读标准的问题提供可直接落地的脚本与配套手册。资源包共2个文件包含1个SQL脚本与1个docx操作手册压缩包约109KB其中SQL脚本用于批量采集数据库状态、配置与指标信息docx手册则说明执行方式与结果解读思路。内容覆盖性能监控、空间管理、安全性检查、备份与恢复策略、参数调整、索引与表维护、日志与警报审查等巡检维度并涉及执行计划分析与慢查询优化方向。目前已有333人学习下载适合初、中级DBA对照手册快速上手也便于有经验的运维人员将其作为巡检清单与排错参考提升巡检效率与结果一致性。1. 巡检脚本不是万能药Oracle 数据库巡检文档到底在解决什么问题很多团队第一次做 Oracle 数据库巡检都是从一份 Excel 检查表开始的表空间使用率、归档日志空间、等待事件、失效对象、备份状态一项项手工查。查完一轮两小时第二天数据全变了又得重来。更麻烦的是不同的人查出来的结论不一致有人觉得 85% 的表空间该扩容了有人觉得还能撑一周。Oracle 数据库巡检文档和配套的巡检脚本本质上解决的就是这个问题把「凭经验看」变成「按固定口径采、按固定阈值判、按固定格式出报告」。这套东西适合两类人一类是刚接手 Oracle 运维、需要一份能照着跑的检查清单的工程师另一类是团队里要统一巡检标准、把巡检结果沉淀成可对比历史记录的人。它不解决性能调优的根因分析也不替代 AWR 报告它解决的是「每天/每周固定时间点数据库整体状态是否偏离基线」这个层面的问题。巡检脚本负责采集操作手册负责告诉你每个指标怎么看、阈值怎么定、异常了先查什么。两者缺一不可只有脚本没有手册采出来的数字没人会判只有手册没有脚本执行成本高到没人愿意坚持。2. 巡检脚本的采集层怎么搭从单实例到 RAC 的最小可用方案2.1 先定采集口径再写 SQL写巡检脚本最容易翻车的地方是先写 SQL 再想「这个数代表什么」。正确的顺序反过来先列清楚要巡检的域每个域定一个判定口径再去找对应的视图。常见的巡检域和对应视图如下巡检域核心视图采集频率判定口径表空间容量DBA_TABLESPACE_USAGE_METRICS每日使用率 85% 预警归档日志V$RECOVERY_FILE_DEST、V$ARCHIVED_LOG每日空间使用率 80% 预警会话与进程V$SESSION、V$PROCESS每小时活跃会话数突增 50%等待事件V$SYSTEM_EVENT每日Top 5 等待事件变化对象状态DBA_OBJECTS每周失效对象数 0备份状态V$RMAN_BACKUP_JOB_DETAILS每日最近 24h 无成功备份作业状态DBA_SCHEDULER_JOBS每日失败作业数 0这张表就是巡检文档的核心骨架。脚本里每一个采集块都对应表里的一行。口径定不下来后面阈值就没法设。2.2 采集脚本的骨架一个可复用的 SQL 脚本模板下面是一个最小可用的采集脚本骨架用 SQL*Plus 的spool把结果输出成文本方便后续比对。脚本按「先环境、后容量、再状态」的顺序组织。-- inspect_main.sql -- 用法sqlplus -s / as sysdba inspect_main.sql set linesize 200 set pagesize 500 set feedback off set trimspool on -- 1. 实例基本信息 spool inspect_01_instance.txt select instance_name, host_name, version, startup_time, status, database_status from v$instance; spool off -- 2. 表空间使用率含临时表空间 spool inspect_02_tablespace.txt select d.tablespace_name, round(d.bytes/1024/1024, 2) as total_mb, round(nvl(f.bytes,0)/1024/1024, 2) as free_mb, round((d.bytes - nvl(f.bytes,0))/d.bytes*100, 2) as used_pct from (select tablespace_name, sum(bytes) bytes from dba_data_files group by tablespace_name) d, (select tablespace_name, sum(bytes) bytes from dba_free_space group by tablespace_name) f where d.tablespace_name f.tablespace_name() order by used_pct desc; spool off -- 3. 归档日志空间 spool inspect_03_archive.txt select name, round(space_limit/1024/1024,2) as limit_mb, round(space_used/1024/1024,2) as used_mb, round(space_used/space_limit*100,2) as used_pct from v$recovery_file_dest; spool off -- 4. 失效对象 spool inspect_04_invalid_obj.txt select owner, object_type, count(*) as cnt from dba_objects where status INVALID group by owner, object_type order by cnt desc; spool off -- 5. 最近备份状态 spool inspect_05_backup.txt select session_key, input_type, status, to_char(start_time,yyyy-mm-dd hh24:mi) as start_time, to_char(end_time,yyyy-mm-dd hh24:mi) as end_time from v$rman_backup_job_details where start_time sysdate - 2 order by start_time desc; spool off exit逻辑说明每个spool块对应一个巡检域输出文件名带序号方便按顺序拼接成日报。set trimspool on去掉行尾空格避免后续 diff 时产生大量无意义差异。set feedback off让输出干净不带「已选择 X 行」这类干扰信息。参数说明linesize 200是为了容纳较长的表空间名和路径pagesize 500保证单次输出不分页如果实例的dba_data_files记录很多可以把pagesize调到 1000。这个脚本用sysdba执行因为v$recovery_file_dest和v$rman_backup_job_details需要较高权限。生产环境建议单独建一个巡检账号授予SELECT_CATALOG_ROLE和SELECT ANY DICTIONARY避免直接用sysdba。2.3 把采集结果变成可对比的历史记录单次采集出来的文本看一遍就过去了。巡检真正的价值在于「和昨天比、和上周比」。最简单的做法是用 shell 把每次输出按日期归档再用diff做对比。#!/bin/bash # run_inspect.sh # 每日巡检入口脚本建议放在 crontab 里每天 07:00 执行 BASE_DIR/opt/db_inspect TODAY$(date %Y%m%d) YESTERDAY$(date -d yesterday %Y%m%d) mkdir -p ${BASE_DIR}/${TODAY} # 执行采集 sqlplus -s inspect_user/passwordorcl ${BASE_DIR}/sql/inspect_main.sql # 把 spool 文件移到当天目录 mv ${BASE_DIR}/sql/inspect_*.txt ${BASE_DIR}/${TODAY}/ # 和昨天对比表空间变化 if [ -d ${BASE_DIR}/${YESTERDAY} ]; then echo 表空间使用率变化 ${BASE_DIR}/${TODAY}/diff_tablespace.txt diff ${BASE_DIR}/${YESTERDAY}/inspect_02_tablespace.txt \ ${BASE_DIR}/${TODAY}/inspect_02_tablespace.txt \ ${BASE_DIR}/${TODAY}/diff_tablespace.txt fi # 检查是否有失效对象 if grep -q INVALID ${BASE_DIR}/${TODAY}/inspect_04_invalid_obj.txt; then echo [WARN] 存在失效对象请检查 inspect_04_invalid_obj.txt fi逻辑说明脚本先建当天目录执行采集再把结果归档。diff那一步是巡检从「一次性检查」变成「趋势监控」的关键。表空间一天涨 0.5% 和一天涨 5%处理优先级完全不同。参数说明BASE_DIR按实际环境改inspect_user/passwordorcl换成巡检账号和连接串crontab里建议加MAILTO或把输出重定向到日志文件否则出错时没有任何痕迹。如果实例是 RAC每个节点都要跑一遍输出文件名里带上节点名否则会互相覆盖。3. 操作手册怎么写才有用阈值、判定和处置动作3.1 阈值不是拍脑袋定的分三档来设巡检文档里最容易被忽略的就是阈值来源。写「表空间使用率超过 85% 告警」很容易但为什么是 85% 而不是 80% 或 90%合理的做法是分三档观察线使用率 70%记录趋势不告警。预警线使用率 85%发通知准备扩容。紧急线使用率 95%立即处理否则可能写失败。这三档不是固定的要根据表空间的增长速率反推。比如一个表空间每天涨 1%那 85% 到 95% 只有 10 天缓冲预警线就该提前到 75%。操作手册里应该写清楚「本环境阈值基于日均增长 X% 设定」而不是只给一个数字。3.2 每个巡检项都要有「异常了先查什么」巡检报告出来看到表空间 90%然后呢操作手册的价值就在这个「然后」。以表空间为例处置路径应该是先确认是数据增长还是临时段未释放查dba_segments按段大小排序。如果是数据增长确认最大可扩展空间查dba_data_files的autoextensible和maxbytes。如果还能自动扩展评估磁盘剩余空间如果不能扩展走扩容流程。如果是临时表空间查v$sort_usage看是否有大排序未释放。这四步写进手册新手也能照着做。只写「表空间不足请扩容」等于没写。3.3 巡检报告的结构一页纸能看完巡检报告不要做成几十页的 PDF没人看。推荐结构第一页实例基本信息 红黄绿三色总览。第二页异常项明细每项带当前值、阈值、建议动作。第三页与昨日/上周对比的趋势变化。红黄绿的判定规则要写死在脚本里不能靠人眼判断。比如任一表空间 95% 标红 85% 标黄其余标绿。这样报告出来扫一眼就知道今天要不要干活。4. 避坑与排查巡检脚本落地时最容易翻车的五个地方4.1 用 sysdba 跑巡检审计日志爆炸现象巡检脚本上线一周审计表空间暴涨DBA 被安全团队找上门。原因脚本用sysdba连接每次执行都产生审计记录加上v$视图查询频繁审计量远超预期。解决单独建巡检账号只授予SELECT_CATALOG_ROLE和SELECT ANY DICTIONARY并在脚本里显式用该账号连接。如果安全要求更严可以只授予具体视图的SELECT权限不用角色。4.2 spool 文件编码和换行符导致 diff 全是差异现象昨天和今天的表空间输出明明数字没变diff却显示每一行都不同。原因SQL*Plus 在不同平台上的换行符不一致或者linesize变化导致空格填充不同。解决脚本里固定set linesize、set trimspool on并在 shell 里用dos2unix统一换行符。如果还是不稳定可以在 SQL 里用rpad固定字段宽度让输出格式完全可控。4.3 RAC 环境下只跑了一个节点现象巡检报告显示会话数正常但业务反馈某个节点响应慢。原因脚本只在节点 1 执行v$session只反映当前实例节点 2 的会话和等待事件完全没采集。解决RAC 环境每个节点都要跑输出文件名加节点前缀报告里按节点分别展示。gv$session可以跨节点查但需要额外权限且性能开销更大日常巡检用单节点采集 汇总更稳妥。4.4 阈值写死在 SQL 里换环境就失效现象测试环境阈值 85%搬到生产环境后生产表空间常年 88%每天告警但没人处理最后告警被忽略。原因阈值硬编码在 SQL 的where条件里没有按环境区分。解决把阈值抽到一张配置表里脚本从表里读。比如建一张inspect_threshold表字段item_name、warn_value、critical_value不同环境初始化不同值。SQL 里用子查询关联改阈值不用改脚本。4.5 巡检脚本本身把数据库拖慢现象巡检脚本执行期间业务反馈出现短暂卡顿。原因脚本里查了v$sql或dba_segments全量数据这些视图在大型库上查询开销很大。解决限制查询范围比如dba_segments只查bytes 100M的段v$sql只查last_active_time sysdate - 1/24的记录。巡检脚本的执行时间控制在 30 秒以内超过就说明采集口径太宽需要收窄。5. 让巡检从「每天跑一次」变成「持续可信」的两个进阶技巧5.1 用基线对比替代固定阈值固定阈值的问题在于它假设所有数据库的「正常」是一样的。实际上一个 OLTP 库的活跃会话数常年 200一个报表库可能只有 20。更好的做法是建立基线连续采集两周算出每个指标的中位数和标准差之后巡检时看当前值是否偏离基线超过 2 个标准差。-- 计算表空间使用率的基线需要先有历史数据表 select tablespace_name, avg(used_pct) as avg_pct, stddev(used_pct) as std_pct, avg(used_pct) 2 * stddev(used_pct) as upper_bound from inspect_history_tablespace where collect_date sysdate - 14 group by tablespace_name;逻辑说明inspect_history_tablespace是每天采集结果入库后的历史表。upper_bound就是动态阈值超过它就告警。这样不同库有不同的判定标准误报率会明显下降。参数说明14 天是经验值太短基线不稳太长会掩盖近期变化。如果业务有周期性比如月末结算基线要按周期分段算不能混在一起。5.2 巡检结果入库用 SQL 做趋势分析把每次采集的结果写进历史表比看文本文件强得多。建表结构大致如下create table inspect_history_tablespace ( collect_date date, instance_name varchar2(30), tablespace_name varchar2(30), total_mb number, used_mb number, used_pct number );然后每天采集后insert进去。有了这张表就能回答「过去 30 天哪个表空间增长最快」「哪个库的失效对象反复出现」这类问题。巡检文档里可以附几条常用分析 SQL比如-- 过去 30 天增长最快的表空间 select tablespace_name, max(used_pct) - min(used_pct) as growth_pct from inspect_history_tablespace where collect_date sysdate - 30 group by tablespace_name order by growth_pct desc;这条 SQL 跑出来的结果比任何文字描述都更能说明问题。我自己的习惯是每周一看一次这个排名排第一的表空间优先处理。巡检脚本和操作手册最终要落到「有人看、有人判、有人动」这个闭环上否则采再多数据也只是硬盘上的文本。希望帮到你。本文还有配套的精品资源点击获取