什么是SQL* Net message to client 和SQL * Net more data to client等待事件?
SQL * Net message to client等待事件发生在当一个服务器进程已经发送数据或消息到客户端并正等待回复的时候.这个等待时间是等待从TCP(Transparent Network Substrate)等待响应的时间.这个等待事件通常被认为是一个空闲等待事件,它被看作是服务器进程正在等待其它的回复.在性能调整中如果个别的等待时间很高那么在服务器进行调整的可能性不大而是在其它方面进行调整,如果总的等待时间很高但个别的等待时间较小那么等待可能是由于收集数据所引起的
对于SQL * Net more data to client等待事件,oracle使用SDU(session data unit)会话数据单元将SDU缓存写入到TCP套接字缓存中.如果数据比会话数据单元的初始大小大那么数据需要被多次的发送.如果有大量的数据被发送然后在每批数据发送后这个会话将会等待’SQL * Net more data to client’等待事件.
oracle net允许通过参数SDU(会话数据单元)和TDU(传输数据单元)来控制数据包的大小.它们分别控制’Session’和’Transport’层的缓存大小.TDU在数在oracle net v8.0中已经被废弃.
数据包大小
SDU是会话数据单元它控制着发送和收接数据的大小.SDU值的范围从512到31767字节缺省大小是2048bytes(这个值依赖于数据库的版本).为了最小化oracle net 数据包头的开销和消息碎片.设置SDU的大小作为一个多重的MSS(网络协议被使用的最大段大小).TDU是最大传输单元(MTU)
计算MSS:
MSS=MTU-TCP header size-IP header size
MTU(or TDU)-1500 bytes for Ethernet
TCP-20 bytes
IP-20 bytes
对于以太网的TCP/IP协议的MSS这里还有1460bytes,传输网络底层(TNS)头是额外的30bytes.所以能被发送的数据大小是1430 bytes.国灰TNS头被包含在TCP数据包中,所以在SDU中包含了TNS头的大小.对于实例来说,如果你有5720 bytes的数据要发送,它将分成四个TCP包(5720/1430=4)那么这将有四个TNS包要发送.对于每个包的TNS头要增加30 bytes(1430+30=1460),增加TCP/IP头的大小40 bytes,你将得到四个完全以太网包的发送大小(1460+40=1500).为了得到TCP/IP的最佳效果,应该要配置TCP发送和接收的缓存大小.
TDU是传输数据单元它控制着传输网络层发送和读取数据的大小.TDU缺省的大小是32767 bytes在oracle v8.0和以后的版本中不用配置.TDU值的范围从0到32767.如果不设置TDU那么它将使用缺省值.例如TDU的值如果为1,这将造成在网络层读写数据只有1 bytes.
在SQL *Plus中的arraysize参数决定每一次网络传输获取多少行记录.
对于一个SDU大小大于2048的连接,客户端和服务端必需指定一个较大的SDU值.数据库将选择两者中最低的哪一个.
SDU配置
为了配置SDU,要确保SDU值出现在所有相关的地方
1.客户端的TNSNAMES.ora:这个参数必需出现在DESCRIPTION子句中:
TEST =
(DESCRIPTION =
(SDU=8192)
(TDU=8192) < – 8.0 TDU position
(ADDRESS =(PROTOCOL = TCP)(HOST = jy)(PORT = 1521))
(CONNECT_DATA = (SID = V920)))
LISTENER.ora:这个参数必需出现在SID_DESC子句中:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SDU = 8192) (TDU = 8192) (SID_NAME = V920)
(ORACLE_HOME = /oracle/product/9.2.0)))
2.从oracle的9.0.1.5,9.2.04和10.2.0.1开始这个缺省的SDU大小对于连接改成使用动态注册了.
在SQLNET.ora中
DEFAULT_SDU_SIZE = 8192
上面的参数,SDU可以在客户端的sqlnet.ora文件和服务端的sqlnet.ora文件中进行设置而不用连接描述符
对于共享服务器的配置
如果使用共享服务器,在DISPATCHERS参数中设置SDU的大小:
DISPATCHERS=”(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP))(SDU=8192))”
对于oracle8使用MTS_DISPATCHERS参数
为了确保SDU的大小与客户端配置的大小相匹配,服务端将选择较小的一个.有些客户端的SDU必需要小于服务端的SDU值
怎样诊断SQL* Net message to client 和SQL * Net more data to client等待事件
诊断SQL* Net message to client 和SQL * Net more data to client等待事件最好的方法就是运行10046跟踪.
sys@JINGYONG> oradebug setmypid 已处理的语句 sys@JINGYONG> alter session set events '10046 trace name context forever,level 1 2'; 会话已更改。 sys@JINGYONG> select * from scott.emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-12月-80 800 20 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7566 JONES MANAGER 7839 02-4月 -81 2975 20 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7782 CLARK MANAGER 7839 09-6月 -81 2450 10 7788 SCOTT ANALYST 7566 19-4月 -87 3000 20 7839 KING PRESIDENT 17-11月-81 5000 10 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7876 ADAMS CLERK 7788 23-5月 -87 1100 20 7900 JAMES CLERK 7698 03-12月-81 950 30 7902 FORD ANALYST 7566 03-12月-81 3000 20 7934 MILLER CLERK 7782 23-1月 -82 1300 10 已选择14行。 sys@JINGYONG> alter session set events '10046 trace name context off'; 会话已更改。 sys@JINGYONG> oradebug tracefile_name /u01/app/oracle/diag/rdbms/jingyong/jingyong/trace/jingyong_ora_2745.trc
使用tkprof对跟踪文件格式化后可以得到以下内容:
select * from scott.emp call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.03 0.04 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.01 0.02 6 8 0 14 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.05 0.07 6 8 0 14 Misses in library cache during parse: 1 Optimizer mode: ALL_ROWS Parsing user id: SYS Rows Row Source Operation ------- --------------------------------------------------- 14 TABLE ACCESS FULL EMP (cr=8 pr=6 pw=0 time=94 us cost=3 size=532 card=14) Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ SQL*Net message to client 2 0.00 0.00 Disk file operations I/O 1 0.00 0.00 db file sequential read 1 0.01 0.01 db file scattered read 1 0.00 0.00 SQL*Net message from client 2 0.00 0.01 ********************************************************************************
我们可以看到单个SQL*Net message to client等待事件通常是非常短的(在上面的例子总的等待小于1毫秒).等待时间被记录为0毫秒,这个等待事件不会造成性能问题.
如果当发现这个等待事件的等待时间不同寻常的高.例如在statspack或awr报告中出现在top等待事件中,那么可以通过跟踪程序或sql来进行调整
潜在的几种解决方法
1.SDU大小
记住SQL* Net message to client等待事件通常不是一个网络问题,它基于TCP包的吞吐量.第一阶段发送SDU缓存的内容将其写入TCP缓存中,第二阶段就是等待SQL* Net message to client等待事件,这个等待与下面的原因有关:
orace sdu大小
返回给客户端的数据大小
一种解决方法增加SDU的大小,增加大小的方法上面提到过
2.数组大小
如果程序正在处理大量数据库,可以考虑在程序中增加数组的大小.如果使用较小的数组来获取数据那么查询将会执行多批次的调用,它们的每一次调用都会等待SQL* Net message to client等待事件.使用较小的数组来处理大量的数据SQL* Net message to client等待事件会大量增加.
如果从sqlplus中运行查询,在sqlplus中可以使用”set”命令来增加数组的大小
set arrayzie 1000
从10046跟踪文件中可以从fetch行看到获取的缓存大小或数组大小
FETCH #6:c=1000,e=793,p=0,cr=1,cu=0,mis=0,r=13,dep=0,og=1,plh=3956160932,tim=1381994001395851
上面的r=13指示数组大小是13,13可能太小了所以如果SQL* Net message to client等待事件时间长的话就可考虑增加
数组的大小
3.TCP
调整TCP连接确保TCP配置正确
Thank you, I’ve recently been loioking foor info approximately this topic forr a long time and yours is the greatest I’ve came upon so far.
However, what about the conclusion? Are youu positive concerning thhe supply?
This is really interesting, You’re a very skilled blogger.
I’ve joined your feed and look forward to seeking more of your
excellent post. Also, I’ve shared your web site in my social networks!