简介:这是一份面向Oracle DBA与运维人员的数据库巡检实践资料,针对日常巡检中检查项繁杂、缺乏统一脚本与解读标准的问题,提供可直接落地的脚本与配套手册。压缩包共2个文件,包含1个SQL脚本与1个docx操作手册,整体约109KB,其中SQL脚本用于批量采集数据库状态、配置与性能指标,docx手册则说明执行方法与结果解读思路。内容覆盖性能监控、空间管理、安全性检查、备份与恢复策略、参数调整、索引与表维护、日志与警报审查、架构版本确认及性能调优等方向,可帮助读者快速建立巡检流程、定位慢查询与空间隐患、核对权限与备份有效性。目前已有333人学习下载,适合初入门的DBA对照练习,也适合有经验的运维人员作为巡检清单与排错参考。
1. 一次凌晨告警让我重新翻出这套 Oracle 巡检脚本
凌晨两点被电话叫醒,某业务库的归档目录撑满,实例挂起。登上去一看,问题其实三天前就有征兆:alert.log里归档切换频率在悄悄变快,表空间使用率也在爬。当时没人盯,巡检靠人肉敲几条 SQL,漏了。那次之后我把手头这套「数据库巡检脚本及操作手册.zip」重新拆了一遍——里面就三样东西:Oracle_DB_Check.sql巡检脚本、数据库巡检脚本操作手册.docx操作手册,外加打包说明。它解决的不是什么高深问题,就是把 Oracle 日常巡检里那些「该看但总忘看」的指标,固化成一个能反复执行的 SQL 脚本,再配一份告诉你每段输出怎么读的手册。适合谁?手上管着几套 Oracle、没有成套监控平台、又不想每次巡检都从零写 SQL 的运维和 DBA。下面我按自己实际跑的方式,把它拆开讲清楚。
2. 拆开压缩包:脚本结构、执行入口与手册怎么配合
2.1 三份文件各自管什么
先把包解开,结构很朴素,没有嵌套目录:
| 文件 | 类型 | 作用 | 使用方式 |
|---|---|---|---|
Oracle_DB_Check.sql | SQL 脚本 | 巡检主体,按模块输出指标 | SQL*Plus / SQLcl 里@执行 |
数据库巡检脚本操作手册.docx | 文档 | 逐段解释输出含义、阈值、处置建议 | 先读再跑,或边跑边对照 |
| 打包说明 | 文本 | 版本、适用环境、执行前提 | 执行前扫一眼 |
这里有个容易被忽略的点:脚本和手册是配套的。脚本只负责「把数据捞出来」,手册负责「告诉你捞出来的数字意味着什么」。很多人拿到 SQL 直接跑,输出几百行结果看不懂,就丢一边了——问题不在脚本,在于没对着手册读。我的习惯是第一次先把手册通读一遍,把每个模块的判定阈值记下来,再跑脚本。
2.2 执行入口与前置检查
脚本是纯 SQL 查询集合,不涉及建表、不改数据,所以执行门槛很低。但低门槛不等于随便跑,前置检查还是要有。
# 1. 确认连的是目标库,别连错环境 sqlplus -S / as sysdba <<'EOF' select name, open_mode, database_role from v$database; select instance_name, host_name, version from v$instance; EOF这段先确认三件事:库名对不对、是不是主库(database_role)、版本号。巡检脚本里有些视图字段在不同版本上名字不一样,比如v$parameter和v$system_parameter的取舍,先知道版本能少踩坑。
# 2. 建一个只读巡检目录,输出落盘留档 mkdir -p /home/oracle/dbcheck/$(date +%Y%m%d) cd /home/oracle/dbcheck/$(date +%Y%m%d) # 3. 执行脚本,输出同时打印和存文件 sqlplus -S / as sysdba <<'EOF' | tee check_$(date +%H%M).log set linesize 200 set pagesize 1000 set trimspool on @/path/to/Oracle_DB_Check.sql EOF参数说明:linesize 200是因为巡检输出里有些字段(比如 SQL 文本、等待事件名)比较长,默认 80 会折行,读起来痛苦;pagesize 1000减少分页停顿;trimspool on去掉输出尾部空格,方便后续 diff。用tee是为了既在屏幕上看,又留一份带时间戳的日志——巡检的价值一半在「当下看」,一半在「和历史比」。
提示:脚本里如果包含
@嵌套调用其他 SQL 文件,确认相对路径。我一般把脚本和它依赖的文件放同一目录,用cd进去再执行,避免路径找不到。
2.3 手册的正确打开方式
手册不是让你从头读到尾的说明书,它更像「输出字典」。我的用法是:脚本跑完,输出按模块分段,遇到看不懂的指标名,回手册里搜对应段落。手册里通常会写清楚这个指标的正常范围、偏高偏低分别意味着什么、下一步该查什么。比如看到「临时表空间使用率 92%」,手册会提示去看是不是有大的排序操作、pga_aggregate_target是否偏小。这种「指标 → 原因 → 动作」的链路,才是手册真正的价值,比脚本本身还重要。
3. 巡检脚本覆盖的六个核心模块与判读方法
3.1 性能与等待事件:先看整体再钻细节
性能模块是巡检的重头。脚本一般会从v$sysstat、v$system_event、v$session_wait这些视图取数。判读顺序很关键:先看整体负载,再看等待集中在哪。
-- 整体负载:每秒逻辑读、物理读、事务数 select name, value from v$sysstat where name in ( 'session logical reads', 'physical reads', 'user commits', 'execute count' ); -- 非空闲等待事件 Top 10 select event, total_waits, time_waited_micro/1000000 as wait_sec, average_wait_micro/1000 as avg_ms from v$system_event where wait_class <> 'Idle' order by time_waited_micro desc fetch first 10 rows only;逻辑说明:第一段拿的是累计值,单看没意义,要和上次巡检的差值比,算出「这段时间每秒多少」。第二段按累计等待时间排序,wait_class <> 'Idle'过滤掉空闲等待(比如SQL*Net message from client这种不算问题)。average_wait_micro/1000转成毫秒,方便判断单次等待是否异常。
参数上要注意:fetch first 10 rows only是 12c 以后的写法,11g 得用rownum <= 10。这就是前面为什么要先确认版本。判读时,如果db file sequential read平均等待突然拉高,多半是索引读变慢或 I/O 压力;如果log file sync高,去看提交频率和 redo 写盘。
3.2 空间管理:表空间、数据文件与归档目录
空间是巡检里最容易出「硬故障」的地方,归档撑满直接挂库。脚本会查dba_tablespace_usage_metrics、dba_data_files、v$recovery_file_dest等。
-- 表空间使用率,按使用率倒序 select tablespace_name, round(used_space * 8 / 1024, 2) as used_mb, round(tablespace_size * 8 / 1024, 2) as total_mb, round(used_percent, 2) as used_pct from dba_tablespace_usage_metrics order by used_percent desc; -- 归档目录使用情况 select name, space_limit/1024/1024/1024 as limit_gb, space_used/1024/1024/1024 as used_gb, space_reclaimable/1024/1024/1024 as reclaimable_gb, number_of_files from v$recovery_file_dest;dba_tablespace_usage_metrics里的used_space单位是块,乘 8 再除 1024 换成 MB(假设 8K 块,块大小不同要改)。used_percent直接给了百分比,省事。归档那段重点看space_reclaimable——如果它很大,说明有大量已备份可删除的归档没清,是清理策略问题,不是空间真不够。
注意:临时表空间不在这两个视图里,得单独查
dba_temp_files和v$temp_space_header。手册里一般会单独列一段,别漏。
3.3 安全与权限:默认账户、权限分配、审计
安全模块查的是「有没有不该开的口子」。脚本通常扫dba_users(默认账户状态)、dba_role_privs、dba_sys_privs、dba_audit_trail。
-- 检查默认账户是否被锁定或过期 select username, account_status, expiry_date, default_tablespace from dba_users where username in ('SCOTT','HR','OE','PM','IX','SH','BI','MDDATA') order by account_status; -- 拥有 DBA 角色的用户 select grantee, granted_role, admin_option from dba_role_privs where granted_role = 'DBA' order by grantee;第一段盯的是那些示例账户,正常生产库它们应该是LOCKED或EXPIRED & LOCKED。如果哪个是OPEN,就是风险点。第二段看谁有 DBA 角色,admin_option = YES意味着这人还能把 DBA 转授给别人,权限扩散的口子,要重点确认。
判读原则:默认账户该锁的锁,DBA 角色该收的收。手册里会给一份「建议锁定账户清单」,但不同版本默认账户不一样,以实际查询结果为准,别照搬。
3.4 备份与恢复:验证可恢复性而非只看有没有备份
备份模块容易被做成「看一眼有没有备份任务」,但巡检真正该问的是「这份备份能不能恢复」。脚本会查v$rman_backup_job_details、v$backup_set、v$rman_status。
-- 最近 7 天备份任务状态 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, output_bytes/1024/1024/1024 as out_gb from v$rman_backup_job_details where start_time > sysdate - 7 order by start_time desc; -- 检查是否有备份集损坏或过期 select recid, status, completion_time, incremental_level from v$backup_set where status <> 'A' order by completion_time desc fetch first 20 rows only;第一段看status是不是COMPLETED,有没有FAILED。第二段status <> 'A'(A = Available)挑出异常备份集。这里有个血泪经验:备份任务显示成功,不代表备份集可用。有条件的话,定期做一次restore validate才是真验证,脚本只能做到「看状态」,恢复演练得单独安排。
3.5 参数与日志:SGA/PGA、归档模式、alert 扫描
参数模块查v$parameter和v$spparameter(spfile 里的值),重点看内存、归档、redo 相关。
-- 关键参数当前值 select name, value, isdefault from v$parameter where name in ( 'sga_target','pga_aggregate_target','memory_target', 'db_recovery_file_dest_size','log_archive_dest_1', 'processes','sessions','open_cursors' ) order by name;isdefault = TRUE说明这个参数没被显式设置过,用的是默认值。有些参数默认值在生产环境偏小,比如processes、open_cursors,值得关注。memory_target如果非零,说明开了 AMM,那sga_target、pga_aggregate_target就是自动管理的,别手动去调,会冲突。
日志部分脚本一般会提示你去查alert.log和v$diag_alert_ext(12c+)。巡检脚本没法替你读日志,但手册会告诉你搜哪些关键字:ORA-、Corrupt、Block recovery、Checkpoint not complete。我一般配合grep快速扫:
# 扫最近一天的 alert 日志异常 grep -E "ORA-|Corrupt|Checkpoint not complete" \ $ORACLE_BASE/diag/rdbms/*/*/trace/alert_*.log | tail -503.6 索引与对象维护:碎片、失效对象、统计信息
对象模块查dba_indexes、dba_ind_columns、dba_objects(失效对象)、统计信息新鲜度。
-- 失效对象 select owner, object_type, count(*) as cnt from dba_objects where status = 'INVALID' group by owner, object_type order by cnt desc; -- 统计信息超过 7 天未收集的表 select owner, table_name, last_analyzed, num_rows from dba_tables where last_analyzed < sysdate - 7 and owner not in ('SYS','SYSTEM','SYSAUX') order by last_analyzed asc fetch first 30 rows only;失效对象多,通常是编译依赖问题,@?/rdbms/admin/utlrp.sql重编译一遍。统计信息过期是慢查询的常见根因,尤其在大批量数据变更后。判读时注意:不是所有表都需要频繁收集统计信息,小表、静态配置表可以放宽,重点盯大表和频繁变更的表。
4. 避坑与排查:跑巡检脚本时最容易翻车的五件事
4.1 用业务账号跑,结果一堆视图查不到
现象:脚本执行到一半报ORA-00942: table or view does not exist,或者输出大量空行。 原因:dba_*、v$*视图需要SELECT ANY DICTIONARY或 DBA 角色权限,普通业务账号看不到。 解决:用sysdba或专门的巡检只读账号执行。如果公司不允许用 sysdba,提前建一个只读账号并授予SELECT ANY DICTIONARY、SELECT ANY TABLE(按需),别临时抓瞎。
4.2 输出没设 linesize,长字段折行读不了
现象:SQL 文本、等待事件名被截断或折成好几行,没法直接复制分析。 原因:SQL*Plus 默认linesize 80,巡检输出里长字段很常见。 解决:执行前set linesize 200(或更大),set trimspool on。如果输出要进 Excel 分析,用set markup csv on直接出 CSV 更省事。
4.3 拿单次快照当结论,误判性能问题
现象:看到某个等待事件累计时间很高,就断定有性能问题,结果白忙一场。 原因:v$sysstat、v$system_event是实例启动以来的累计值,单次快照反映的是「历史总和」,不是「当前状态」。 解决:巡检至少跑两次,间隔一段时间(比如 1 小时),用差值算速率。或者结合v$active_session_history(需诊断包授权)看近期活动。手册里如果只给了单次查询,自己补一个差值对比。
4.4 归档目录查了但没看可回收空间
现象:看到归档目录使用率 85% 就紧张,急着扩容。 原因:v$recovery_file_dest里space_reclaimable可能很大,说明有大量已备份可删的归档占着位置,清理即可,不用扩。 解决:先看space_reclaimable,再决定是清理还是扩容。清理用 RMANdelete archivelog all completed before 'sysdate-1',别手动rm,会破坏 RMAN 目录。
4.5 脚本版本和数据库版本不匹配
现象:脚本里用了新版本语法(如fetch first),在旧库上直接报错中断。 原因:脚本可能按较新版本写,11g 不认 12c 的语法。 解决:执行前确认版本,旧库把fetch first N rows only换成where rownum <= N。更稳妥的做法是脚本里用兼容写法,或者按版本准备两份。手册里一般会标注适用版本,别跳过那段。
5. 把巡检做成可对比的历史基线:我的固定动作
单次巡检只能看「现在」,真正有价值的是「和上次比」。我现在固定这么做:每次巡检输出按日期/实例名/归档,文件名带时间戳,然后用一个简单的 diff 脚本对比关键指标。
#!/bin/bash # compare_check.sh - 对比两次巡检的关键指标 PREV=$1 CURR=$2 echo "=== 表空间使用率变化 ===" diff <(grep -A100 "TABLESPACE" $PREV | head -30) \ <(grep -A100 "TABLESPACE" $CURR | head -30) echo "=== 失效对象数量变化 ===" grep -i "INVALID" $PREV | tail -5 grep -i "INVALID" $CURR | tail -5这个脚本很糙,但够用。核心思路是:把巡检输出当「时间序列数据」而不是「一次性报告」。跑上一个月,你就能看出哪些指标在缓慢爬升——表空间、归档量、失效对象数,这些趋势比单点阈值更早暴露问题。
再进一步,可以把关键指标抽出来入库。比如每次巡检把表空间使用率、归档使用率、Top 等待事件写进一张自建的监控表,用 SQL 做趋势查询:
-- 自建巡检历史表(一次性建) create table db_check_history ( check_time date, inst_name varchar2(30), metric_name varchar2(60), metric_value number, note varchar2(200) ); -- 每次巡检后插入关键指标 insert into db_check_history select sysdate, (select instance_name from v$instance), 'tablespace_used_pct:' || tablespace_name, used_percent, null from dba_tablespace_usage_metrics; commit;有了这张表,查「过去 30 天 SYSTEM 表空间使用率走势」就是一句 SQL 的事。这比每次翻日志文件高效得多,也是我从「人肉巡检」过渡到「半自动基线监控」的关键一步。
最后说个习惯:手册里给的阈值是参考,不是圣旨。不同业务库的合理水位不一样,交易库的表空间用到 80% 可能就该处理,报表库用到 90% 也许还能撑。我一般跑完头几次巡检后,结合自己库的实际情况,在手册上把阈值改成「本库适用值」,再传给同事。从那以后我每次拿到新的巡检脚本,都强制先跑三遍、对着手册标一遍阈值,再正式用——省得后面被误报折腾。希望这套拆解帮到你。
本文还有配套的精品资源,点击获取