mysql網路架構 MySQL 整體架構一覽

2021-10-18 11:44:32 字數 3656 閱讀 7263

mysql 在整體架構上分為 server 層和儲存引擎層。其中 server 層,包括聯結器、查詢快取、分析器、優化器、執行器等,儲存過程、觸發器、檢視和內建函式都在這層實現。資料引擎層負責資料的儲存和提取,如 innodb、myisam、memory 等引擎。在客戶端連線到 server 層後,server 會呼叫資料引擎提供的介面,進行資料的變更。

聯結器負責和客戶端建立連線,獲取使用者許可權以及維持和管理連線。

通過 show processlist; 來查詢連線的狀態。在使用者建立連線後,即使管理員改變連線使用者的許可權,也不會影響到已連線的使用者。預設連線時長為 8 小時,超過時間後將會被斷開。

簡單說下長連線:

優勢:在連線時間內,客戶端一直使用同一連線,避免多次連線的資源消耗。

劣勢:在 mysql 執行時,使用的記憶體被連線物件管理,由於長時間沒有被釋放,會導致系統記憶體溢位,被系統kill. 所以需要定期斷開長連線,或執行大查詢後,斷開連線。mysql 5.7 後,可以通過 mysql_rest_connection 初始化連線資源,不需要重連或者做許可權驗證。

查詢快取

當接受到查詢請求時,會現在查詢快取中查詢(key/value儲存),是否執行過。沒有的話,再走正常的執行流程。

但在實際情況下,查詢快取一般沒有必要設定。因為在查詢涉及到的表被更新時,快取就會被清空。所以適用於靜態表。在 mysql8.0 後,查詢快取被廢除。

分析器詞法分析:

如識別 select,表名,列名,判斷其是否存在等。

語法分析:

判斷語句是否符合 mysql 語法。

優化器確定索引的使用,join 表的連線順序等,選擇最優化的方案。

執行器在具體執行語句前,會先進行許可權的檢查,通過後使用資料引擎提供的介面,進行查詢。如果設定了慢查詢,會在對應日誌中看到 rows_examined 來表示掃瞄的行數。在一些場景下(索引),執行器呼叫一次,但在資料引擎中掃瞄了多行,所以引擎掃瞄的行數和 rows_examined 並不完全相同。

不預先檢查許可權的原因:如像觸發器等情況,需要在執行器階段才能確定許可權,在優化器階段無法驗證。

mysql 日誌模組

如前面所說,mysql 整體分為 server 層和資料引擎層,而每層也對應了自己的日誌檔案。如果選用的是 innodb 引擎,對應的是 redo log 檔案。server 層則對應了 binlog 檔案。至於為什麼存在了兩種日誌系統,咱們往下看。

redo log

redo log 是 innodb 特有日誌,為什麼要引入 redo log 呢,想象這樣乙個場景,mysql 為了保證永續性是需要把資料寫入磁碟檔案的。我們知道,在寫入磁碟時,會進行檔案的 io,查詢操作,如果每次更新操作都這樣的話,整體的效率就會特別低,根本沒法使用。

既然直接寫入磁碟不行,解決方法就是先寫進記憶體,在系統空閒時再更新到磁碟就可以了。但光更新記憶體不行,假如系統出現異常宕機和重啟,記憶體中沒有被寫入磁碟的資料就會被丟掉,資料的一致性就出現問題了。這時 redo log 就發揮了作用,在更新操作發生時,innodb 會先寫入 redo log 日誌(記錄了資料發生了怎麼樣的改變),然後更新記憶體,最後在適當的時間再寫入磁碟。先寫日誌,在寫磁碟的操作,就是常說到的 wal (write-ahead- logging)技術。

redo log 的出現,除了在效率上有了很大的改善,還保證了 mysql 具有了 crash-safe 的能力,在發生異常情況下,不會丟失資料。

在具體實現上 redo log 的大小是固定的,可配置一組為 4 個檔案,每個檔案 1gb,更新時對四個檔案進行迴圈寫入。

write pos 記錄當前寫入的位置,寫完就後移,當第寫入第 4 個檔案的末尾時,從第 0 號位置重新寫入。

check point 表示當前可以擦除的位置,當資料更新到磁碟時,check point 就向後移動。

write pos 和 check point 之間的位置,就是可以記錄更新操作的空間。當 write pos 追上 check point ,不在能執行新的操作,先讓 check point 去寫入一些資料。

可以將 innodb_flush_log_at_trx_commit 設定成 1,開啟 redo log 持久化的能力。

binlog

binlog 則是 server 層的日誌,主要用於歸檔,在備份,主備同步,恢復資料時發揮作用,常見的日誌格式有 row, mixed, statement 三種。具體的使用方法可以參見 binlog 恢復日誌這篇。

可以通過 sync_binlog=1 開啟 binlog 寫入磁碟。

這裡對 binlog 和 redo 進行下區分:

所有者不同,binlog 是 server 層,所有引擎都可使用。redo log 是 innodb 特有的。

型別不同,binlog 是邏輯日誌,記錄的是語句的原始邏輯(比 statement)。redo log 是物理日誌,記錄某個資料頁被做了怎樣的修改。

資料寫入的方式不同,binog 日誌會一直追加,而 redo log 是迴圈寫入。

功能不同,binlog 用於歸檔,而 redo log 用於保證 crash-safe.

兩階段提交

一條更新語句,在 innodb 引擎下的更新過程如下。在更新記憶體後,將寫入 redolog 和寫入 binlog 放在一起成為乙個事務最後一起寫入 redo log 和 binlog 的過程就是常說的兩階段提交。用於保證當有意外情況發生時,資料的一致性。

這裡假設下,如果不採用兩階段提交會發生什麼?

先寫 redo log 後寫 binlog. 假設在寫入 redo log 後,mysql 發生異常重啟,此時 binlog 沒有寫入。在重啟後,由於 redolog 已經寫入,此時資料庫的內容是沒有問題的。但此時,如果想要拿 binlog 進行備份或恢復,發現會少了最後一條的更新邏輯,導致資料不一致。

先寫 binlog 和 redo log. binlog 寫入後,mysql 異常重啟,redo log 沒有寫入。此時重啟後,發現 redo log 沒有成功寫入,任務這個事務無效,而此時 binlog 卻多了一條更新語句,拿去恢復後自然資料也是不一致的。

再分析下兩階段提交的過程:

在寫 redo log prepare階段奔潰,重啟後,發現 redo log 沒寫入,發現此次事務。

如果在寫 binlog 時奔潰,重啟後,發現 binlog 未被寫入,回滾操作

如果在寫入 redo log 和 binlog 後崩潰,重啟後,發現沒提交,則進行 commit.

小節在文章開始部分,說明了 mysql 的整體架構分為 server 層和引擎層,並簡要說明了一條語句的執行過程。接著 mysql 在 5.5 後選用 innodb 作為預設的引擎,就是因為比原生的 myisam 多了事務以及 crash-safe 的能力。

而 crash-safe 就是由 redo log 實現的。與 redo log 類似的日誌檔案還有 binlog,是 server 引擎的日誌,用於歸檔和備份資料。

最後提到了,為了保證資料的一致性,將 redo log 和 binlog 放入相同的事務中,也就是常提到的兩階段提交操作。

mysql 字串中取整 MySQL取整

對乙個表取任意隨機數 select from tmp xf test where id select floor rand select max id from tmp xf test order by id limit 1 有條件性的取隨機數 select from tmp xf test whe...

mysql架構 MySQL的基礎架構

mysql是關聯式資料庫,關聯式資料庫,顧名思義,是建立在關係模型基礎上的資料庫,我們現實世界中的各種實體以及實體之間的各種聯絡一般可用關係模型來表示。經過數十年的發展,關聯式資料庫在理論和工業實踐中都已經發展到很成熟的地步,可以說,目前的絕大部分應用,使用mysql都有成熟的解決方案。資料庫的架構...

mysql架構介紹 Mysql邏輯架構介紹

總體概覽 和其它資料庫相比,mysql有點與眾不同,它的架構可以在多種不同場景中應用並發揮良好作用。主要體現在儲存引擎的架構上,外掛程式式的儲存引擎架構將查詢處理和其它的系統任務以及資料的儲存提取相分離。這種架構可以根據業務的需求和實際需要選擇合適的儲存引擎。1.連線層 最上層是一些客戶端和連線服務...