$ mpstat 5
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 20 0 3592 3350 2338 1355 43 184 285 0 4578 9 6 1 84
1 19 0 304 465 283 2139 135 398 140 0 6170 9 6 1 85
2 25 0 352 507 295 2153 158 433 183 0 7508 12 7 1 81
3 26 0 357 513 302 2082 155 425 181 0 7460 12 7 0 81
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 3 0 3879 3773 2754 1832 61 322 339 0 3424 12 7 0 81
1 2 0 555 544 264 3040 197 670 112 0 4828 15 6 0 78
2 11 0 188 595 269 3141 219 738 121 0 5291 18 6 1 75
3 65 0 185 585 279 2660 211 673 110 0 5420 22 9 0 69
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 6 0 4028 3633 2620 1695 51 287 343 0 2857 12 8 0 80
1 7 0 150 545 265 3044 196 663 117 0 4374 14 4 0 81
2 14 0 226 602 279 2823 225 707 103 0 4715 22 4 1 73
3 2 0 125 600 282 2810 230 699 118 0 4665 18 4 0 78
mpstat可以确定每一个CPU都在花时间做什么:比如,分配给系统、用户、等待、空闲时间、系统调用、锁竞争、中断、错误、交叉调用。
有关每一列的详细含义请看mpstat(1M)的手册页。
2.3.3. iostat -使用iostat命令
iostat命令报告磁盘的使用情况。表格中的每一行代表一个磁盘的活动信息。常用的选项有这些:
选项
说明
N
按cXtYdZ格式指定磁盘。
X
报告扩展统计信息。
z
这个选项在Solaris 8操作环境中是新的。它使得在采样间隔中没有磁盘活动的那些行被省略掉,这样可以让输出简短一些并且突出那些有活动的磁盘。
p和P
报告分区前(per-partition)的I/O统计信息,当察看内存交换设备的时候有用。
E
对于找出产生错误的磁盘有用。
表1:iostat的选项
iostat也可以透过NFS报告磁盘活动,不过可能产生比较长的报告。
2.3.4. truss -你的朋友
truss(1M)工具执行制定的命令并且生成一个追踪记录,包括它执行的系统调用、接收到的信号、导致的机器错误(traps/interruptions——译者注)。
truss也可以用来追踪一个正在退出的进程。这是一个非常有用的工具,可以定位应用程序向内核请求了哪些变慢了或者是被过度使用的资源。
如果你不了解truss,那么可以看看手册页并且试一试。-m选项对于显示例如页面错误这样的错误非常有用。-c选项可以给出这样一个汇总信息:
系统调用
错误
信号
在每一类型系统调用上累计的时间
失败的系统调用数目
2.3.5. lockstat -资源竞争
内核锁可以保护对数据结构的多重更新,并且控制对诸如磁盘缓存、网络缓存、各种内核缓存这些资源的访问。
lockstat执行一个命令,报告在命令执行期间所有内核锁的活动情况,不论请求锁的是哪个进程或设备。请看lockstat(1M)的手册页。-s 10选项报告在每一个锁上进行竞争的内核线程栈。
2.3.6. trapstat -运行时的陷阱统计
trapstat是一个在运行着普通Solaris内核的UltraSPARC?处理器上提供运行时陷阱(trap)统计信息的工具。对于I-TLB和D-TLB未命中,trapstat能够可选地显示花在操作系统TLB未命中处理程序中的时间量。对于中断向量陷阱,trapstat能够可选地显示中断设备。
2.3.7. gprof -应用程序性能分析
对于C、C++和FORTRAN应用,试试用-xpg选项编译,并且在会产生性能问题的典型负载下运行这个程序。对生成的tmon.out文件执行gprof。这可以显示出该应用程序大部分的时间花在哪里。
Forte[tm] TeamWare (以前的Sun WorkShop[tm] TeamWare) 有很多有用的工具,比如用图形化的方式表示应用程序的时间都花在哪里的分析工具。要想了解更进一步的信息,请看Forte TeamWare文档以及Rajat Garg与Ilya Sharapov的Sun[tm] BluePrints书籍,应用程序的优化技巧:高性能计算(Techniques for Optimizing Applications: High Performance Computing).
2.3.8. proc工具
proc是一个利用/proc的特性来报告比如这样一些进程属性的实用工具:
pstack -调用栈
ptree -进程关系树
pfiles -打开的文件描述符列表
pldd -正在运行中的进程使用的动态链接库的列表
更多信息请看proc(1)的手册页。
3. 一些常见问题和一些建议
3.1. 64位的运算与容量能带来什么?
从性能的角度看,可以运行64位应用程序的能力有两大好处。首先是更大规模的问题能够利用更大的进程地址空间获得有效解决。其次是整数运算可以使用64位的寄存器和指令。
整体来说,因为代码中的指针和数据结构都更大了所以程序也稍微变大一些。反过来,这意味着CPU的缓存也很有可能没有足够的缓存行,那些在32位环境下就能够运行得很好的程序可能会稍微有一点慢。
内核线程栈是16Kb而不是8Kb,不过产生的效果经常是可以忽略的。
3.2. 空闲内存
检查一个Solaris系统以确定还有多少空闲内存一直以来都是个容易引起混淆的地方。
对于Solaris 8操作环境之前的版本,要想察看是否内存不够,是不依赖于"free"列或者"sr"列的。在"fr"列中的值并不能指示内存缺乏。页面缓存一直保留住页面以备再次需要用到它们。虚拟内存子系统只在需要的时候才收回内存。
在SunWorld文章与SUN性能与调整——Java[tm]与Internet(Sun Performance and Tuning - Java[tm] and the Internet)中这个题目已经被写了很多了。为了确定是否有内存不足的情况存在,同时检查第12列("sr",也就是扫描率)和交换分区的磁盘I/O流量(用iostat -P)。如果大量的I/O活动由文件系统产生并且需要运行页面扫描程序为I/O释放页面,"sr"列会有比较大的数值。
只有在空闲链表缩短到一个门限值 (lotsfree,以页面为单位)以下,pageout扫描程序才运行。任何非活动的并且没有被锁在内存中的进程或文件页面都可能被换出。freelist的大小看上去会缩短并保持在那个数值(lotsfree)。当freelist的数量下降到lotsfree门限以下的时候,页面守护进程将启动,扫描需要从页面缓存以及已退出和空闲的进程中回收的内存。没有办法能够让"空闲"值增长到这个门限以上很多,因为没有办法让页面扫描程序在这个门限之外回收内存。让页面保留在页面缓存中比把它们不必要地放到空闲链表中更有效率。
Solaris 8操作环境在segmap驱动程序内实现了一个更为有效的算法给I/O提供所需的页面。vmstat中的"fr"列确实反映了空闲并且没有被页面缓存所使用的内存。-p选项被加到vmstat中,用来给出更准确的页面调度行为细节。
对于单独的进程,pmap命令报告单独进程的内存空间布局情况(-x选项比较有用)。
3.3. 优先内存页面调度
优先内存页面调度是在Solaris 7操作环境引入的,并被向后移植到了Solaris 2.6操作环境(内核补丁105181-XX)和Solaris 2.5.1操作环境(内核补丁103640-XX)。这两个补丁的最近版本可以在SunSolve Online[sm]找到。
优先内存页面调度提供了一种改进的页面调度算法,从而在文件系统被使用的时候可以明显地改善系统的响应速度。优先内存页面调度引入了一个新增加的名词,cachefree。页面调度参数现在有这些:
minfree < desfree < lotsfree < cachefree
缺省情况下这个新功能在Solaris 2.5.1, 2.6, 和7操作环境下是关闭的,所以在有明显频繁内存调度的系统上允许这个功能就很重要。当priority_paging没有被允许的时候,cachefree被置为与lotsfree一样。当它被允许的时候,缺省情况下cachefree被设置为lotsfree的2倍。
调整这个参数趋于使工作站系统上窗口间切换起来更快,这对于需要从文件系统中把大文件读入内存的运行数据库的系统是很大的帮助。在通过文件系统执行大量I/O操作的系统上,对于拥有大量数据集的计算密集型任务,百分之几百的速度提高都曾经有过。
Solaris 8操作环境采用了一种不同的算法,消除了以前版本中页面扫描程序必须扫描内存以供给segmap驱动程序来存放I/O的限制因素。segmap不再需要的所有内存页面都被放到一个可以立即重用的链表中。不要在Solaris 8操作环境中设置priority_paging。并且,Solaris 8操作环境应该不需要手工调整虚拟内存参数,除了在大系统中把fastscan和maxpgio设置到高一些的值会有益。
更多关于优先内存页面调度的信息,请参考下面这些:
Sun性能、优先内存页面调度FAQ
文档17946: 在2.5.1+中针对优先内存页面调度的新的内核可调整项
3.4. 隐私的共享内存(ISM-Intimate Shared Memory)
ISM使得共享内存被锁在内存中,不能被换出(page out)。原本在一般情况下仅为单独进程创建的内存管理数据结构在一次性创建后就被所有进程共享。在Solaris 2.6操作环境下,还存在进一步的优化,内核试图寻找可以作为大的内存页面被用来映射共享内存的连续的4-Mbyte物理内存块。这大大降低了内存管理单元的开销。(请看性能与调整——Java[tm]与Internet(Performance and Tuning - Java[tm] and the Internet)的333页。)缺省情况下,类似Oracle、Informix、Sybase这样的应用程序使用一个特殊的标志来表明它们希望使用ISM。
ISM是一个关于虚拟内存实现方面,使得内核与硬件资源的使用更为有效的很重要的优化。 并且,ISM提供了把频繁用到的共享内存页面锁在内存中的方法。
在缺省情况下ISM是被允许的,不需要编辑/etc/system文件来打开这个特性。在具有当前补丁级别的内核上,关闭ISM会导致系统性能降级并且可能会挂起。而且在数据库的配置文件中,比如Oracle的init.ora文件中,不应该有use_ism=false,因为这样会关闭ISM。
3.5. 与共享内存有关的交换空间设置
想要理解与共享内存有关的交换空间配置,请看Adrian Cockcroft写的"清除在交换空间方面的混乱理解(Clearing Up Swap Space Confusion)"。
在设置交换空间大小的时候有两个主要的考虑,就是要有足够的:
内存,以避免在普通操作的时候就产生内存交换
交换空间,能够放下一次崩溃记录(crash dump)
3.6. 进程间通信(IPC)的参数
以下IPC参数值需要你的数据库系统管理员(DBA)确定。Sun解决方案中心不能给出实际IPC参数设置应该是怎样的建议。这些值依赖于应用程序。
在/etc/system的IPC参数设置中拼错字是非常可能的。这种错误会对应用程序带来严重的性能影响。要检查拼写错误,遍历/var/adm/messages寻找这样形式的消息:
genunix: [ID 492708 kern.notice] sorry, variable 'seminfo_semopn'
is not defined in the 'semsys'
这说明其中有一个拼写错误。用Grep找"sorry"。
Solaris 8操作环境比以前的版本改进了IPC参数的缺省值。
对于Solaris 2.6操作环境之前的版本,共享内存需要更多的交换空间(也就是“后援空间”)。用swap -l,将block数值除2就可以得到兆字节数。应该有至少两倍于已分配共享内存(shmmax)的交换空间。
这里是shmmax的缺省值和最大值:
缺省 最大
shmmax 1048576 (Meg) 4294967295 (4GB) 2.5.1, 2.6, 32位solaris 7
2147483647 (2GB) 2.5或更低
在Solaris 2.6操作环境下,shmmax和shmmin是无符号整型(32位)。在Solaris 7操作环境下,"32位"的shmmax和shmmin是无符号整型(32位)。在Solaris 7操作环境下,"64位"的shmmax 和shmmin是无符号长整型(64位)。在所有情况下,shmmni和shmseg都是有符号整型(32位)。表2汇总了这些命令和它们的类型。
命令
Solaris 2.6
32位
Solaris 7
32位
Solaris 7
64位
shmmax
无符号整型
无符号整型
无符号长整型
shmmin
无符号整型
无符号整型
无符号长整型
shmmni
有符号整型
有符号整型
--
shmseg
有符号整型
有符号整型
--
表2: 命令类型
shmmax限值共享内存段的最大大小,这是shmget(2)所能请求的最大值。它所控制的资源不是预先分配的,而是根据需要分配的。
在Solaris 7和8环境下,64位突破了4-Gbyte的限制。这个最大值是理论上的。实际的设置需要根据象内存、数据库大小、系统配置这些系统资源来确定。段的最大值本身(shmmax)是一个上限。
附加资源
A. 源自SunSolve Online[sm]关于IPC的文章
关于IPC参数话题,Sun解决方案中心已经写了大量的文章。这些文章可以在SunSolve Online[sm]获得。(合同客户可以访问附加的相关出版物。) 接下来是部分文章列表。
如果对/etc/system文件的修改似乎没有起作用,请看文档12824: sysdef -i 不报告设置在/etc/system中的IPC参数。
关于IPC参数的一般信息:
文档6328: 在2.X中所有关于共享内存参数的信息
文档2270: 理解信号灯、seminfo_信号灯信息
文档12075: 如何在你的系统中配置IPC信号灯和共享内存
文档5288: 如何通过adb确定IPC参数值
文档2273: 针对消息队列的内核调整参数
文档7241: 确定消息队列参数
关于调试问题:
文档12174: 怎样检查系统使用了多少共享内存
文档16985: 一个使用共享内存的进程已经终止,但是交换空间似乎没有被回收
B. SUN性能信息
The Sun Performance page提供了各种资源。
SunWorld在线专栏 1995-1999
Cockcroft, Adrian和Richard Pettit, SUN性能与调整——Java[tm]与Internet(Sun Performance and Tuning - Java[tm] and the Internet), Sun Microsystems Press, 1998. 这是一本有用的书,其中介绍的原则经受了时间的考验。不过很多内容在应用到当前的系统时需要带一点怀疑地去看待。
Garg, Rajat和Ilya Sharapov, 优化应用程序的技巧:高性能计算(Techniques for Optimizing Applications: High Performance Computing), Sun BluePrints, 2001. 这本书是在基于Sun UltraSPARC技术的平台上对计算密集型程序进行性能优化的实用指导,对于理解应用程序如何利用系统资源会有帮助。
Mauro, Jim和Richard McDougall, Solaris内部,核心内核架构(Solaris Internals, Core Kernel Architecture), Sun Microsystems Press, 2001. 这本书被认为是关于Solaris操作环境内部工作非常优秀的深入指南。
与性能和其他系统管理方面比如容量规划有关的,源自Sun Blueprints[tm] Programs的大量出版物。
C. 相关文章和书籍
ITWorld.com上源自UnixInsider的文集: Jim Mauro已经写了非常多介绍Solaris内核组件是如何工作的文章。如果你想知道“内幕”的话这是一个很好的起点。
Alomari, Ahmed, Oracle8i与UNIX性能调整(Oracle8i and UNIX Performance Tuning), Prentice Hall PTR, 2001. (注: 1999年的早期版本针对的是Solaris 2.6操作环境。)
关于作者
Karen Edwards已经在Sun工作了七年。她最早的几年是在加利福尼亚的SUN企业服务解决方案中心做外设与内核的支持。然后她为SunSolve Online[sm] program工作,帮助提供内容以及给客户做补丁问题的支持。目前她以作者身份为Sun[sm] Alert program工作。看看SunSolv网站上新的Sun Alert Notification集合吧。
Clive King在SUN的客户问题解决方案工程组工作。他擅长性能分析以及I/O子系统设备驱动方面的问题。作为一个Kepner Tregoe认证的ATS(Analytic Trouble Shooting)课程讲师,他在问题解决、决策制定和风险管理方面教授和实践Rational过程。