目錄
- update更新"未成功"?
- 前言
- 問題場景
- MySQL出現“寫了binlog但并沒有寫redo-log“
- 簡單看下兩階段提交的流程
- 兩階段寫日志的意義?
- 排查陷入僵局
- 排查binlog
- 排查這段時間內的所有和這個id有關的binlog記錄
- 總結
update更新"未成功"?
前言
筆者最近解決了一個非常曲折的問題,就是業務反應有一條資料進行update并且成功后,查詢依然是舊資料,于是開始一路排查,最后才完美解釋了所有的現象,在這里將整個程序寫成文章記錄下來,希望能夠對讀者有所幫助,(篇幅可能會有點長,耐心看完,絕對物有所值~)
問題場景
業務小明:有一筆訂單更新,更新資料回傳成功,但是資料庫里還是舊的資料,

看了這組資料后,百思不得其解:”不但修改的資料沒有生效,uptime也不一樣了“,于是登錄資料庫進行查詢,結果的確是小明同志描述的那樣,怎么辦呢?
翻了一下關于這條資料的binlog記錄的陳述句確是就是進行了更新,那么問題來了,這不就意味著:
? 寫了binlog但并沒有進行redo-log的更新 ,這不就資料不一致了啊?
MySQL出現“寫了binlog但并沒有寫redo-log“
中所周知MySQL具有WAL機制(先寫日志,再寫磁盤),我們要搞清楚會不會出現“寫了binlog但并沒有寫redo-log“的情況,就需要研究這個WAL機制的二段提交特性,
在說兩階段提交事物之前,我們先來說說事務,
簡單看下兩階段提交的流程
兩階段提交的時序圖:

粗略觀察一下上圖,MySQL想要執行事務的時候會分成兩個階段
第一階段 (prepare階段):寫rodo-log 并將其標記為prepare狀態,
緊接著寫binlog

第二階段(commit階段):寫bin-log 并將其標記為commit狀態,

兩階段寫日志的意義?
你有沒有想過這樣一件事,binlog默認都是不開啟的!
也就是說,如果你根本不需要binlog帶給你的特性,那你根本就用不著讓MySQL寫binlog,也用不著什么兩階段提交,
只用一個redolog就夠了,無論你的資料庫如何crash,redolog中記錄的內容總能讓你MySQL記憶體中的資料恢復成crash之前的狀態,
所以說,兩階段提交的主要用意是:為了保證redolog和binlog資料的安全一致性(劃重點!!!拐杖敲黑板3次),只有在這兩個日志檔案邏輯上高度一致了,你才能放心的使用redolog幫你將資料庫中的狀態恢復成crash之前的狀態,使用binlog實作資料備份、恢復、以及主從復制,而兩階段提交的機制可以保證這兩個日志檔案的邏輯是高度一致的,沒有錯誤、沒有沖突,
排查陷入僵局
? 看到這里我們就發現兩階段提交保證了redolog和binlog資料的安全一致性,binlog里進行commit,redolog里一定是成功的也就是說:
? 根本不可能出現寫了binlog但并沒有寫redo-log的情況,完全不會出現小明描述的那樣的問題,

經過反復思考,真実(しんじつ)は いつも ひとつ 平假名:しんじつはいつもひとつ(真相只有一個)

那就是描述資訊里有遺漏,在更新后和查詢前必定有一個事務對這個記錄進行了操作,

排查binlog
1.排查這段時間內的所有和這個id有關的binlog,并提取出相關記錄
2.找出更新后和查詢前的那個事務的binlog
排查這段時間內的所有和這個id有關的binlog記錄
如何出排查這段時間內的所有和這個id有關的binlog記錄呢,這么多的binlog,那只能寫個腳本就行批處理了,

file_list=$(ls mysql-bin.00*)
for i in file_list
do
count=`mysqlbinlog -vv -d t100w.t_250w $i |grep -c "{主鍵id}"`
[ $count -gt 0 ] && (echo $i $count)
done
## 代碼解釋:
# mysqlbinlog -d t100w.t_250w 只查看t100w庫t_250w表的binlog
# grep -c 統計檔案中搜索關鍵字的個數(等價于 select count(*) from table where id > ?)
# 通過ls獲取到所有mysql-bin,通過for回圈找到搜索關鍵字的個數大于0的檔案,并列印檔案名和統計個數

然后使用less命令,搜索主鍵id,
mysqlbinlog -vv -d t100w.t_250w mysql-bin.009820|less
# less內
# /主鍵id
最終找到了那條記錄,真相大白:

總結
有時候問題并沒有那么復雜,并不是MySQL底層除了問題,而是“小明”在提供資訊的時候不一定能把問題準確的描述清楚,導致我們的一些誤判,在處理問題上應該先從距離問題最近的角度出發,感謝大家看完一名菜雞DBA的文章,我們下個文章再見!

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/279515.html
標籤:其他
