mysql各個子產品如何協同工作的,我們通過啟動mysql、用戶端連接配接、請求query,得到傳回結果,最後退出。這個過程來看一下。
執行啟動mysql指令後,mysql的初始化子產品從配置檔案中讀取系統參數與指令行參數,并按參數來初始化整個系統。同時各個存儲引擎也被啟動,并進行各自的初始化工作。
當整個系統初始化結束後,連接配接管理子產品接手,連接配接管理子產品啟動處理用戶端連接配接請求的監聽程式,包括tcp/ip網絡監聽,還有unix的socket。此時mysql server基本啟動完成,準備好接受用戶端請求。
當連接配接管理子產品監聽到用戶端的連接配接請求,雙方通過client&server互動協定子產品定義的協定“寒暄”幾句後,連接配接管理子產品将連接配接請求轉給線程管理子產品,去請求一個連接配接線程。
線程管理子產品馬上将控制交給連接配接線程子產品,告訴連接配接線程子產品:我這有連接配接請求,需要建立連接配接。連接配接線程子產品接到連接配接請求後,首先檢查目前線程連接配接池中是否有cache有空閑連接配接線程,如果有,取出一個和用戶端請求連接配接,如果沒有,則建立一個連接配接線程與用戶端連接配接。當然連接配接線程子產品并不是收到連接配接請求後馬上取出連接配接線程與用戶端連接配接,而是先調用使用者子產品進行授權檢查,隻有用戶端請求通過了授權檢查後,它才會将用戶端請求與線程連接配接上。
在mysql中,用戶端請求分為兩種:一種是query,需要調用parser和轉發子產品才能執行的請求,一種是command,不需要調用parser就可以直接執行的請求。(如果在配置檔案中打開了full query logging功能,那麼query解析與轉發子產品會調用日志記錄子產品将請求記入日志,不管是一個query類型的請求還是一個command類型的請求,都會記錄進入日志)
當用戶端請求與連接配接線程接上頭後,連接配接線程就開始處理用戶端請求發送過來的各種指令或是query。它将收到的query轉給query解析和轉發子產品,query解析器先對query進行基本的語義和文法解析,然後根據指令類型的不同,有些是直接處理,有些是轉發給其他子產品處理。
如果是一個query類型的請求,将控制權交給query解析器,query解析器首先分析是不是一個select,如果是,則調用查詢緩存子產品,讓它檢查該query在query cache中是否存在,如果有,則直接将cache中的資料傳回給連接配接線程子產品,然後再通過與用戶端的連接配接線程将資料傳輸給用戶端。如果沒有,那query将傳回query解析器,讓query解析器進行相應處理,再通過query分發器轉給相關處理子產品。
如果解析器解析後的結果是一個未被cache的select,則将控制權交給optimizer,也就是query優化器子產品。
如果是DML或是DDL,則交給表變更管理子產品,
如果是一些更新統計資訊、檢測、修複和整理類的query則會交給表維護子產品
複制相關的query則交給複制子產品
請求狀态的query交給狀态收集報告子產品
各個子產品收到query解析與分發子產品分為過來的請求後,首先通過通路控制子產品檢查連接配接使用者是否有通路目标表以及字段的權限,如果有,調用表管理子產品請求相應的表,并擷取對應的鎖。(表管理子產品會檢視該表是否在table cache中,如果已經打開則直接進行鎖相關處理,如果不在cache,則需要打開表檔案擷取鎖,然後将打開的表交給表管理子產品)
當表變更管理子產品擷取打開的表後,根據該表的相關meta資訊,判斷表的存儲引擎類型的其他相關資訊,根據表的存儲引擎類型,送出給存儲引擎接口子產品,調用對應的存儲引擎實作子產品,進行相應處理。(對于表變更管理子產品來說,可見是僅是存儲引擎所提供的一系列API,底層存儲引擎實作子產品的具體實作,對于表變更管理子產品來說是透明的,它隻需要調用對應的接口,指明表類型,接口子產品表根據表類型調用正确存儲引擎進行相應處理)
當一個query或是一個command處理完成(成功是失敗)後,控制權都會交給連接配接線程子產品。如果處理成功,則将處理結果通過連接配接線程傳回給用戶端,如果處理失敗,也會将相應的錯誤資訊發送給用戶端,然後連接配接線程子產品會進行相應的清理工作,并繼續等待後面的請求,重複上面提到的過程,或是完成用戶端斷開連接配接的請求。
如果上面過程中,相關子產品使資料庫中的資料發生成了變化,而且mysql打開了binlog,則對應的處理子產品會調用日志處理子產品将相應的變更語句以更新事件的形式記錄到相關參數指定的二進制日志檔案中。