mysql伺服器架構
mysql是最廣泛使用的開源資料庫之一,作為後端開發人員,或多或少都會和mysql打交道,本篇文章會從sql查詢語句的執行過程,來介紹mysql的伺服器架構,
查詢的過程大致分為從客戶端到伺服器,在伺服器上解析,生成執行計劃,執行,並返回結果給客戶端。如下圖1.1所示。
圖1.1 sql查詢執行路徑
1.1 聯結器
聯結器對客戶端的連線請求進行使用者名稱和密碼的驗證,並會管理連線池。客戶端和伺服器為“半雙工”通訊協議,客戶端和伺服器無法同時傳送訊息,當伺服器向客戶端傳送查詢結果時,必須全部返回,客戶端不能主動停止,mysql需要等所有的資料都發送給了客戶端才會釋放本次查詢所佔用的資源,因此大多數庫函式都會接收結果並快取在客戶端,以使查詢早點結束,減輕服務端壓力。
對於連線到mysql的客戶端,可以用show full processlist檢視連線狀態,該狀態表示了mysql當前在做什麼,一個查詢完整的生命週期,狀態會變很多次。
在show full processlist中,欄位command表示執行緒正在執行的命令型別,The type of command the thread is executing,一般就是休眠(sleep),查詢(query),連線 (connect),含義如下:
- sleep,執行緒正在等待客戶端傳送新的請求。
- query,執行緒正在執行查詢或將結果返回客戶端。
- connect,正在建立連線。
show full processlist最重要的欄位是state,Most states correspond to very quick operations. If a thread stays in a given state for many seconds,there might be a problem that needs to be investigated.An action, event, or state that indicates what the thread is doing,表示執行緒處於某一狀態下具體正在做什麼,值的含義如下:
- Locked,在Mysql伺服器層,執行緒正在等待鎖,這裡不包括innodb儲存引擎實現的行鎖
- Analyzing and statistics,執行緒正在收集儲存引擎的統計資訊,並生成查詢的執行計劃。
- Copying to tmp table [on disk],執行緒正在執行查詢,並將結果放在臨時表,帶有on disk,表示mysql在將記憶體臨時表存入磁碟。
- Sorting result,執行緒正在對結果集排序。
- Sending data,執行緒正在多個狀態間傳送資料,或者在生成結果集,或者向客戶端返回資料。
1.2 查詢快取
在解析sql語句之前,mysql會從查詢快取中獲取資料,具體是一個大小寫敏感的雜湊查詢,sql語句必須和快取中的sql語句完全匹配,否則不會命中,對於更新比較頻繁的資料庫,經常會導致快取失效,建議將查詢快取關閉。
1.3 分析器
假如查詢快取沒有命中,則會進入分析器,對sql語句進行詞法和語法分析,並會進行預處理,以便知道此sql語句是要做什麼。它會驗證是否使用錯誤的關鍵字,關鍵字順序是否正確等。並且,預處理會根據一些規則對解析樹的合法性進行進一步校驗,比如檢查資料表和列是否存在,解析名字和別名,看看是否有歧義等,如下圖1.2經常遇到的語法錯誤就在這一階段
圖1.2 sql語法錯誤提示
1.4 優化器
sql語句經過分析器分析合法,需要經過查詢優化器轉化成執行計劃,查詢優化器解決的是怎麼做的問題,相同的sql語句,返回相同的結果集,有很多種執行方式,查詢優化器就是要選擇效能較好的一種。
mysql是基於成本的優化器,會預測一個查詢使用某種計劃時的成本,並選擇其中成本最小的一種,可以通過Last_query_cost值查詢到當前會話查詢的成本。很多原因會導致mysql優化器選擇錯誤的執行計劃,比如:統計資訊不準、不考慮其他併發執行的查詢,執行計劃太多,無法估算所有的計劃等。
1.5 查詢執行引擎
查詢執行引擎根據優化器生成的執行計劃(執行計劃是一種資料結構,而不是位元組碼),呼叫儲存引擎介面,完成執行計劃中的所有操作。mysql將查詢結果返回客戶端是一個增量、逐步返回的過程。開始生成第一條結果,mysql就可以開始向客戶端返回資料。這樣做服務端無需儲存太多結果,減小了服務端記憶體的消耗壓力,另外,客戶端也可以第一時間獲得返回的結果。