賽迪網 > IT技術 數據庫 > 精彩更新
  IT資訊搜索
 
IT產品搜索

Linux平台下監控Oracle數據庫性能

發佈時間:2007.01.25 04:55     來源:enet.com    作者:enet.com

在單一的應用環境或業務相對簡單的系統下, 系統性能問題, 瓶頸所在往往是不言自明, 解決問題的前提--定位問題是比較容易解決的, 但在一個複雜的應用環境下, 各應用系統對系統資源往往是一種共用和競爭的關係, 而且應用系統之間也可能存在著共生或制約的關係, 資源利益的均衡往往是此消彼長, 而這種環境下的應用系統一旦出現資源競爭, 系統的瓶頸往往難以斷定, 甚至會發生不同應用設計人員之間互相推諉責任的扯皮現象。本文僅就此問題對Linux平台下各應用系統對Oracle數據庫的使用情況作一探討。Oracle數據庫的TUNING不是一個可以一言以蔽的主題,本文無意概全,內容僅涉及問題的定位及各應用對數據庫資源的共用與競爭問題。

本文試驗及問題取證的環境:

RedHat6.1 Web server(Apache1.3.9+PHP4.0)+Client/Server(Pro*C)之Server端

RedHat6.2 + Oracle8.1.6.1.0

RedHat7.1 Web server(Apache1.3.20+PHP4.06) + Oracle8.1.7.0.0

為方便問題的討論, 應用系統已做簡化, 競爭方僅包括一個Pro*C的daemon程式作為C/S模式的服務端, 和由Apache+PHP所支援的WEB網站業務。

首先, 最簡單的情況莫過於單個SQL語句的分析, SQL語句的優化也是數據庫優化的一個最直接最立竿見影的因素。SQL語句的性能監控從監控工具來說大致可分為由高級語言提供和由Oracle本身提供, 高級語言以典型的應用C 語言和WEB開發語言PHP為例, C語言中可以用gettimeofday函數來在某一數據庫操作之前和之後分別獲取一個時間值, 將兩個時間值之差做為衡量該數據庫操作的效率, 在PHP中, 也可以用gettimeofday, 操作方法當然與C語言中有所不同。當然, PHP中也有其他一些函數可以達到同樣的時間精度, 關於時間精度的考慮, 不能簡單以大小衡量微秒級的時間數值, 因為時鐘中斷的時間間隔從根本上決定了時間計算所能達到的精度, 此外,作業系統本身對進程的時間片分配, 及進程切換的開銷等因素也在一定程度上影響時間數據的意義。所以, 以下時間的計算最理想的情況是對同一操作在盡可能避免緩存的情況下進行多次的迴圈操作,取總的時間值加以平均, 從而得到比較接近真實情況的時間值。C語言的例子:   

  
  #define TV_START 0 
  
  #define TV_END 1 
  
  int how_long(int cmd, char *res); 
  
  struct CMD_TIME{ 
  
  int times; 
  
  /* times occured within specified package number */ 
  
  struct timeval time; 
  
  /* total time consumed by the cmd */ 
  
  }; 
  
  void foo() 
  
  { 
  
  int id; 
  
  how_long(TV_START, NULL); 
  
  EXEC SQL WHENEVER SQLERROR CONTINUE; 
  
  EXEC SQL WHENEVER NOT FOUND CONTINUE; 
  
  EXEC SQL select user_id into :id from users where name='slimzhao';2; 
  
  how_long(TV_END, time_consume); 
  
  puts(time_consume); 
  
  } 
  
  int how_long(int cmd, char *res) 
  
  /* return value: -1 error, 0 sucess , res: 20 bytes is enough */ 
  
  { 
  
  static struct timeval before, after; 
  
  if(cmd == TV_START) { 
  
  gettimeofday(&before, NULL); 
  
  return 0; 
  
  } else if(cmd == TV_END) { 
  
  gettimeofday(&after, NULL); 
  
  if(res) { 
  
  if(after.tv_usec > before.tv_usec) { 
  
  sprintf(res, "%ld %ld", after.tv_sec - before.tv_sec, 
  
  after.tv_usec - before.tv_usec); 
  
  } else { 
  
  sprintf(res, "%ld %ld", 
  
  after.tv_sec - before.tv_sec - 1, 
  
  1000000 + after.tv_usec - before.tv_usec); 
  
  } 
  
  } 
  
  return 0; 
  
  } else { 
  
  return -1; 
  
  } 
  
  }
  

下面是一個PHP的例子(為簡化起見, 程式的錯誤檢查被忽略):

    
  include "/how_long.inc"; 
  
  how_long(TV_START, $timestr); 
  
  $conn = OCILogon("username", "password", "dblink"); 
  
  $stmt = OCIParse($conn, "select ID from users where name='slimzhao'"); 
  
  OCIDefineByName($stmt, ID, $id); 
  
  OCIExecute($stmt); 
  
  OCIFetch($stmt); 
  
  OCIFreeStatement($stmt); 
  
  OCILogoff($conn); 
  
  how_long(TV_END, $timestr); 
  
  echo "用戶ID: $id , 該操作消耗時間:$timestr
  "; 
  
  ?>
  

其中how_long函數的PHP版本如下:

  
  #耗費時間的字符串, 該函數本身的開銷不計入其中. 
  
  define("TV_START", 0); 
  
  define("TV_END", 1); 
  
  function how_long($operation, &$str) 
  
  #返回值: 0--成功, -1--傳遞了非法的參數. 
  
  { 
  
  global $before_SQL, $after_SQL; 
  
  if($operation == TV_START) { 
  
  $before_SQL = gettimeofday(); 
  
  return 0; 
  
  } else if($operation == TV_END) { 
  
  $after_SQL = gettimeofday(); 
  
  if($before_SQL["usec"] > $after_SQL["usec"]) { 
  
  $str = ($after_SQL["sec"] - $before_SQL["sec"] - 1)."秒". 
  
  ($after_SQL["usec"] + 1000*1000 -$before_SQL["usec"])."微秒"; 
  
  } else { 
  
  $str = ($after_SQL["sec"] - $before_SQL["sec"])."秒". 
  
  ($after_SQL["usec"]-$before_SQL["usec"])."微秒"; 
  
  } 
  
  } else { 
  
  return -1; 
  
  } 
  
  } 
  
  ?>
  

上面的數據庫操作開銷的計算僅限于對時間消耗的計算,對同時使用同一數據庫的其他應用軟體的影響,對磁片操作的頻繁程度,數據庫操作所採取的具體策略等等因素,都未考慮在內,高級語言也不可能提供這樣的參考數據。而數據庫本身提供的監測手段彌補了這一不足。最簡單的操作控制臺:

sqlplus 
  
  SQL> set timing on
  

將為每次執行的數據庫操作進行計時, 精度為1/100秒, 筆者對該功能的使用中發現其時間的計算也有一定的偏差。而且時間偏差很大,嚴格說來,已不屬於誤差的範圍,該歸錯誤了,下面是一個例子中得到的數據:

    
  [bash$] cat tmp.sql 
  
  set timing on 
  
  host date; 
  
  select count(*) from users; 
  
  host date; 
  
  SQL> @tmp.sql 
  
  Wed Dec 5 00:21:01 CST 2001 
  
  
  COUNT(*) 
  
  ---------- 
  
  1243807 
  
  Elapsed: 00:00:06.16 
  
  Wed Dec 5 00:21:05 CST 2001 
  
  

從系統的時間差來看, 為4秒左右, 但ORACLE卻報告了6.16秒!

如果說Oracle工具在時間計算上太差強人意的話,在SQL語句的執行方案上可算是對SQL語句如何執行的最權威的詮釋了。解讀這樣的資訊就需要對Oracle內部對SQL操作的過程有一定了解。

(T004)


[ 發表評論 ] 字體[  ] [ 列印 ] [ 進入博客 ] [ 進入論壇 ]  [ 推薦給朋友 ]
  相關文章
· 掌握Linux常用指令--奔向高手之路 (01-24) · 用Linux Command Shell模擬DOS命令 (01-24)
· Oracle中PL/SQL編程對系統性能的影響 (01-24) · 專家調優秘密之改善Oracle數據庫性能 (01-24)
· Linux作業系統應用軟體之多媒體概述 (01-23) · 靈活使用頭尾命令查看Linux系統文件 (01-23)
· Linux作業系統下列印工作命令簡介 (01-23) · Linux系統編程:用PHP執行Root命令 (01-23)
· Linux作業系統伺服器--FreeNAS初探 (01-23) · 監控和保護Linux作業系統下進程安全 (01-23)
  客戶需求反饋表
* 姓  名:
更多資料  了解方案  認識廠商
* 單位名稱:
* 聯繫電話:
* 電子郵件:
  賽迪推薦  
  手機·資費 ·新品·導購·評測·手機資費·寬帶
手機搜索  諾基亞 N73 MOTO Z6
  IT產品 ·筆記本·臺式機·伺服器·列印·投影
IT產品搜索 
  IT技術 ·開發·網管·安全·數據庫·作業系統
  博客·論壇 ·曾劍秋·項立剛·Java學習·網管