一條SQL更新語句的執行過程

2022-06-05 06:42:09 字數 1481 閱讀 4091

目錄如果執行這條更新語句資料庫是如何執行的呢?

update student set name='小明'  where  studentid=1
根據之前說過的sql語句查詢的流程來說,只要表上有資料更新,有關查詢的索引就會失效,接下來分析器會根據每個單詞識別知道這是update語句,優化器根據這個id獲取需要的索引,然後執行器執行這一行,進行更新。

先說裡面有乙個重要的內容就是:redo log(重做日誌)和 binlog(歸檔日誌)。

在mysql語句更新的時候,如果每一次更新操作都需要寫進磁碟,然後磁碟也找到對應的記錄,然後再更新,會消耗很大的io,降低系統的效率。

這個時候重做日誌的場景就來了,當一條資料進行更新的時候,innodb引擎會先把記錄寫在redo log日誌中,並更新記憶體完成更新。在系統空閒的時候引擎會把這個操作記錄更新到磁碟。

但是如果一直在往redo log中寫入資料,redo log日誌也是有固定大小的,當寫滿了,會將最之前插入進來的資料,更新到磁碟,然後擦除這段資料可以用來記錄新的操作。有了這個功能,mysql在異常重啟情況下資料都不會丟失。這個能力稱為crash-safe。

當時mysql沒有innodb引擎,只有歸檔日誌binlog,因此其他引擎沒有crash-safe功能,後面有了innodb才誕生redo log日誌。

兩種日誌的特點:

首先執行器根據studentid=1的索引取得這一行資料,如果這一行資料在記憶體中,就直接返回給執行器,否者從磁碟讀取進記憶體再返回。

執行器拿到資料給name改為小明,得到新的資料行。

引擎將這個資料更新到記憶體中,然後將操作記錄寫入redo log,這時redo log處於prepare狀態,然後告知執行器已經完成可以提交事務。

執行器生成這個操作的binlog,並把binlog寫進磁碟。

執行器呼叫引擎介面提交事務,並把剛剛寫入的redo log 改成提交(commit)狀態,更新完成

如果不用兩次提交會發生什麼情況

假如不用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 不丟失。

一條SQL更新語句是如何執行的

mysql create table t id int primary key,c int 如果要將id 2這一行的值加1,sql語句就會這麼寫 mysql update t set c c 1where id 2 執行語句前要先連線資料庫,這是聯結器的工作。在乙個表上有更新的時候,跟這個表有關的查...

一條SQL語句的執行過程

1.1連線層 提供連線協議 tcp ip,socket 提供驗證 使用者 密碼 ip socket 提供專用連線線程 接收使用者sql,返回結果 通過以下語句可以檢視鏈結執行緒的基本情況 mysql show processlist 1.2sql層 重點 接收上層傳送的sql語句 語法驗證模組 驗證...

日誌系統 一條SQL更新語句是如何執行的

一 重要的日誌模組 redo log wal技術 先寫日誌,再寫磁碟。具體是當有一條紀錄需要更新的時候,innodb引擎就會先把紀錄寫到redo log裡面,並更新記憶體,在引擎空閒的時候,將這個操作紀錄更新到磁碟裡面。1 redo log紀錄了這個資料頁做了什麼改動 2 redo log 是固定大...