同樣的sql執行結果不同的原因分析
對於不可見字元的問題,有必要先說明一下,可以簡單舉個例子。
我們建立一個表,然後插入的資料含有不可見字元,比如回車,換行符。
SQL> create table test as select object_id,object_name||chr(10) objname from all_objects where rownum<3;
Table created
插入資料之後,我們檢視一下資料。
SQL> select *from test;
OBJECT_ID OBJNAME
---------- -------------------------------
20 ICOL$
46 I_USER1
簡單的驗證一下,可以看到object_id=46對應的是objname為I_USER1的資料行。
SQL> select *from test where objname='I_USER1';
no rows selected --但是查詢的時候卻沒有任何結果
如果我們在查詢中明確的加入那個不可見字元,就可以很容易就插敘出來。
SQL> select *from test where objname='I_USER1'||chr(10);
OBJECT_ID OBJNAME
---------- -------------------------------
46 I_USER1
這個時候可以使用dump函式來分析。
如果可以對比一下資料的dump細節,可以發現唯一的差比是最後有一個chr(10)的字元
SQL> select object_id,dump('I_USER1') DUMP1,dump(objname) DUMP2 from test where objname like 'I_USER%';
OBJECT_ID DUMP1 DUMP2
---------- ---------------------------------- --------------------------------------------------
46 Typ=96 Len=7: 73,95,85,83,69,82,49 Typ=1 Len=8: 73,95,85,83,69,82,49,10
但是當我自信滿滿的檢視了開發提供的日誌之後,然後在客戶端中又執行了一遍,發現問題似乎比預想的更有些奇怪。
語句是一個簡單的select語句,類似select xxxx,xxxxx,xxxx from districute where entity_id=:id and status='ACTIVE', 其中entity_id是傳入的引數。
在反覆比較之後,基本上這個地方不太可能出現問題,在API想傳入這個特殊字元都不容易。但是一模一樣的語句在兩邊執行結果卻不相同。
肯定是某個地方出了問題,我靜下來,仔細的分析日誌中的sql語句,按照目前的情況來說,只可能在某處修改了資料導致的,從這個查詢語句往前排查,最終發現了線索。
在這個查詢之前,其中有一步是update操作,語句類似update distribute set xxxx=xxx where distribute_no=:distid 從表面上來看,兩個語句的唯一共同之處在於都是基於同一個表。
檢視sql語句中對應的變數值,發現在select之前的這步操作已經修改了對應的status值,所以在後續的查詢中根據entity_id就匹配不到相應的記錄了。
透過資料來說明,就如同下面的情況,我們透過distribute_no修改了status值,再透過status,entity_id來匹配對應的資料行得到的結果就為空,在得到的結果為空後,校驗失敗,於是事務就回退了。然後下一次呼叫繼續update,select,rollack。
entity_id status distribute_no xxxx
100 ACTIVE 100001 xxxxx
分析了這些之後,問題就一下子明朗多了,不是什麼特別的bug,不是什麼特別的場景,都是潛意識中自己被誤導了。所以大家在排查問題的時候,可能提供給你的資訊不是最全面最完整的,我們需要分析去佐證。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8494287/viewspace-1422000/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 故障分析 | MySQL 相同 SQL 不同環境執行時間不一樣案例分析MySql
- 如何使用效能分析工具定位SQL執行慢的原因?SQL
- 生產系統 SQL 執行異常原因分析SQL
- 記一次utlrp.sql指令碼執行引發的結果SQL指令碼
- 用 Explain 命令分析 MySQL 的 SQL 執行AIMySql
- 獲取任務的執行結果
- SQL Server資料庫判斷最近一次的備份執行結果SQLServer資料庫
- 同樣的SQL,怎麼突然就慢了?SQL
- Oracle - 執行過的SQL、正在執行的SQL、消耗資源最多的SQLOracleSQL
- Java獲取多執行緒執行結果方式的歸納與總結Java執行緒
- Spark Task 的執行流程④ - task 結果的處理Spark
- 為啥同樣的邏輯在不同前端框架中效果不同前端框架
- MySQL——通過EXPLAIN分析SQL的執行計劃MySqlAI
- 面試官:請分析一條SQL的執行面試SQL
- 有遇到過嗎?同樣的規則 Excel 中 比Python 結果大ExcelPython
- 不同的SQL語句執行時需要申請並持有對應的鎖SQL
- synchronized下的 i+=2 和 i++ i++執行結果居然不一樣synchronized
- 小米10ultra 同樣亮度 ISO不同導致的解析度不同
- MySQL中UPDATE語句裡SET後使用AND的執行過程和結果分析MySql
- 多執行緒的補充 獲取一定時間的執行結果執行緒
- 動態建立 @ViewChild 導致執行時錯誤的原因分析View
- sql語句執行緩慢分析SQL
- SQL是如何執行的SQL
- 在連結與執行地址不同時gdb的除錯方法除錯
- 多執行緒並行執行,然後彙總結果執行緒並行
- BGP - 不同 AS 間執行的協議協議
- Mac 下 Docker 執行較慢的原因分析及個人見解MacDocker
- 【Spark】 Spark作業執行原理--獲取執行結果Spark
- 突然斷電,是否會影響Mysql的執行結果MySql
- [20221104]執行計劃一樣Plan hash value不同.txt
- sql語句如何執行的SQL
- sql更新是如何執行的?SQL
- MYSQL sql執行過程的一些跟蹤分析(一)MySql
- Mybatis原始碼分析(五)探究SQL語句的執行過程MyBatis原始碼SQL
- python執行shell並獲取結果Python
- 選擇排序中交換資料的不同方式出現的不同結果排序
- 評“MySQL 隱式轉換引起的執行結果錯誤”MySql
- 分享一個shell指令碼的坑:grep匹配+wc取值 在指令碼執行後的結果與手動執行結果不一致指令碼
- 更高階的技術可用於獲取使用QThreadPool和QRunnable啟動執行緒的執行結果QTthread執行緒