mysql程式更新 MySQL 更新執行的過程

2021-10-22 10:06:11 字數 2783 閱讀 2259

mysql 查詢執行的過程鏈結

select語句的執行過程會經過聯結器、分析器、優化器、執行器、儲存引擎,同樣的 update語句也會同樣走一遍 select語句的執行過程。

但是和 select最大不同的是,update語句會涉及到兩個日誌的操作 redo log(重做日誌) 和 binlog (歸檔日誌)。

那麼 mysql中又是怎麼使用 redo log和 binlog?為什麼要使用 redo log和 binlog呢?直接執行更新然後存庫不就行了嗎?還要放在 redo log和binlog中,這不是多此一舉嗎?且聽我慢慢道來,這裡面大有文章。

redo log

大家都是知道 mysql是關係型資料庫,用來儲存資料的,在訪問資料庫量大的時候,mysql讀寫磁碟訪問的效率是非常低的,加上 sql中的條件對資料的篩選過濾,那麼效率就更低了。這也是為什麼引入非關係型資料庫作為作為資料快取原因,例如:redis、mongodb等,就是為了減少 sql執行期間的資料庫 io操作。

同樣的道理,若是每次執行 update語句都要進行磁碟 io操作、以及資料的過濾篩選,小量的訪問和資料量資料庫還可以撐住,那麼訪問量一大以及資料量一大,這樣資料庫肯定頂不住。基於上面的問題於是出現了redo log日誌,redo log日誌也叫做 wal技術(write-ahead logging),他是一種先寫日誌,並更新記憶體,最後再更新磁碟的技術,並且更新磁碟往往是在 mysql比較閒的時候,這樣就大大減輕了 mysql的壓力。

redo log的特點就是:redo log是固定大小,是物理日誌,屬於 innodb引擎的,並且寫 redo log是環狀寫日誌的形式:

如上圖所示:若是四組的redo log檔案,一組為1g的大小,那麼四組就是4g的大小,其中write pos是記錄當前的位置,有資料寫入當前位置,那麼write pos就會邊寫入邊往後移。而check point是擦除的位置,因為redo log是固定大小,所以當redo log滿的時候,也就是 write pos追上 check point的時候,需要清除 redo log的部分資料,清除的資料會被持久化到磁碟中,然後將 check point向前移動。redo log日誌實現了即使在資料庫出現異常宕機的時候,重啟後之前的記錄也不會丟失,這就是 crash-safe能力。

binlog

binlog稱為歸檔日誌,是邏輯上的日誌,它屬於 mysql server層面的日誌,記錄著 sql的原始邏輯,主要有兩種模式,乙個是statement格式記錄的是原始的sql,而row格式則是記錄行內容。那麼這樣看來 redo log和 binlog雖然記錄的形式、內容不同,但是這兩者日誌都能通過自己記錄的內容恢復資料,那麼為什麼還要這兩個日誌同時存在呢?只要其中乙個不就行了嘛,兩個同時存在不就多此一舉了嘛。且聽我慢慢道來,這裡面也大有文章。

因為剛開 mysql自帶的引擎 myisam就沒有 crash-safe功能的,並且在此之前 mysql還沒有 innodb引擎,mysql自帶的 binlog日誌只是用來歸檔日誌的,所以 innodb引擎也就通過自己 redo log日誌來實現 crash-safe功能。

update執行過程

上面說了那麼久兩種日誌的作用和特點,那麼這兩種日誌究竟和 update執行語句有什麼關係呢?先來看圖:

上面說過 select語句走過的流程 update語句也會走一遍,當來到執行器的時候:

執行器會呼叫引擎的讀介面,然後找到 id=2的資料行,因為 id是主鍵索引,索引按照樹的搜尋找到這一行, 若是資料行已經存在於記憶體的資料頁中就會立即將結果返回,若是不在記憶體中,就會從磁碟中進行載入到記憶體中,然後將查詢的結果返回。

執行器將返回的結果的age欄位+1,並呼叫引擎的寫介面寫入更新後的資料行。

引擎獲取到更新後的資料行更新到記憶體和redo log(也是寫入磁碟,順序寫入,比較快)中,並告訴執行器可以隨時提交事務,此時的 redo log處於 prepare階段。

執行器收到引擎的告知後,生成 binlog日誌,並且呼叫引擎的介面提交事務,引擎將 redo log的狀態修改為commit狀態,這樣這個更新操作算是完成。

兩階段提交

上面詳細的說了update語句的執行流程,提到了redo log的 prepare 和commit兩個階段,這就是兩階段提交,兩階段提交的目的是為了保證 redo log日誌與 binlog日誌保持資料的一致性。若是 redo log寫成功 binlog寫失敗,或者 redo log寫失敗 binlog寫成功,最後使用這兩者日誌進行資料恢復得到的結果資料都是不一致性的,所以為了保證兩個日誌邏輯上的一致,使用兩階段進行提交。

redo log 與 binlog的總結

最後來對比一下這兩種日誌:redo是物理的,binlog是邏輯的,redo的大小固定,並且以環狀的形式寫入資料,資料滿的時候需要將 redo日誌中擦除資料,並且將擦除的資料持久化到磁碟中。而 binlog以追加日誌的形式寫入,也就是當日誌寫到一定大小後,就會切換到下乙個,並不會覆蓋以前寫的日誌。binlog 是在 mysql server層中使用,因為 binlog沒有 crash-safe功能,所以 innodb引擎自己實現了 redo log日誌的 crash-safe的功能,為了保證這兩個日誌邏輯上的一致使用兩階段提交。在使用 redo和 binlog這兩種日誌的時候,可以將引數 innodb_flush_log_at_trx_commit和sync_binlog都設定為1,它表示每次事務提交的時候,都會將日誌持久化到磁碟中。

mysql查詢並更新 MySQL如何實現更新查詢?

update更新查詢的基本語法是 where update查詢的實現 讓我們考慮下表 data 其中包含四列 id firstname lastname 和 age 要更新 data 表中 id 為201的人員的 age 我們可以使用以下 使用過程方法更新查詢 link mysqli connect...

mysql程式更新 更新MySQL資料庫

當搞亂mysql的檔案系統時,你必須停止mysql伺服器.為避免在現場計算機上停機,請使用具有same version of mysql伺服器的備份 虛擬機器.當backup mysql伺服器停止時,將表 我假設.frm,myi等?複製到 var lib mysql backup db backup...

mysql更新時間 Mysql 更新時間

mysql時間加減函式為date add date sub 定義和用法 date add 函式向日期新增指定的時間間隔。date sub 函式向日期減少指定的時間間隔。語法date add date,interval expr type date sub date,interval expr typ...