閱讀722 返回首頁    go 京東網上商城


Delphi 程序錯誤寫法造成Oracle數據庫負載異常

本文講的是Delphi 程序錯誤寫法造成Oracle數據庫負載異常

作者介紹

image
張洪濤 富士康 DBA

注意:本文涉及的問題在9i的環境中測試的,經驗證,同樣適用於11g.

在用Toad的SGA Trace工具監控我們的Oracle 9.2.0.8 Patch 31古董數據庫時發現一條奇怪的SQL,它占到數據庫整體邏輯讀50%以上,SQL如下:


image

image

image

這條SQL單次執行邏輯讀不到900,但執行非常頻繁,它本意想查詢HRM.ORGANIZATION表的表與索引信息。

程序員應該不會特意寫這種SQL,那它到底來自哪裏?

通過MODEL_NAME,找到SQL對應的Session,並做10046 Trace分析這條SQL與
SELECT departmentname FROM hrm.organization WHERE departmentid=:1交替執行。DB層麵已經很難再有什麼有價值線索,隻有請開發提供源碼分析。

這個程序使用Delphi7開發,很快開發將源碼發來,代碼如下:


image

image

分析Delphi程序在執行以下語句時調用了異常SQL。

ADOQuery2.SQL.Add(str_4);
ADOQuery2.Open;
ADOQuery2.First;

程序員正確使用了Delphi ADOQuery控件添加了SQL文本,並調用Open方法執行SQL,但為何要再調用First方法?

ADOQuery的First方法本意為定位到結果集的第一條記錄。因為departmentid為主鍵,SELECT必返回一條記錄,此步應為多餘。請開發人員屏蔽掉ADOQuery2.First;再上線新版程序觀察。

第二天這條詭異SQL仍被監控到,看樣子屏蔽掉First方法調用並沒有找到Root Cause,需要繼續研究源碼。

image


仔細分析此段程式,ADOQuery2調用Select語句時並沒有使用綁定變量,是否是因為SQL硬解析造成異常SQL調用?

依此思路再將程序改寫成以下使用綁定變量形式,並請程序員再次編譯程序並上線。


image

第三天這條詭異SQL又被監控到,到底是哪裏還有問題,還是解決問題的思路錯了?再回到前一天改過的源碼......

文本改為綁定變量沒有錯,是否Delphi ADOQuery控件執行Add方法時這條奇怪的SQL被調用?依據這個思路,再修改第三版程序,將ADOQuery 的Add方法調用放到While循環外,並請程序員重新編譯上線。

image


現在在While循環外定義SQL,在While循環內給變量賦值並執行SQL。

繼續監控發現這條詭異SQL終於消失了。確認Delphi ADOQuery調用Add方法時調用這條問題SQL獲得對應表與索引信息。將Add方法移到While 循環外就徹底消除了循環內對問題SQL的調用。這也是Delphi ADOQuery控件在循環內執行SQL的正確方法。

Remark:
因為我們還有Informix 7 史前數據庫,公司Policy規定不可用ODBC訪問接口直接訪問它,且Oracle 11.2 Gateway又不支持對Informix 7的訪問,所以隻有保留Oracle 9.2.0.8以利用其異構服務訪問Informix 7。

原文發布時間為:2017-09-21
作者: 張洪濤
本文來自雲棲社區合作夥伴“ 數據和雲”,了解相關信息可以關注“ 數據和雲”微信公眾號

最後更新:2017-09-22 16:34:16

  上一篇:go  82歲成都“極客”老人將族譜“上雲” 還想去杭州雲棲大會見馬雲
  下一篇:go  Nutanix企業雲助力廣播傳媒的融合媒體發展之路