Oracle 性能问题排查实战

Oracle 性能问题排查实战

适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07


1. 概述

性能问题排查方法论[1]:

步骤

  1. 现象收集
  2. 数据采集
  3. 瓶颈定位
  4. 根因分析
  5. 优化实施
  6. 验证监控

2. 现象收集

2.1 关键信息

  • 何时开始
  • 持续时间
  • 影响范围
  • 业务表现
  • 系统表现

2.2 问询

- 哪个业务慢?
- 何时开始?
- 数据量?
- 是否有变更?
- 服务器资源?

3. 数据采集

3.1 AWR 快照

-- 手动快照
EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT();

-- 查看快照
SELECT snap_id, begin_time, end_time 
FROM dba_hist_snapshot
ORDER BY snap_id DESC;

3.2 ASH

SELECT * FROM v$active_session_history
WHERE sample_time > SYSDATE - 1/24;

3.3 OS 监控

# CPU
top
vmstat 1

# 内存
free -m

# I/O
iostat -x 1

# 网络
sar -n DEV 1

4. 瓶颈定位

4.1 Top 5 等待

SELECT 
  event,
  total_waits,
  time_waited,
  average_wait,
  wait_class
FROM v$system_event
WHERE wait_class != 'Idle'
ORDER BY time_waited DESC
FETCH FIRST 5 ROWS ONLY;

4.2 等待类

SELECT 
  wait_class,
  SUM(time_waited) AS total_time
FROM v$system_event
WHERE wait_class != 'Idle'
GROUP BY wait_class
ORDER BY total_time DESC;

4.3 活跃会话

SELECT 
  sid,
  serial#,
  username,
  program,
  event,
  sql_id,
  seconds_in_wait
FROM v$session
WHERE status = 'ACTIVE'
  AND username IS NOT NULL;

5. 根因分析

5.1 CPU 高

-- 1. Top SQL by CPU
SELECT sql_id, cpu_time / 1000000 AS cpu_sec
FROM v$sql
ORDER BY cpu_time DESC
FETCH FIRST 10 ROWS ONLY;

-- 2. 会话 CPU
SELECT sid, serial#, username, program, value / 100 AS cpu_sec
FROM v$sesstat s, v$statname n, v$session ss
WHERE s.statistic# = n.statistic#
  AND s.sid = ss.sid
  AND n.name = 'CPU used by this session'
ORDER BY value DESC;

5.2 I/O 高

-- 1. Top SQL by reads
SELECT sql_id, disk_reads
FROM v$sql
ORDER BY disk_reads DESC
FETCH FIRST 10 ROWS ONLY;

-- 2. 数据文件 I/O
SELECT 
  df.file_name,
  fs.phyrds,
  fs.phywrts
FROM v$filestat fs, dba_data_files df
WHERE fs.file# = df.file_id
ORDER BY phyrds + phywrts DESC;

5.3 锁等待

-- 1. 阻塞会话
SELECT 
  blocking_session,
  sid,
  event,
  seconds_in_wait
FROM v$session
WHERE blocking_session IS NOT NULL;

-- 2. 锁详情
SELECT * FROM dba_waiters;

5.4 内存不足

-- 1. SGA
SELECT * FROM v$sgainfo;

-- 2. PGA
SELECT * FROM v$pgastat WHERE name LIKE '%allocated%';

-- 3. 命中率
-- Buffer Cache, Library Cache

6. 优化策略

6.1 SQL 优化

-- 1. 执行计划
EXPLAIN PLAN FOR <SQL>;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

-- 2. 加索引
-- 3. 重写 SQL
-- 4. HINT
-- 5. SQL Profile

6.2 索引优化

-- 1. 索引使用
SELECT * FROM v$object_usage;

-- 2. 索引碎片
ANALYZE INDEX idx_name VALIDATE STRUCTURE;
SELECT * FROM index_stats;

6.3 统计信息

EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'EMP', cascade => TRUE);

6.4 参数调优

-- 内存
ALTER SYSTEM SET sga_target = 8G;
ALTER SYSTEM SET pga_aggregate_target = 4G;

-- 并行
ALTER SYSTEM SET parallel_max_servers = 32;

7. 常见问题处理

7.1 数据库慢

-- 1. AWR 报告
@?/rdbms/admin/awrrpt.sql

-- 2. Top SQL
-- 3. 等待事件
-- 4. 资源使用
-- 5. 优化

7.2 锁等待

-- 1. 找阻塞会话
SELECT blocking_session, sid FROM v$session WHERE blocking_session IS NOT NULL;

-- 2. 查看 SQL
SELECT sql_text FROM v$sql WHERE sql_id = (SELECT sql_id FROM v$session WHERE sid = &blocking_sid);

-- 3. 杀会话
ALTER SYSTEM KILL SESSION 'sid,serial#';

7.3 ORA-01555

-- 1. 增大 Undo
-- 2. 增大 undo_retention
-- 3. 优化长查询

7.4 内存不足

-- ORA-04031
-- 1. 增大 Shared Pool
-- 2. 优化 SQL
-- 3. FLUSH SHARED POOL(临时)

8. 排查案例

8.1 案例:业务突然慢

1. 询问:15:00 开始慢
2. AWR:15:00-16:00 报告
3. Top 等待:enq: TX - row lock contention
4. 阻塞会话:sid=123 长时间未提交
5. 杀掉会话
6. 业务恢复

8.2 案例:CPU 100%

1. top 找进程
2. ASH 找 SQL
3. 执行计划:全表扫描
4. 加索引
5. CPU 下降

8.3 案例:磁盘 I/O 满

1. iostat 找热点
2. 数据文件 I/O
3. 大表查询
4. 分区或缓存
5. I/O 下降

9. 监控告警

9.1 关键指标

  • AAS(平均活跃会话)
  • CPU 使用率
  • I/O 等待
  • 锁等待
  • 表空间使用

9.2 告警阈值

CPU > 80% 持续 5 分钟
I/O 等待 > 50 ms
锁等待 > 60 秒
表空间 > 85%

10. 常见坑与排错

10.1 误判

- 治标不治本
- 临时优化掩盖问题
- 未根因分析

10.2 过度优化

- 加太多索引
- 改太多参数
- HINT 滥用

10.3 测试不足

- 未验证效果
- 副作用未发现

11. 最佳实践

  1. 方法论:系统化
  2. 数据驱动:AWR/ASH
  3. 瓶颈定位:精准
  4. 根因分析:彻底
  5. 小步优化:可验证
  6. 监控验证:效果
  7. 文档化:积累
  8. 预防为主:监控
  9. 测试充分:避免副作用
  10. 持续改进:循环

12. 参考资料

[1] Oracle Database Performance Tuning Guide 19c https://docs.oracle.com/en/database/oracle/oracle-database/19/tgdba/