mysql中有乙個重要的技術叫wal(write-ahead logging),意思是寫入資料之前先寫日誌。當有一條update語句需要執行的時候,innodb引擎會先把修改的記錄寫到redo log中,並將資料的變更寫入記憶體中的page pool中,不用每次都把修改的資料寫入磁碟。
innodb的後台執行緒會按照一定的規則將記憶體中的髒頁寫入磁碟,落盤後記錄下來當前redo log中有多少update日誌已經實際儲存到磁碟資料檔案中了。redo log的總的寫入量叫lsn(log secquence numer日誌序列號),而redo log中update記錄已經寫入到磁碟檔案中的數量叫checkpoint lsn,表示的是有多少變更已經寫入到了磁碟中。 一旦資料庫崩潰innodb開始恢復資料的時候,先讀取checkpoint,然後從checkpoint所指示的lsn讀取其之後的redo log進行資料恢復。所以,當db重啟恢復時,只需要恢復checkpoint之後的資料,這樣就能大大縮短恢復時間。
binlog屬於server層,是邏輯日誌,記錄了某個更新或者插入語句的原始邏輯,例如"給表t的id=1行的a子段加1"。binlog可以追加寫入。
怎麼使用binlog日誌來恢復資料?
如果在某一天下午6點,發現中午12點有資料被誤刪了。那麼,我們可以先找到最近的一次全量備份(可能就是昨天晚上做的全量備份)。然後從備份的時間點開始,將備份的binlog取出來,應用到備份資料上,一直應用到誤刪資料的那個時刻前。接下來,就可以把臨時庫的資料恢復到線上庫。
①redo log屬於引擎層,是innodb特有的;binlog屬於server層,是所有引擎共用的。
②redo log是物理日誌,記錄了"在哪個資料頁上做了什麼修改";而binlog是邏輯日誌,記錄了執行語句的原始邏輯。
①執行器找引擎取id=2這行。id是主鍵的情況下,可以直接通過索引找到這行。如果這一行所在的資料頁已經存在於記憶體中,則可以直接返回;否則,從磁碟讀入記憶體再返回。
②執行器對要更新的行對應的字段值作更新(比如加1),得到新的一行資料。
③引擎將這行新資料更新到記憶體中,同時將更新操作記錄到redo log buffer中,此時redo log處於prepare狀態。
④執行器將更新操作記錄到binlog中。
⑤引擎把redo log狀態改為commit,更新完成。
用反證法證明:
如果不用兩階段提交,那麼就變成兩個日誌先後分別提交一次的情況。
如果先寫redo log後寫binlog,那麼當redo log已經寫好後,寫binlog的時候突然系統崩潰了。redo log寫完提交之後的事務是不可以回滾的(如果回滾會覆蓋掉別的事務的更新),因此主庫必定存在新的資料行,而binlog是主庫要傳給備庫作同步的,由於binlog中並沒有記錄這個更新操作,所以會出現主備不一致的情況。
如果先寫binlog後寫redo log,那麼當binlog已經寫完,寫redo log的時候突然崩潰,重啟後主庫中並沒有更新這一行,但是binlog中卻記錄下了,會導致備庫多進行了操作,也會出現主備不一致的情況。
MySQL的日誌模組
mysql的持久化能力非常強大,它可以恢復到兩周內任意一秒的狀態。像查詢所需要執行的一套流程,更新也會再執行一次。如果不知道,可以看這裡.mysql的底層機制 但是更新操作會牽扯到日誌模組,這裡的日誌是redo log與bin log。也就是我們常說的重做日誌和歸檔日誌。目錄 redo log bi...
日誌模組 logging模組
logging.debug 通常除錯時用到的日誌資訊 logging.info 證明事情按照預期的那樣工作 longging.warning 表明發生了意外,或者不就得將來發生的問題 如 磁碟滿了 軟體還是正常的工作 longging.error 由於更嚴重的問題導致軟體已經不能繼續執行某些功能 l...
任務模組 報告模組 日誌模組
需求背景 報告模組 怎麼來處理這個報告的問題,報告是非常重要的一塊,1,可以看到每一次執行的情況,多少通過了,多少失敗了 2,可以看到執行的日誌,每一步的日誌,失敗了,我要知道失敗在 了,3,每次都要有報告 業務設計 1,任務列表,任務名稱,檢視任務詳情,報告列表,執行的功能,2,任務詳情,每乙個用...