edu最近兩周發生很奇怪的問題,如所示,這個bug的簡單描述就是同樣的語句,通過mysql.data,取資料庫,取到的值不穩定,有的時候能返回正確的值,有的時候就返回null,一開始認為是我們內部orm架構的bug,但是後來用直接調用mysqlcommand的ExecuteScalar方法也依然報錯。而且這個bug只要一重啟之後就恢複正常,一段時間,可能1天可能2天就又會重現,完全不知道該如何下手。因為這個問題,edu產生了很多插曲,
這個有空詳細總結下edu在這次異動中的經驗教訓,項目兩年了,還是不斷重複著昨天的故事。
回到這個bug,我今天回頭從mysql.data的源碼裡面找原因,看到幾個可疑的地方
mysqlcommand的ExecuteScalar方法內部調用的還是mysqlreader這個對象,可以先排除語句本身的錯誤,因為確實沒錯,而且確實應該返回而且大部分時間返回正確的值,那麼剩下的代碼裡面可以看到
public override object ExecuteScalar()
{
lastInsertedId = -1;
object val = null;
MySqlDataReader reader = ExecuteReader();
if (reader == null) return null;
try
{
if (reader.Read())
val = reader.GetValue(0);
}
finally
{
if (reader != null)
{
reader.Close();
lastInsertedId = reader.InsertedId;
}
reader = null;
}
return val;
}
reader等於null,或者reader返回的結果為null會導致這個問題,那
1、reader為null,構建reader失敗可能就是原因
在看reader返回結果是null又會存在什麼可能?
ExecuteReader()裡面的代碼
catch (MySqlException ex)
{
// if we caught an exception because of a cancel, then just return null
if (ex.Number == 1317)
{
if (TimedOut)
throw new MySqlException(Resources.Timeout);
return null;
}
if (ex.IsFatal)
Connection.Close();
if (ex.Number == 0)
throw new MySqlException(Resources.FatalErrorDuringExecute, ex);
throw;
}
這段catch裡面有個值得注意的地方,
2、錯誤碼1317,
Error: 1317 SQLSTATE: 70100 (ER_QUERY_INTERRUPTED)
Message: Query execution was interrupted
官方的解釋是代碼執行被中斷,這個也是個可能的地方
總結,這次放假歸來,我一定要查出這個bug的原因,而且我也發現大家對mysql.data不瞭解,這次debug輸出出來的東西為什麼要用cmd.ExecuteScalar這個方法,而不是直接用mysqlreader,這樣才能看出問題的原因,工作在.net上,已經很多東西都看不到了,如果看過源碼,一定知道要列印的是mysqlreader裡面的東西,我們都還是低水平的debug。沒見到高明的人是怎麼做的。不要自我滿足,你我都是井底之蛙。我們這沒有牛人。