当在Linux/Unix中遇到CPU使用很高时, 我们会用"top"或"prstat"命令来查找那个进程序点用了最多的CPU.
然后再根据操作系统的进程号, 关联V$PROCESS和V$SESSION来找出是那个Oracle会话引起了问题, 这是一个很有用的解决突然性的性能问题的方法.
但这只能根据CPU或占用的内存的大小来排序, 却不能按IO等其他指标来查找. 如果我们能在Oracle中找出那些会话引起了最多的磁盘读或生成了最多的日志,
将是很有用的信息. 为此我写了一个比较方便的工具:OTop.
OTop可以在10秒钟内告诉你这些问题的答案. 在Oracle中收集了会话级的统计值, 这对于性能调整是很有用的.
我们只需要关联V$SESSION和V$SESSTAT, 并计算两个时间点的差值进行降序排列, 就生成了对调优很有用的信息, 可以很容易找出那些会话,
引起了最多的逻辑读或物理读. 我已经用OTop在很短的时间内发现了不少性能问题. 并且用这个工具可以增加你对数据库的了解,
了解不同的时间你的数据库都在做什么. 我只化了几个小时完成了这个工具, 却发现是很有帮助的.
1, 免费下载
2, 安装及命令行选项
OTop是一个很有用的小工具, 要运行必需安装Oracle客户端, 并配好与服务器的连接字符串, 或在服务器上直接运行.
我一般建一个ANYSQL的用户, 具有"CREATE SESSION","ALTER SESSION"和SELECT_CATALOG_ROLE的角色权限.
C:\MYDUL\utility>dcba -1 -h
AnySQL.net OTop for Oracle, Release 3.0.0
(c) Copyright Lou Fangxin (AnySQL.net) 2004-2006, all rights reserved.
Usage: dcba -[option][value]
-{1|2|3|4} 1:OTop, 2:OPMon, 3:OTune, 4:OLoad
-H print help message
-U Oracle user name with select_catalog_role.
-S tns alias if remote database.
-C number of top SQLs displayed (min 5, max 16384)
-Q run in quiet mode, write to file
-D directory of output file in quiet mode
-O Order by (GETS/CPUT/DISK/SORT/WAIT/REDO/EXEC)
对于OTop, 默认的时间间隔是10秒, 输出按逻辑读降序来排列, 在输出20次后会退出, 也可以按"Control+C"来中途退出,
并可以使用"-o"选项来指定其他的排序方式. 在这儿我预先指定了一些简写:
- DISK = physical reads
- GETS = consistent gets
- EXEC = execute count
- CPUT = CPU used by this session
- SORT = sorts (memory)
- REDO = redo size
- WAIT = enqueue waits
- SENT = bytes sent via SQL*Net to client
可以用-o"统计名称"来指定其他指标.
3, 如何连接数据库?
如果你在SQL*Plus中用"sqlplus anysql/anysql@prod"连接的话, 那么运行OTop的命令是"dcba -1 -uanysql/anysql -sprod".
找出物理读最多的会话? 请执行"dcba -1 -uanysql/anysql -sprod -odisk ".
找出产生Redo最多的会话? 请执行 "dcba -1 -uanysql/anysql -sprod -oredo ".
按其他任意统计名称排序的会话? 请执行" dcba -1 -uanysql/anysql -sprod -o"统计名" ".
4, 输出例子
Top Session ( 16:54:47 - 16:54:53 ) Order by gets
-Statistics-------------------------------------------------------------------------------------
1 0 logons cumulative 735 122 opened cursors 4 0 user commits
8567 1427 user calls 826 137 CPU this session 0 0 enqueue waits
48 8 db block gets 165K 27K consistent gets 2739 456 physical reads
55 9 db block changes 0 0 consistent change 0 0 physical writes
0 0 DBWR buffers scan 2206 367 free buffer req 1 0 free buffer ins
0 0 CR blocks created 17K 2959 redo size 37 6 redo blks written
180K 30K Table scan rows 1125K 187K Table fetch rowid 744 124 Total parse count
1 0 Hard parse count 3151 525 execute count 8025K 1337K bytes via SQL*Net
529 88 sorts (memory) 0 0 sorts (disk)
-Get/S--Mis/S--Slp/S-IGet/S-IMis/s-SGet/S--Latch------------------------------(Top Latch)-------
18K 980 17 0 0 963 library cache
5851 143 0 0 0 143 row cache objects
7748 74 1 0 0 72 shared pool
9475 35 1 0 0 34 library cache pin
6248 26 0 0 0 26 library cache pin allocation
---SID-Serial--VALUE--VAL/S----PCT-----PrevSQL------CurSQL---Host-------------------------------
1366 40755 61K 10K 37.28 2277403718 0 hostname (username)
2031 1881 23K 3931 14.37 2277403718 2277403718 hostname (username)
706 12041 23K 3926 14.35 2277403718 2277403718 hostname (username)
2677 36301 22K 3768 13.77 2277403718 2277403718 hostname (username)
1700 64805 10K 1803 6.59 0 1925564194 hostname (username)
700 44726 2386 397 1.45 0 0 hostname (username)
864 45587 799 133 0.49 755074748 3481933384 hostname (username)
141 51698 772 128 0.47 0 3093740634 hostname (username)
260 47501 711 118 0.43 0 0 hostname (username)
604 50029 645 107 0.39 3093740634 3093740634 hostname (username)
1086 42825 587 97 0.36 0 3093740634 hostname (username)
2400 10629 544 90 0.33 3093740634 3093740634 hostname (username)
683 23077 463 77 0.28 0 3093740634 hostname (username)
2124 7060 415 69 0.25 3093740634 0 hostname (username)
383 60489 400 66 0.24 2254641363 2254641363 hostname (username)
1993 47707 365 60 0.22 0 0 hostname (username)
18 21110 338 56 0.21 0 0 hostname (username)
441 59330 334 55 0.20 97002241 2170752115 hostname (username)
2313 33672 315 52 0.19 0 1907819273 hostname (username)
98 27416 312 52 0.19 0 0 hostname (username)
这里面显示的值皆为两个时间点之前的差值, 第一部份是系统级统计信息的变化,
第二部份是LATCH的信息, 第三部份是Top会话信息.
在这个例子中, 你可以看到最上面的4个会话贡献了大约全部的逻辑读,
表示这几个会话正在跑的SQL可能是有问题的, 可以根据OTop中给出的SQL的HASH值找到相应的SQL文本,
并进行优化.
你会发现这是一个不错的工具.
5, 备注
OTop本身并不会占用较多的资源, 我在2000多个会话的机器上进行测试, OTop中的SQL的运行时间不到一秒.