Oracle网络相关等待事件(转)

来源:互联网 发布:散热器优化仿真 编辑:程序博客网 时间:2024/06/15 08:51

Oracle有两个简单的网络相关等待事件,“SQL*Net message to client”和“SQL*Net more data to client”,一个是Message to Client,一个是More data to client。这二者有什么区别?

我们都知道Oracle有一个“预读取”,或叫“批量读”的功能,在SQLPLUS中可以用set arraysize 设置批量读的批大小。在SQLPLUS中默认值是15,也就是一次逻辑读默认读15行。
逻辑读的数据是发何发送给客户端的呢?这些数据要先被读取出来,暂时存入PGA的一块名叫Session Data Unit(简称SDU)的空间,再从SDU中通过网络发送给客户端。
SDU默认大小是8K,如果一次逻辑读读出的数据小于SDU大小,等待事件是“SQL*Net message to client”。如果一次逻辑读的数据大于SDU,数据将被分多次发送,这时将会有等待事件“SQL*Net more data to client”。具体来说,比如一次逻辑读的数据共10K,而SDU是8K,这将会产生一次“SQL*Net more data to client”,一次“SQL*Net message to client”。
关键问题是,数据已经占满SDU,这时加在数据块对应Buffer上的Buffer Pin锁不会释放,因为一次逻辑读还没有完成。数据通过网络发送,同时进程注册等待事件“SQL*Net more data to client”。发送完数据,继续逻辑读。直到这个块Buffer中的数据被读完、或者达到一个批大小,Buffer Pin锁才释放。
也就是说,Buffer Pin锁的持有,在有等待事件“SQL*Net more data to client”时,包含了网络的传输。这将导致Buffer Pin锁持有时间加长,有可能触发Buffer Busy Waits相关等待。
简单点说,批量读批大小超过SDU,将会有“SQL*Net more data to client”。没超过是“SQL*Net message to client”。而有“SQL*Net more data to client”,则说明进程将在块Buffer上持有更长时间的Buffer Pin锁。
SDU的大小,虽然默认是8K,但它是可调的。关于它,在文档“Net Services Reference”,第5章中,和文档“Net Services Administrator's Guide”第7章中,都有介绍。我将“Net Services Administrator's Guide”第7章中的粘下来,这一段还比较详细:
Session Data Unit (SDU) Size
Before sending data across the network, Oracle Net buffers and encapsulates data into the session data unit (SDU). Oracle Net sends the data stored in this buffer when the buffer is full, flushed, or when database server tries to read data. When large amounts of data are being transmitted or when the message size is consistent, adjusting the size of the SDU buffers can improve performance, network utilization, or memory consumption. You can deploy SDU at the client, the application Web server, and the database server.
说实话,这段英文看的我莫明其妙。很早之前我看这段话的时候,完全无法理解SDU的真正影响与作用。
SDU到底控制着什么,调节它的大小可以影响性能,影响什么性能?影响有多大?……,有N多的问题,文档中都没有提到。
没有提的原因无外乎有两个:一是信息垄断。只有内部人士可以掌握更多的信息,现代社会,信息就是金钱啊,相信Oracle有理由这么做的。
不过,这个调节参数是在sqlnet.ora等监听配置文件中调的,如果真是为了限藏它,干脆在文档中不提多好。
如果文档不提,用户用show parameter或查隐藏参数的视图,又找不有这么个东西。这样多好,除了内部人,其他人断无可能知道有这么个东西。
文档即然提了,又没讲清楚,我想还有另一个原因,就是写的文档的人也不知道这东西是干吗的,从以前版本的文档中直接照抄过来完事。

我原来在网上也了解过这个参数。一些个老外也有提到过这个东西,但都没有说清楚。
说白了SDU很简单,加大SDU大小,可以将“SQL*Net more data to client”等待事件变成“SQL*Net message to client”事件,减少Buffer Pin锁的持有时间,节省CPU。
使用gdb/mdb和Dtrace,非常简单就可以将SDU的意义发觉出来。我就是在一次调试Oracle时,发现进程运行代码中,一会注册“SQL*Net more data to client”等待事件,一会注册“SQL*Net message to client”等待事件。进一步分析,发现读取数据量超过8K时,就会有“SQL*Net more data to client”等待事件。然后在文档中查了一下,SDU的默认值是8K,修改了这个值,果然可以去掉“SQL*Net more data to client”等待事件。因此发现SDU的作用,过程也很简单。

-----

转从:http://www.itpub.net/forum.php?mod=viewthread&tid=1806151