SQL語句在MySQL中是如何執行的(一)


參考:

https://mp.weixin.qq.com/s?__biz=MzU3NDkwMjAyOQ==&mid=2247483894&idx=1&sn=43642fac89173db293d2a3739decb4ef&chksm=fd2a1b94ca5d92822ac4a8b97c4cc1323255f366a2f0114de7ee9ba1faa58ba2a85195dd126b&scene=178&cur_album_id=1552870102100983810#rd

https://juejin.cn/post/6844903811983622157

https://www.cnblogs.com/jasonbourne3/p/12530069.html

https://www.cnblogs.com/gusluo/p/11281687.html

https://www.cnblogs.com/gusluo/p/11250863.html

https://www.dazhuanlan.com/2019/10/23/5db04095c5885/

 

 

 

 

SQL語句在MySQL中是如何執行的

mysql> select * from T where ID=10;

開門見山,當我們輸入一條 SQL 語句的時候,MySQL 內部究竟執行了什么?直接上架構圖,我們才能對其有一個概念,而不要陷入細節之中。

架構

架構概況

大體上來說,MySQL 可以分為 Server 層與存儲引擎兩個部分。

  1. Server 層包括連接器、查詢緩存、分析器、優化器、執行器。
  2. 存儲引擎負責數據的存儲和讀取,其架構模式是插件式的,支持支持 InnoDB、MyISAM、Memory 等多個存儲引擎。現在最常用的存儲引擎是 InnoDB,它從 MySQL5.5.5 版本開始成為了默認存儲引擎。

所以不難看出,主要差別在於 Server 層,也就是連接器到執行器部分。接下來我們來說明上文的 SQL 語句到底在內部經歷了什么。

連接器

第一步,客戶端會先連接到數據庫,這個時候就是連接器來接待。它負責跟客戶端建立連接、獲取權限、維持和管理連接。

如果用戶名密碼正確,連接器就到權限表查詢你所擁有的的權限之后這個連接里面的權限判斷,都依賴於此時讀到的權限。

這就意味着,一個用戶成功建立連接后,被修改了權限,也不會影響已經存在的連接的權限。修改完成后,只有再重新建立的連接才會使用到新的權限設置。

建立連接的過程通常是比較復雜的,所以我建議你在使用中要盡量減少建立連接的動作,也就是盡量使用長連接。

另外說到這里就順便提一下,客戶端連接mysql服務器時,如果連接一直處於空閑狀態,那么到了一定的時候就會斷開連接,多長時間是由 wait_timeout 控制的,其默認是8個小時。如果超過8個小時,你執行操作數據庫時就回提示 “Lost connection to MySQL server during query”,這時只有重新連接數據庫方能進行操作。

說到連接器,咱們得說一下長連接和短鏈接。長連接就是如果客戶端一直都有請求操作數據庫,那么就會一直使用這個連接進行操作。短鏈接就是每次執行完很少的數據庫操作就斷開連接了,如果再有請求就必須重新連接。

所以這里建議減少數據庫的連接操作,盡量使用長連接。但是長時間使用長連接會導致一個問題,那就是mysql的占用的內存會越來越大,甚至到最后可能會出現OOM情況,導致mysql異常重啟,那么這就尷尬了。

針對上面的情況有兩種解決辦法:

(1)、定期斷開長連接,或者斷開一些查詢占用內存比較大的操作的連接,釋放資源。

(2)、如果是5.7及以上版本,可以使用 mysql_reset_connection 來重置連接,但是需要注意以下幾點

  • 活躍事務會被回滾,自動提交模式也會被重置;
  • 釋放所有表鎖;
  • 關閉&刪除所有臨時表;
  • 會話變量(選項)被重置成和全局變量一致;
  • 用戶級變量丟失;
  • PREPARE語句會被釋放(其相應的HANDLER也會被關閉);
  • LAST_INSERT_ID值重置為0;
  • 利用GET_LOCK獲取的鎖會被釋放。

以上是mysql官微給出的解釋,所以重置連接的時候以上因素,以免對數據庫中的數據產生影響。

 

查詢緩存

連接建立好了以后,就可以執行 select 語句了,執行邏輯進入第二步:查詢緩存。

MySQL 拿到一個查詢語句,會先查詢緩存,先校驗這個語句是否執行過,以 key-value 的形式存在內存里, Key 是查詢預計,Value 是結果集。如果緩存 key 被命中,就會直接返回給客戶端,如果沒有命中,就會執行后續的操作,完成后也會把結果緩存起來,方便下一次調用。當然在真正執行緩存查詢的時候還是會校驗用戶的權限,是否有該表的查詢條件。

Mysql 查詢不建議使用緩存,因為對於經常更新的數據來說,緩存的有效時間太短了,往往帶來的效果並不好,對於不經常更新的數據來說,使用緩存還是可以的,Mysql 8.0 版本后刪除了緩存的功能,官方也是認為該功能在實際的應用場景比較少,所以干脆直接刪掉了。

分析器

如果沒有命中緩存,那么就進入分析器,主要就是分析 SQL 語句是拿來干嘛,也就是解析該語句生成語法樹,會分為兩步:

  1. 第一步:詞法分析, 一條 SQL 語句有多個字符串組成,首先要提取關鍵字,比如 select,提出查詢的表,提出字段名,提出查詢條件等等。做完這些操作后,就會進入第二步。
  2. 第二步:語法分析,主要就是判斷你輸入的 SQL 是否正確,是否符合 MySQL 的語法。,主要就是判斷你輸入的 SQL 是否正確,是否符合 MySQL 的語法。

優化器

經過了分析器分析,MySQL 知道你要干啥了,在開始執行之前,還要先經過優化器的處理。

優化器的作用就是它認為的最優的執行方案去執行(雖然有時候也不是最優),比如多個索引的時候該如何選擇索引,多表查詢的時候如何選擇關聯順序等。

select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;

比如這條語句,既可以先從表 t1 里面取出 c=10 的記錄的 ID 值,再根據 ID 值關聯到表 t2,再判斷 t2 里面 d 的值是否等於 20。也可以先從表 t2 里面取出 d=20 的記錄的 ID 值,再根據 ID 值關聯到 t1,再判斷 t1 里面 c 的值是否等於 10。

這兩種的執行邏輯結果是一樣的,但是執行效率會有不同,而優化器就是決定使用哪種方案。

執行器

當選擇了執行方案后,MySQL 就准備開始執行了,首先執行前會校驗該用戶有沒有權限,如果沒有權限,就會返回錯誤信息,如果有權限,就會去調用引擎的接口,返回接口執行的結果。這里的權限其實就是第一步客戶端連接到連接器然后去查詢出來的權限信息。

InnoDB 引擎更新數據的操作其實還會涉及到兩個日志模塊的操作,以后會專門分析。主要就是 binlog 以及 redolog 的操作。

InnoDB 引擎把數據保存在內存中,同時記錄 redo log,此時 redo log 進入 prepare 狀態,然后告訴執行器,執行完成了,隨時可以提交。執行器收到通知后記錄 binlog,然后調用引擎接口,提交 redo log 為提交狀態,更新完成。

總結

  • Mysql 主要分為 Server 層和引擎層,Server 層主要包括連接器、查詢緩存、分析器、優化器、執行器,同時還有一個日志模塊(binlog),這個日志模塊所有執行引擎都可以共用。
  • 引擎層是插件式的,目前主要包括,MyISAM,InnoDB,Memory 等。
  • 查詢語句的執行流程如下:權限校驗(如果命中緩存)---》查詢緩存---》分析器---》優化器---》權限校驗---》執行器---》引擎 。
  • 更新語句執行流程如下:分析器----》權限校驗----》執行器---》引擎---redo log(prepare 狀態---》binlog---》redo log(commit 狀態) 。

參考

《MySQL 專欄 45 講》

 

 

 

 

 

 

 

sql執行過程分析

本篇文章會分析一個 sql 語句在 MySQL 中的執行流程,包括 sql 的查詢在 MySQL 內部會怎么流轉,sql 語句的更新是怎么完成的。

在分析之前我會先帶着你看看 MySQL 的基礎架構,知道了 MySQL 由那些組件組成以及這些組件的作用是什么,可以幫助我們理解和解決這些問題。

MySQL 基礎架構分析

1.1 MySQL 基本架構概覽

下圖是 MySQL 的一個簡要架構圖,從下圖你可以很清晰的看到用戶的 SQL 語句在 MySQL 內部是如何執行的。

先簡單介紹一下下圖涉及的一些組件的基本作用幫助大家理解這幅圖

  • 連接器: 身份認證和權限相關(登錄 MySQL 的時候)。

  • 查詢緩存: 執行查詢語句的時候,會先查詢緩存(MySQL 8.0 版本后移除,因為這個功能不太實用)。

  • 分析器: 沒有命中緩存的話,SQL 語句就會經過分析器,分析器說白了就是要先看你的 SQL 語句要干嘛,再檢查你的 SQL 語句語法是否正確。

  • 優化器: 按照 MySQL 認為最優的方案去執行。

  • 執行器: 執行語句,然后從存儲引擎返回數據。

 

 
    簡單來說 MySQL 主要分為 Server 層和存儲引擎層:

 

  • Server 層:主要包括連接器、查詢緩存、分析器、優化器、執行器等,所有跨存儲引擎的功能都在這一層實現,比如存儲過程、觸發器、視圖,函數等,還有一個通用的日志模塊 binglog 日志模塊。

  • 存儲引擎: 主要負責數據的存儲和讀取,采用可以替換的插件式架構,支持 InnoDB、MyISAM、Memory 等多個存儲引擎,其中 InnoDB 引擎有自有的日志模塊 redolog 模塊。現在最常用的存儲引擎是 InnoDB,它從 MySQL 5.5.5 版本開始就被當做默認存儲引擎了。

1.2 Server 層基本組件介紹

  1. 連接器

連接器主要和身份認證和權限相關的功能相關,就好比一個級別很高的門衛一樣。 主要負責用戶登錄數據庫,進行用戶的身份認證,包括校驗賬戶密碼,權限等操作,如果用戶賬戶密碼已通過,連接器會到權限表中查詢該用戶的所有權限,之后在這個連接里的權限邏輯判斷都是會依賴此時讀取到的權限數據,也就是說,后續只要這個連接不斷開,即時管理員修改了該用戶的權限,該用戶也是不受影響的。

  1. 查詢緩存(MySQL 8.0 版本后移除)

查詢緩存主要用來緩存我們所執行的 SELECT 語句以及該語句的結果集。

連接建立后,執行查詢語句的時候,會先查詢緩存,MySQL 會先校驗這個 sql 是否執行過,以 Key-Value 的形式緩存在內存中,Key 是查詢預計,Value 是結果集。如果緩存 key 被命中,就會直接返回給客戶端,如果沒有命中,就會執行后續的操作,完成后也會把結果緩存起來,方便下一次調用。當然在真正執行緩存查詢的時候還是會校驗用戶的權限,是否有該表的查詢條件。

MySQL 查詢不建議使用緩存,因為查詢緩存失效在實際業務場景中可能會非常頻繁,假如你對一個表更新的話,這個表上的所有的查詢緩存都會被清空。對於不經常更新的數據來說,使用緩存還是可以的。

所以,一般在大多數情況下我們都是不推薦去使用查詢緩存的。

MySQL 8.0 版本后刪除了緩存的功能,官方也是認為該功能在實際的應用場景比較少,所以干脆直接刪掉了。

  1. 分析器

MySQL 沒有命中緩存,那么就會進入分析器,分析器主要是用來分析 SQL 語句是來干嘛的,分析器也會分為幾步:

第一步,詞法分析,一條 SQL 語句有多個字符串組成,首先要提取關鍵字,比如 select,提出查詢的表,提出字段名,提出查詢條件等等。做完這些操作后,就會進入第二步。

第二步,語法分析,主要就是判斷你輸入的 sql 是否正確,是否符合 MySQL 的語法。

完成這 2 步之后,MySQL 就准備開始執行了,但是如何執行,怎么執行是最好的結果呢?這個時候就需要優化器上場了。

  1. 優化器

優化器的作用就是它認為的最優的執行方案去執行(有時候可能也不是最優,這篇文章涉及對這部分知識的深入講解),比如多個索引的時候該如何選擇索引,多表查詢的時候如何選擇關聯順序等。

可以說,經過了優化器之后可以說這個語句具體該如何執行就已經定下來。

  1. 執行器

當選擇了執行方案后,MySQL 就准備開始執行了,首先執行前會校驗該用戶有沒有權限,如果沒有權限,就會返回錯誤信息,如果有權限,就會去調用引擎的接口,返回接口執行的結果。

二 語句分析

2.1 查詢語句

說了以上這么多,那么究竟一條 sql 語句是如何執行的呢?其實我們的 sql 可以分為兩種,一種是查詢,一種是更新(增加,更新,刪除)。我們先分析下查詢語句,語句如下:

select * from tb_student A where A.age='18' and A.name=' 張三 ';

結合上面的說明,我們分析下這個語句的執行流程:

  • 先檢查該語句是否有權限,如果沒有權限,直接返回錯誤信息,如果有權限,在 MySQL8.0 版本以前,會先查詢緩存,以這條 sql 語句為 key 在內存中查詢是否有結果,如果有直接緩存,如果沒有,執行下一步。

  • 通過分析器進行詞法分析,提取 sql 語句的關鍵元素,比如提取上面這個語句是查詢 select,提取需要查詢的表名為 tb_student,需要查詢所有的列,查詢條件是這個表的 id='1'。然后判斷這個 sql 語句是否有語法錯誤,比如關鍵詞是否正確等等,如果檢查沒問題就執行下一步。

  • 接下來就是優化器進行確定執行方案,上面的 sql 語句,可以有兩種執行方案:

    a.先查詢學生表中姓名為“張三”的學生,然后判斷是否年齡是 18。

    b.先找出學生中年齡 18 歲的學生,然后再查詢姓名為“張三”的學生。

    那么優化器根據自己的優化算法進行選擇執行效率最好的一個方案(優化器認為,有時候不一定最好)。那么確認了執行計划后就准備開始執行了。

  • 進行權限校驗,如果沒有權限就會返回錯誤信息,如果有權限就會調用數據庫引擎接口,返回引擎的執行結果。

2.2 更新語句

以上就是一條查詢 sql 的執行流程,那么接下來我們看看一條更新語句如何執行的呢?sql 語句如下:

update tb_student A set A.age='19' where A.name=' 張三 ';

我們來給張三修改下年齡,在實際數據庫肯定不會設置年齡這個字段的,不然要被技術負責人打的。其實條語句也基本上會沿着上一個查詢的流程走,只不過執行更新的時候肯定要記錄日志啦,這就會引入日志模塊了,MySQL 自帶的日志模塊式 binlog(歸檔日志) ,所有的存儲引擎都可以使用,我們常用的 InnoDB 引擎還自帶了一個日志模塊 redo log(重做日志),我們就以 InnoDB 模式下來探討這個語句的執行流程。流程如下:

  • 先查詢到張三這一條數據,如果有緩存,也是會用到緩存。
  • 然后拿到查詢的語句,把 age 改為 19,然后調用引擎 API 接口,寫入這一行數據,InnoDB 引擎把數據保存在內存中,同時記錄 redo log,此時 redo log 進入 prepare 狀態,然后告訴執行器,執行完成了,隨時可以提交。
  • 執行器收到通知后記錄 binlog,然后調用引擎接口,提交 redo log 為提交狀態。
  • 更新完成。

這里肯定有同學會問,為什么要用兩個日志模塊,用一個日志模塊不行嗎?

這是因為最開始 MySQL 並沒與 InnoDB 引擎( InnoDB 引擎是其他公司以插件形式插入 MySQL 的) ,MySQL 自帶的引擎是 MyISAM,但是我們知道 redo log 是 InnoDB 引擎特有的,其他存儲引擎都沒有,這就導致會沒有 crash-safe 的能力(crash-safe 的能力即使數據庫發生異常重啟,之前提交的記錄都不會丟失),binlog 日志只能用來歸檔。

並不是說只用一個日志模塊不可以,只是 InnoDB 引擎就是通過 redo log 來支持事務的。那么,又會有同學問,我用兩個日志模塊,但是不要這么復雜行不行,為什么 redo log 要引入 prepare 預提交狀態?這里我們用反證法來說明下為什么要這么做?

  • 先寫 redo log 直接提交,然后寫 binlog,假設寫完 redo log 后,機器掛了,binlog 日志沒有被寫入,那么機器重啟后,這台機器會通過 redo log 恢復數據,但是這個時候 bingog 並沒有記錄該數據,后續進行機器備份的時候,就會丟失這一條數據,同時主從同步也會丟失這一條數據。
  • 先寫 binlog,然后寫 redo log,假設寫完了 binlog,機器異常重啟了,由於沒有 redo log,本機是無法恢復這一條記錄的,但是 binlog 又有記錄,那么和上面同樣的道理,就會產生數據不一致的情況。

如果采用 redo log 兩階段提交的方式就不一樣了,寫完 binglog 后,然后再提交 redo log 就會防止出現上述的問題,從而保證了數據的一致性。那么問題來了,有沒有一個極端的情況呢?假設 redo log 處於預提交狀態,binglog 也已經寫完了,這個時候發生了異常重啟會怎么樣呢? 這個就要依賴於 MySQL 的處理機制了,MySQL 的處理過程如下:

  • 判斷 redo log 是否完整,如果判斷是完整的,就立即提交。

  • 如果 redo log 只是預提交但不是 commit 狀態,這個時候就會去判斷 binlog 是否完整,如果完整就提交 redo log, 不完整就回滾事務。

這樣就解決了數據一致性的問題。

三 總結

•MySQL 主要分為 Server 層和引擎層,Server 層主要包括連接器、查詢緩存、分析器、優化器、執行器,同時還有一個日志模塊(binlog),這個日志模塊所有執行引擎都可以共用,redolog 只有 InnoDB 有。 •引擎層是插件式的,目前主要包括,MyISAM,InnoDB,Memory 等。 •SQL 等執行過程分為兩類,一類對於查詢等過程如下:權限校驗---》查詢緩存---》分析器---》優化器---》權限校驗---》執行器---》引擎 •對於更新等語句執行流程如下:分析器----》權限校驗----》執行器---》引擎---redo log prepare---》binlog---》redo log commit


作者:thekingisalwayslucky
鏈接:https://juejin.cn/post/6844903811983622157
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

 

 

 

 

 

 

update語句執行過程

  以下面的一條sql為例 (ID為主鍵)

update T set b=b+1 where ID = 2
  1. 客戶端通過連接器與mysql建立連接 
  2. 刪除要update表的緩存
  3. 分析器解析sql並判斷是否含有語句錯誤
  4. 優化器確定查詢索引
  5. 執行器調用Innodb存儲引擎接口獲取ID=2的數據行。
  6. Innodb存儲引擎掃描主鍵索引查找到ID=2的行返回給server層。
  7. 執行器將B+1 調用存儲引擎接口寫入該行數據。
  8. Innodb存儲引擎將數據保存在內存中(WAL)。
  9. Innodb存儲引擎寫redo日志,prepare狀態,通知Server層。
  10. server層 提交Binlog后通知Innodb存儲引擎。
  11. Innodb存儲引擎將redo日志commit。

  至此一條update語句就執行完成了。

  redo日志:Innodb存儲引擎特有的機制,可以用來應對異常恢復,Crash-safe,redo可以保證mysql異常重啟時,將未提交的事務回滾,已提交的事務安全落庫。

  二階段提交:redo(perpare)--->binlog-->redo(commit) 保證了mysql在異常重啟的時候,數據的一致性,在任意環節出錯,都可以保證redo日志和binlog的一致性。

  WAL:第8個步驟,innodb沒有直接將數據落盤,而是存在內存中,並記錄日志,這里用到的技術就是WAL(Write-Ahead Logging)。數據在持久化硬盤前,如果mysql異常重啟,innodb可以根據redo日志將未持久化的數據恢復。redo日志是有大小限制的,循環寫,當redo快要寫滿時,將redo日志頭部的記錄清理,擦除記錄前要把內存記錄更新到數據文件。

  binLog: binlog 記錄的是邏輯日志,是mysql的歸檔日志,支持所有引擎使用。與redo不同的是,binlog是不限制大小,文件追加寫。

這里將老師的圖貼上(對應的5--11的步驟)

  

 

 

 

 

一條更新sql的執行過程

update scores set  score=c+10 where id=1

上面一條sql是將id為1的分數加上10。

那么它的執行流程是怎樣的呢?借用上篇文章的圖,如下:

我這邊就再簡單的說一下這個流程,首先客戶端連接mysql服務器,連接后執行sql語句,執行sql的過程需要經過分析器得出它是需要做update操作,再接着經過優化器它決定使用id這個索引,然后經過執行器通過索引找到這一行,最后進行更新操作。

以上就是整個更新操作得整個流程。說到這你肯定以為說完了,不過很遺憾的告訴你,這才剛剛開始呢。

因為更新操作和查詢操作不一樣,更新操作涉及到兩個非常重要的日志模塊。redo log (重做日志) 和 bin log(歸檔日志)。這個兩個才是今天要說的重點。

首先咱們得知道這兩個日志是什么?然后再得知道它們是干什么的?

redo log 是 InnoDB 引擎特有,它是屬於物理日志,主要用於記錄 “某個數據頁上做了什么修改” ,而且它的記錄空間是固定的並且是會用完的。

bin log 是屬於 server 層持有的,主要是再執行器中記錄日志,所以mysql所有的引擎都可以使用它。bin log 是屬於邏輯日志,它有 statement 和 row 兩種模式,statement記錄的是執行的sql語句,row記錄的是更新行的內容,所以是記錄兩條,一條是更新前的內容,另外一條是更新后的內容。默認模式是 row 模式。另外 bin log 是會追加寫入日志,當日志文件寫到一定大小的時候,就會切換到下一個繼續寫入日志,並且不會覆蓋之前的日志文件。

以上就是這兩種日志的概念以及作用,那么現在我們說說它們的記錄流程。咱們先看下面一張圖,黃填充色的為執行器的操作,藍填充色為InnoDB引擎的操作

 

圖有點長,不過應該很容易看懂。那么現在就來一步一步的分析。

1、首先執行器會找引擎取id=1這條數據;

2、因為id是主鍵,所以使用樹來找到一行數據。不過引擎先去內存中查找是否有這一頁數據;

3、如果有則直接返回數據給執行器;如果沒有就會去磁盤把數據讀入到內存中,然后返回數據給執行器。

4、執行器就會執行C+10操作;

5、執行器生成新的一行數據;

6、再調用 InnoDB 引擎的寫入接口,把數據更新到內存中;

7、InnoDB 引擎寫入 redo log 日志,標記狀態為 prepare,並且告訴執行器已經更新數據完成,可以隨時提交事務;

8、執行器把此操作寫入 bin log ,並且把 bin log 寫入磁盤;

9、最后執行器調用引擎的提交事務接口,引擎把 redo log 的狀態改 commit ,至此整個更新操作完成。

 

看到這里也許你會冒出幾個問題?

1、redo log 空間是固定,那它會不會用完呢?

首先不用擔心 redo log 會用完空間,因為它是循環利用的。例如 redo log 日志配置為一組4個文件,每個文件分別為1G。它寫的流程如下圖:

上圖中有兩塊填充色,黃色和紅色,黃色標記着 check point,這表示這當前擦除掉 redo log 的位置,紅色標記着 write pos ,這表示着當前記錄 redo log 的位置。當 redo log 寫滿了之后,就會停下來,不再寫入數據,會執行擦除 redo log 操作,當然在擦除這些日志之前,都會把數據寫入到磁盤中,把數據進行持久化。這樣才能保住數據的准確性。

2、為什么要用這兩種日志呢?因為在沒有 InnoDB 引擎的時候是沒有 redo log 日志的。

因為 InnoDB 引擎的 redo log 可以保證即使數據庫突然宕機了或者異常重啟了,之前提交的數據是不會丟失的。這個能力咱們稱之為 crash-safe。

3、當mysql服務器在執行過程中突然間宕機了,數據會不會丟失?

 答案是不會。為什么這么肯定呢?我們可以從第二張圖就可以看出來。比如有以下幾種情況:

1、寫入 redo log 之前宕機了,那么原始數據是不會發送改變的,因為還沒有進行事務的提交。

2、如果寫入 redo log 之后,寫入 bin log之前宕機,那么原始數據還是不會變,因為數據庫重啟后,因為兩種日志的記錄沒有同步,所以不會有新數據生成。

3、在 redo log 生成commit之前宕機了,數據庫重啟后 數據會變成更新后的數據,因為這個時候 redo log 和 bin log 都有了記錄,所以數據庫重啟后會自己進行commit,所以這時候的數據就是更新后的數據了。

我們使用 redo log 主要是需要保證 crash-safe 能力,innodb_flush_log_at_trx_commit這個參數設置成1的時候,表示每次事務的redo log都直接持久化到磁盤。這個參數我建議你設置成1,這樣可以保證MySQL異常重啟之后數據不丟失。

sync_binlog這個參數設置成1的時候,表示每次事務的binlog都持久化到磁盤。這個參數我也建議你設置成1,這樣可以保證MySQL異常重啟之后binlog不丟失。

 

 

 

 

為什么mysql更新的效率很高?

  1. WAL機制:即更新內存中數據頁,同時寫redolog+binglog然后返回。后台慢慢將數據頁刷到磁盤中。(隨機寫改為順序寫
  2. mysql的chagen buffer。

 

 


免責聲明!

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



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