導讀:
前言
本文通過一個Bug的分析、解決,概述了使用Lumigent Log Explorer對SQL Server的交易記錄進行分析的方法,以及常見的資料庫誤操作後的恢複、撤銷方法
Bug描述
網站的文章模組有一個評分的功能:
使用者選擇1-5分,點擊提交後,文章的評分次數(Stars) + 1、總分(StarTotal) + 分數、平均分(StarAvg) = 新總分 / 新評分次數
文章頁面顯示使用者的平均分以及評分次數
評分功能中使用者最多打5分,最少打1分,某日忽然發現有的文章平均分竟然大於5,很不可思議。出現這個問題,大致的原因大不過有:
實現評分邏輯的頁面沒有驗證傳入的分數是否合法、有些使用者直接提交他們想要的分數來作弊;
評分邏輯無誤,但計算平均分的演算法錯誤
經檢查,評分模組不僅驗證了分數範圍,而且驗證了訪問來源,使用者根本不可能通過提交他們想要的分數達到修改平均分的目的;平均分演算法也沒有問題。
這就奇怪了,只能先查看一下SQL Server的交易記錄,這裡選用了Lumigent Log Explorer,文章的提交時間是2008-05-06 13:40,發現問題的時間是2008-05-06 14:10,於是
Lumigent Log Explorer 使用方法
1、開啟軟體主介面,點擊左側的“Attach log file”
2、在右側的對話方塊先選擇SQL Server的地址(我把Lumigent Log Explorer裝在了資料庫伺服器上,所以選擇的local),1
圖1
3、點擊Connect後,選擇我們要查看的交易記錄所屬資料庫,注意這裡有兩個選項:Use On-Line Log和Use Backup Log,這裡普及一下SQL Server的交易記錄知識:
交易記錄會“忠實”記錄一切你對資料庫的操作,包括增加、刪除表、欄位,增刪改查資料等等,我們在SQL Server企業管理器的管理(Management)、資料庫維護計劃(Database Maintenance Plan)、交易記錄備份(Transaction Log Backup)選項卡中是可以設定交易記錄的備份計劃的,比如我們設定為1小時備份一次。
那麼如果我們查看的交易記錄還沒有備份,我們選擇Use On-Line Log,如果已經備份成了尾碼名為TRN(這也是可以由你自訂的)的備份檔案,我們選擇Use Backup Log;如果未備份的、已備份的交易記錄都需要查看,則都選
我這裡只選User On-Line Log
點擊Attach,載入相應的日誌
4、在左側菜單 Filter Log Records 中,2
圖2
在TimeRange選項卡中選定上面的時間範圍,3
圖3
投票屬於對錶的修改,於是在Activity選項卡中只選ModifyRow、ModifyColumns,4
圖4
在Table選項卡中只選文章表,5
圖5
點擊Apply後就可以看到所有合格交易記錄了,5-1
圖5-1
Bug分析
經過仔細查詢,我查到了3個對有問題的文章的操作,6、7、8
圖6是對文章評分,我們可以看到:總分是5,評分次數是1,平均分是5,這是沒錯的;
圖6
圖7是對文章的修改,我們可以看到:平均分由5變為了0,評分次數由1變為了0,這是怎麼回事呢?
圖7
經思考得出結論,就在使用者對文章評分前,作者剛剛對文章執行了修改操作,修改會
先建立一個指定文章ID的文章對象(實際是從資料庫中讀取指定ID的記錄) ->
使用者評分 ->
執行修改(實際就是把剛才建立的對象寫入資料庫,因為讀取資料時還沒有評分,所以寫入的資料是評分前的資料)
現在搞明白了,拿北京話講,太“寸”了;這也有辦法解決,只需要使用者修改文章時對指定ID的文章對象加鎖,修改完後解鎖,評分操作同樣如此;
圖8是又有使用者對文章進行評分,我們看到總分變成了9,評分次數是1,平均分也變成了9
圖8
到這裡,真相大白:實際上是有2位使用者對文章進行了評分,因為修改文章的Bug導致資料庫只記錄了1位。
問題有了:為什麼修改文章時平均分歸零、評分次數歸零、恰恰總分沒有歸零呢?如果總分歸零了,起碼再有使用者投票時是不會有平均分大於5的資料的。
忽然想起來,文章的資料庫結構做過一次調整,調整的內容恰恰是增加了總分欄位(StarTotal),而資料持久層卻沒有相應同步,所以在建立文章對象時,漏過了StarTotal這個欄位,也就沒有對這個欄位進行修改。
至此,問題的原因、解決方案都出來了。
使用Lumigent Log Explorer恢複(撤銷)事務、操作
我們常遇到誤刪除、修改資料的時候,利用Lumigent Log Explorer就可以做到只還原指定事務。
事務是對資料庫的一系列操作,比如:UPDATE [dbo].[TestTable] SET [Passed] = 1,會對錶[dbo].[TestTable]的所有記錄的[Passed]欄位進行賦值,我們在Lumigent Log Explorer看到的是一系列相同TransId的操作(5-1),只需要在這一系列操作的任意一個上點右鍵,選擇Undo Transaction,即可對這個事務進行撤銷(還原);
當然,我們也可以對事務的某一個操作進行撤銷(還原),很簡單,只需要按上面的步驟選擇Undo Operation即可。
選擇Undo Transaction或Undo Operatio後,Lumigent Log Explorer會產生一個標準的SQL語句文檔,將這個文檔的內容在查詢分析器(Query Analyzer)裡面執行即可撤銷(還原)事務或事務中的操作。
問題
操作的內容包含ntext或者text欄位時,Lumigent Log Explorer產生的SQL語句中沒有這些欄位的內容,這個問題如果哪位有解決方案,還望不吝賜教,謝謝先。
本文轉自
http://www.chinavalue.net/Blog/BlogThread.aspx?EntryId=60949