實戰筆記丨JDBC問題定位指南
JDBC(Java資料庫連線性)是Java API,用於管理與資料庫的連線,發出查詢和命令以及處理從資料庫獲得的結果集。JDBC在1997年作為JDK 1.1的一部分發布,是為Java持久層開發的首批元件之一。
JDBC問題基礎知識
JDBC問題是指比較寬泛的,體現在JDBC層面的問題,造成JDBC問題的原因主要是三個方面:1、應用程式和應用程式框架問題;2、JDBC業務功能問題;3、資料庫核心問題。問題表現可以分為三個大的方面:1、執行報錯,JDBC丟擲異常;2、執行效率低,耗時異常;3、特性不支援,JDBC未實現的JDK介面。
JDBC問題分類
JDBC問題定位方法及解決措施
建立資料庫連結失敗
1、 關鍵字:Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections. 客戶端ping服務端IP,看網路是否暢通,網路不通首先解決網路問題,然後檢視埠是否正確,埠不正確修改為正確的埠;
2、 關鍵字:FATAL: Invalid username/password,login denied. 檢查使用者名稱密碼的配置是否正確。措施:將其修改為正確的使用者名稱密碼。
3、 關鍵字:No suitable driver found for XXXX 檢查URL格式是否正確, 措施:將其修改為正確的格式gsjdbc4.jar對應 jdbc:postgresql://host:port/database, gsjdbc200.jar對應jdbc:gaussdb://host:port/database。
4、 關鍵字:FATAL: no pg_hba.conf entry for host 檢查所連結CN是否配置遠端訪問許可權,在cn下的pg_hba.conf檔案中新增host all all 0.0.0.0/0 sha256。
5、 關鍵字:conflit JDBC jar包和應用程式衝突,措施:將gsjdbc4.jar替換為gsjdbc200.jar
執行業務拋異常
1、 關鍵字:receiveErrorResponse 若報錯中含有次關鍵字,則JDBC報錯是接收到了核心發來的異常報文和異常資訊, 措施:需要收集相關報錯及日誌資訊發回研發分析。
2、 關鍵字:Broken pipe, connection reset by peer 可能原因:網路故障,資料庫連結超時,措施:檢查網路狀態,修復網路故障,影響資料庫連結超時的因素,資料庫引數session_timeout以及lvs。
3、 關鍵字:The column index is out of range 可能原因:應用程式獲取的結果集和預期不一致,列數不一致,應用程式問題 措施:檢查資料庫表定義和查詢sql,對返回結果集做一個正確預期,若結果集只有3列,取值時傳入的index最大為3。
效能問題
1、 設定loglevel=3,開啟jdbc日誌,若主要耗時在processResult階段,可分為兩種情況:1)jdbc端一直等待核心返回的報文,等待時間較長; 判斷方法:檢視FE=> Syncr日誌和<=BE ParseComplete日誌之間的時間間隔,若時間間隔較久,則判斷是核心執行慢;措施:需要核心人員分析sql執行慢的原因;2)結果集過大,一次性全部載入,消耗大量時間;判斷方法:看日誌若<=BE DataRow出現次數特別多,或則直接在gsql裡執行select count(*)查詢出來的數目特別大,則判斷是結果集過大; 措施:設定fetchSize引數為一個較小的值,使資料按批次返回,客戶端得到快速響應。
2、 若主要耗時在modifyJdbcCall(校驗傳入的sql是否符合規範)和createParameterizedQuery(將傳入的sql解析為preparedQuery,以獲取由simplequery組成的subqueries)階段,則需要看一下傳入的sql是不是過長,措施:jdbc本身沒辦法優化這部分耗時,需要應用端看下是否可以優化傳入的sql。
功能問題
1、 關鍵字:not yet implemented ,JDBC未實現介面,措施:需要研究一下是否可實現,是否需要落需求,或則是否有其他介面已提供相同功能,調整業務使用已提供介面。
2、 JDK標準介面中未提供功能,JDK未提供標準介面,措施:理論上,JDK未提供介面,JDBC不支援,實際使用中可以使用JDBC類中的public方法獲取部分過程資料,絕大部分情況下明確不支援。
常見案例
載入驅動失敗
客戶在使用JDBC的時候往往不是直接通過Java程式載入驅動建立連結,而是通過應用程式框架,做好配置之後通過應用程式框架自動建立連結,可能會由於配置問題導致建立連結失敗,如:使用了gsjdbc200.jar,但是載入的驅動仍然是org.postgresql.Driver後者使用的url格式仍然是jdbc:postgresql,由於是應用程式框架載入的,所以有些時候驅動路徑和url格式都是固定的,只允許配置ip、port、user、password等基本資訊,並且在出錯的時候只能看見建立連結失敗的log資訊,看不見堆疊。
解決措施:(1)首先應該檢查使用者使用的jdbc驅動是gsjdbc4.jar還是gsjdbc200.jar,若是gsjdbc200.jar應該替換為gsjdbc4.jar,嘗試建立連結。(2)排除JDBC嫌疑,寫一個Java測試用例,不通過應用程式架構,通過Java程式直接載入驅動,建立連結,在排除jdbc嫌疑之後再去細緻研究應用程式框架,以解決問題。
JDBC jar包衝突
多個局點曾報出類衝突問題,都是由於JDBC和應用程式擁有相同路徑相同名稱的類導致,大體可以分為兩類,一是gsjdbc4.jar和開源postgresql.jar衝突,兩者具有完全相同的類名,二是gsjdbc4.jar 由於iam特性引入了一些其他工具,例如fastjson,和應用程式中的fastjson衝突;
解決措施:針對和開源postgresql.jar的衝突,我們提供了gsjdbc200.jar,使用和開源驅動不同的url格式和驅動路徑,驅動名由org.postgresql.Driver修改為com.huawei.gauss200.jdbc.Driver,url格式由org:postgresql://host:port/database改為jdbc:gaussdb://host:port/database,徹底解決了和開源jar包的衝突;針對JDBC引入的jar和應用程式中引入jar的衝突,我們通過maven的shade修改了jar裡類的路徑,解決了這類衝突。