一條sql語句的執行過程


一條select語句執行流程

第一步:連接器

連接器負責跟客戶端建立連接、獲取權限、維持和管理連接。如果用戶名密碼驗證通過后,連接器會到權限表里面查出你擁有的權限。之后該連接的權限驗證都依賴於剛查出來的權限。

第二步:查詢緩存

當獲取連接后,一條SELECT語句會先去查詢緩存,看之前是否執行過。如果獲取到緩存后就執行返回,不然繼續后面的步驟。

大多數時候不建議使用緩存,因為只要一個表更新,這個表上的所有緩存數據就會被清空了。對於那些經常更新的表來說,緩存命中率很低。MYSQL8版本直接將查詢緩存的整塊功能刪掉了。

第三步:分析器

分析器首先會做“詞法分析”,MYSQL會識別出SQL語句里面的字符串是什么以及代表什么。接下來就是“語法分析器”,分析SQL的語法問題。

第四步:優化器

優化器會對SQL的執行順序,使用哪個索引進行優化。確定SQL的執行方案。

第五步:執行器

執行器執行SQL語句會對權限進行校驗,如果有權限,就打開表繼續執行。打開表的時候,執行器就會根據表的引擎定義,去使用這個引擎提供的接口。

一條update語句執行流程

update語句除了會執行上面的五步,還會涉及兩個重要的日志模塊。

兩個重要的日志模塊
redo log (重做日志)

redo log 是innodb所特有的,當有一條更新語句時,innoDB引擎會先把記錄寫到redo log中,然后更新內存,這時候更新就算完成了。innoDB會在合適的時候將這個記錄更新到磁盤中去。

特點:redo log 是固定大小的,屬於循環寫。redo log是物理日志,記錄的是“在某個數據頁上做了什么修改”。有了redo log ,InnoDB可以保證數據庫發生異常重啟的時候,之前提交的記錄不會丟失,這個能力為crash-safe。

binlog(歸檔日志)

binlog屬於server層的日志,是邏輯日志,記錄的是這個語句的原始邏輯,比如給“id =1 的一行的某個字段+2”。binlog是追加寫入的,binlog寫到一定的大小后切換到下一個,不會覆蓋之前的。

更新語句的內部流程

update t set n = n+2 where id =1

  1. 執行器先找引擎找到id=1的那一行,如果這一行的數據頁已經在內存中則直接返回給執行器。否則先從磁盤讀入內存中,然后在返回。
  2. 執行器拿到了引擎返回的數據行,把這個n值+1,得到新的行數據,然后調引擎的接口寫入這行新數據。
  3. 引擎將這行數據更新到內存中,同時將這個更新操作記錄到redo log里,此時rodo log屬於prepare狀態。然后告知執行器執行完成了,隨時可以提交事務了。
  4. 執行器生成這個操作的binlog,並把binlog寫入磁盤。
  5. 執行器調引擎的提交事務接口,引擎把剛剛寫入的redo log的狀態改為commit狀態,更新完成。
兩段式提交

redo log的寫入分為兩部分,是為了保證這兩份日志的邏輯一致。

相關配置

redo log 用於保證 crash-safe 能力。innodb_flush_log_at_trx_commit 這個參數設置成 1,表示每次事務的 redo log 都直接持久化到磁盤。

sync_binlog 這個參數設置成 1 的時候,表示每次事務的 binlog 都持久化到磁盤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM