SQL在MySQL資料庫中是如何執行的

coldplay.xixi
發布: 2020-11-09 17:20:22
原創
1838 人瀏覽過

今天和mysql影片教學欄位一起看看一則更新語句又是怎麼一個執行流程。

SQL在MySQL資料庫中是如何執行的

查詢語句的一套執行流程,更新語句也會同樣的走一步,下邊我們在對照上次文章中的圖來簡單的看一下:

<img src=" class="lazyload" src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d529960ec1dd496ca90860641bcaa093~tplv-k3u1fbpfcp-watermark.image" data- style="max-width:90%" data- style="max-width:90%">

首先,在執行語句前要先連接資料庫,這是第一步中連接器的工作,前面我們也說過,當一個表有更新的時候,跟這個表有關的查詢快取都會失效,所以我們通常不建議十月查詢快取。

接下來,分析器會經過語法分析和詞法分析,知道了這是一條更新語句後,優化器決定要使用哪一個索引,然後執行器負責具體的執行,先找到這一行,然後做更新。

與查詢語句更新不同的是,更新流程還涉及兩個重要的日誌,這個我們在前邊的文章中也有專門的介紹,有興趣的可以找一下上週的文章《MySQL的兩個日誌系統》,這裡就不多做介紹了。

下邊透過一個簡單的例子來分析一下更新操作的流程。

我們先建立一張表,這個表有主鍵ID和一個整數欄位c:

mysql> create table demo T (ID int primarty ,c int);复制代码
登入後複製

然後將ID=2的這一行的值加1

mysql> update table demo set c = c + 1 where ID = 2;复制代码
登入後複製

接下來我們來看看update語句的執行流程,圖中淺色框表示在儲存引擎中執行的,神色框代表的是執行器中執行的。

我們可以看到最後的時候,寫redolog的時候分了兩步,prepare和commit,這就是我們常說的「兩階段提交」。

為什麼日誌需要「兩階段提交」?

由於redo log和binlog分別是儲存引擎和執行器的日誌,是兩個獨立的邏輯,如果不用兩階段提交,無論先提交哪個後提交哪個都會存在一些問題。我們這裡也藉助上邊的例子看一下,假設當前ID=2的這一行值為0 ,在update的過程中寫完了第一個日誌後,第二個日誌還沒寫期間發生了crash,會怎麼樣?

  • 先寫redolog後再寫binlog。假設redolog寫完,binlog還沒寫完,MySQL進程異常重啟了。我們知道,redolog寫完以後,系統即使崩潰了,也可以將資料恢復,所以在MySQL重新啟動後,這一行回被恢復成1。由於binlog沒寫完就crash,這時候binlog裡面是沒有這個語句的,因此之後備份日誌的時候,存起來的binlog日誌也沒有這一語句。當我們需要透過binlog來恢復資料的時候,由於binlog遺失了這條語句,恢復出來的這一行的值就是0,與原庫的值不一樣啦。
  • 先寫binlog後再寫redo log。如果寫完buglog之後,redo log還沒寫完的時候發生crash,如果這個時候資料庫奔潰了,恢復以後這個事務無效,所以這一行的值還是0,但是binlog裡已經記載了這條更新語句的日誌,以後需要用binlog來恢復資料的時候,就會多了一個交易出來,執行這條更新語句,將值從0更新成1,與原庫中的0就不同了。

我們可以看到如果不使用「兩階段提交",那麼資料庫的狀態就會和用日誌恢復出來的函式庫不一致。雖然平常用日誌恢復資料的機率比較低,但是用日誌最多的還是擴容的時候,用全量備份和binlog來實現的,這個時候就可能導致線上的主從資料庫不一致的情況。

相關免費學習推薦:mysql影片教學

#

以上是SQL在MySQL資料庫中是如何執行的的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.im
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板