若是執行這條更新語句數據庫是如何執行的呢?mysql
update Student set name='小明' where StudentID=1
根據以前說過的SQL語句查詢的流程來講,只要表上有數據更新,有關查詢的索引就會失效,接下來分析器會根據每一個單詞識別知道這是Update語句,優化器根據這個ID獲取須要的索引,而後執行器執行這一行,進行更新。sql
先說裏面有一個重要的內容就是:redo log(重作日誌)和 binlog(歸檔日誌)。數據庫
在MySQL語句更新的時候,若是每一次更新操做都須要寫進磁盤,而後磁盤也找到對應的記錄,而後再更新,會消耗很大的IO,下降系統的效率。優化
這個時候重作日誌的場景就來了,當一條數據進行更新的時候,InnoDB引擎會先把記錄寫在redo log日誌中,並更新內存完成更新。在系統空閒的時候引擎會把這個操做記錄更新到磁盤。日誌
可是若是一直在往redo log中寫入數據,redo log日誌也是有固定大小的,當寫滿了,會將最以前插入進來的數據,更新到磁盤,而後擦除這段數據能夠用來記錄新的操做。有了這個功能,MySQL在異常重啓狀況下數據都不會丟失。這個能力稱爲crash-safe。code
當時MySQL沒有InnoDB引擎,只有歸檔日誌binlog,所以其餘引擎沒有crash-safe功能,後面有了InnoDB才誕生redo log日誌。索引
兩種日誌的特色:接口
若是不用兩次提交會發生什麼狀況事務
假如不用redo log,在系統崩潰的時候,數據就沒有了。內存
假如不用binlog,沒法用binlog恢復數據庫備份。
爲何要兩種一塊兒用呢,就比如事務,寫入了redo log,即將寫入binlog的時候系統崩潰,你的redo log沒有丟失,能夠等系統正常運行的的時候,再次提交併把binlog寫進磁盤。redo log 和 binlog 均可以用於表示事務的提交狀態,而兩階段提交就是讓這兩個狀態保持邏輯上的一致。
redo log 用於保證 crash-safe 能力。innodb_flush_log_at_trx_commit 這個參數設置成1 的時候,表示每次事務的 redo log 都直接持久化到磁盤。這個參數我建議你設置成 1,這樣能夠保證 MySQL 異常重啓以後數據不丟失。 sync_binlog 這個參數設置成 1 的時候,表示每次事務的 binlog 都持久化到磁盤。這個參數我也建議你設置成 1,這樣能夠保證 MySQL 異常重啓以後 binlog 不丟失。