SQL* Net message to client 和SQL * Net more data to client等待事件

eric0435發表於2013-10-27

什麼是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配置正確

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26015009/viewspace-775110/,如需轉載,請註明出處,否則將追究法律責任。

相關文章