CentOS 下基于 SQL*Plus 的 Oracle 性能监控方法
一 快速定位与单次 SQL 诊断
使用 SQL*Plus 的 AUTOTRACE 获取执行计划与执行统计,定位单条 SQL 的性能瓶颈。前置条件:为用户授予 PLUSTRACE 角色,并在用户 schema 创建 PLAN_TABLE(可由 $ORACLE_HOME/sqlplus/admin/plustrace.sql 创建)。常用设置与含义:
SET AUTOTRACE ON:显示执行计划 + 行源统计 + 实际行数SET AUTOTRACE TRACEONLY:仅显示统计,不输出结果集(适合大结果集)SET AUTOTRACE EXPLAIN:仅显示执行计划SET AUTOTRACE STATISTICS:仅显示统计SET TIMING ON:显示 SQL 执行总耗时(客户端计时)
示例:CONNECT hr/hr
SET AUTOTRACE TRACEONLY STATISTICS
SET TIMING ON
SELECT /*+ monitor */ COUNT(*) FROM orders WHERE order_date >= DATE'2026-01-01';
解读要点:关注 consistent gets、physical reads、redo size、elapsed time 等关键统计项,结合执行计划判断是否存在全表扫描、低效连接方式等。
提升 SQL*Plus 脚本采集效率的客户端参数(减少网络往返与输出开销):
SET ARRAYSIZE(建议 100–5000):一次从服务器获取的行数,网络良好时增大可显著降低往返次数SET LINESIZE:尽量接近实际列宽,避免过宽导致的内存拷贝与网络传输SET PAGESIZE 0:关闭分页标题,适合批量采集SET TRIMOUT ON / TRIMSPOOL ON:去除行尾空格,减少输出体积SET SERVEROUTPUT OFF:关闭 DBMS_OUTPUT 输出SET DEFINE OFF:关闭替代变量解析(脚本无 & 变量时)SET APPINFO OFF:减少客户端向服务器写入应用信息
示例:SET ARRAYSIZE 1000
SET LINESIZE 200
SET PAGESIZE 0
SET TRIMOUT ON
SET TRIMSPOOL ON
SET SERVEROUTPUT OFF
SET DEFINE OFF
SET APPINFO OFF
这些参数对大数据量脚本/监控采集尤为有效。
二 登录与连接慢的排查
sqlplus / as sysdba 或普通登录明显变慢时,可用 strace 定位系统调用层面的耗时点:strace -T -t -f -o strace_login.log sqlplus / as sysdba
关注输出行右侧的耗时(单位秒),例如 DNS 解析、读取配置文件、审计文件创建、读取消息文件、网络读写等。若发现某次调用耗时异常(如读取 oraus.msb 或网络 recvmsg 长时间阻塞),可据此进一步排查 DNS/hosts 配置、审计目录 I/O、Oracle Net 配置 等。三 持续监控与指标采集脚本
#!/bin/bash
DB_CONN_STR="user/pass@//host:1521/service"
OUT=redo_tps_$(date +%F_%H%M).txt
sqlplus -S "$DB_CONN_STR" <<'EOF' > "$OUT"
SET linesize 150 pages 100 feedback off verify off
COL dbname NEW_VALUE dbname
COL ts NEW_VALUE ts
SELECT name dbname, TO_CHAR(SYSDATE,'YYYY-Mon-DD HH24:MI:SS') ts FROM v\$database;
-- Redo 组与大小
COL bytes FORMAT 9,999,999,999,999
COL member FORMAT a60
SELECT group#, thread#, sequence#, members, bytes/1024/1024 size_MB, archived, status
FROM v\$log ORDER BY 1,2;
-- 近15分钟每小时 Redo 切换次数
TTITLE LEFT "Redo Switch times per hour" CENTER "&dbname" RIGHT "&ts"
SET term on
COL tps00 FOR 999 HEAD "00"
COL tps01 FOR 999 HEAD "01"
...
COL tps23 FOR 999 HEAD "23"
SELECT * FROM (
SELECT SUBSTR(year_np,1,8) ts_day,
SUBSTR(year_np,5,2) mon,
SUBSTR(year_np,7,2) day,
SUM(DECODE(SUBSTR(year_np,9,2),'00',cnt,0)) tps00,
...
SUM(DECODE(SUBSTR(year_np,9,2),'23',cnt,0)) tps23
FROM (
SELECT TO_CHAR(first_time,'YYYYMMDDHH24') year_np, COUNT(*) cnt
FROM v\$log_history
WHERE first_time > SYSDATE - 15/1440
GROUP BY TO_CHAR(first_time,'YYYYMMDDHH24')
)
GROUP BY SUBSTR(year_np,1,8), SUBSTR(year_np,5,2), SUBSTR(year_np,7,2)
)
ORDER BY ts_day;
EXIT
EOF
说明:
四 系统层面的配合监控