那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一條SQL更新語(yǔ)句的執(zhí)行流程2

jf_78858299 ? 來(lái)源:蟬沐風(fēng)的碼場(chǎng) ? 作者: 蟬沐風(fēng) ? 2023-03-03 10:02 ? 次閱讀

3.3 redo日志的系統(tǒng)變量

redo日志位于MySQL數(shù)據(jù)目錄下,默認(rèn)有ib_logfile0ib_logfile1兩個(gè)文件,如下圖所示。

圖片

可以發(fā)現(xiàn),兩個(gè)redo日志文件的大小都是50331648,默認(rèn)48MB。為什么這個(gè)大小是固定的呢?因?yàn)槿绻覀円褂庙樞騃/O,就必須在申請(qǐng)磁盤(pán)空間的時(shí)候一次性決定申請(qǐng)的空間大小,這樣才能保證申請(qǐng)的磁盤(pán)空間在地址上的連續(xù)性。

這也就決定了redo日志的舊數(shù)據(jù)會(huì)被覆蓋,一旦文件被寫(xiě)滿,就會(huì)觸發(fā)Buffer Pool臟頁(yè)到磁盤(pán)的同步,以騰出額外空間記錄后面的修改。

可以通過(guò)以下指令查看redo日志的系統(tǒng)屬性。

mysql> show variables like 'innodb_log%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| innodb_log_buffer_size      | 16777216 |
| innodb_log_checksums        | ON       |
| innodb_log_compressed_pages | ON       |
| innodb_log_file_size        | 50331648 |
| innodb_log_files_in_group   | 2        |
| innodb_log_group_home_dir   | ./       |
| innodb_log_write_ahead_size | 8192     |
+-----------------------------+----------+
參數(shù)名稱(chēng) 含義
innodb_log_file_size 指定每個(gè)redo日志文件的大小,默認(rèn)48MB
innodb_log_files_in_group 指定redo日志文件的數(shù)量,默認(rèn)2
innodb_log_group_home_dir 指定redo文件的路徑,如果不指定,則默認(rèn)為datadir目錄

介紹到這里,讀者朋友可以發(fā)現(xiàn),我們剛才探索的是如何讓已經(jīng)提交的事務(wù)保持持久化,但是如果某些事務(wù)偏偏在執(zhí)行到一半的時(shí)候出現(xiàn)問(wèn)題怎么辦?

事務(wù)的原子性要求事務(wù)中的所有操作要么都成功,要么都失敗,不允許存在中間狀態(tài)。就好比我在寫(xiě)這篇文章的時(shí)候,會(huì)時(shí)不時(shí)地敲一下ctrl+Z返回到上一步或者過(guò)去好幾步之前的狀態(tài),MySQL也需要“留一手”,把事務(wù)回滾時(shí)需要的東西都記錄下來(lái)。

比如,插入數(shù)據(jù)的時(shí)候,至少應(yīng)該把新增的這條記錄的主鍵的值記錄下來(lái),這樣回滾的時(shí)候只要把這個(gè)主鍵值對(duì)應(yīng)的記錄刪除就可以了。

MySQL又一個(gè)鼎鼎大名的日志—— undo日志 ,正式登場(chǎng)!

4. undo日志

undo log(撤銷(xiāo)日志或回滾日志)記錄了事務(wù)發(fā)生之前的數(shù)據(jù)狀態(tài),分為insert undo log和update undo log。

如果修改數(shù)據(jù)時(shí)出現(xiàn)異常,可以用 undo log來(lái)實(shí)現(xiàn)回滾操作(保持原子性)。可以理解為undo日志記錄的是反向的操作,比如INSERT操作會(huì)記錄DELETE,UPDATE會(huì)記錄UPDATE之前的值,和redo日志記錄在哪個(gè)物理頁(yè)面做了什么操作不同,所以這是一種邏輯格式的日志。

undo日志和redo日志與事務(wù)密切相關(guān),被統(tǒng)稱(chēng)為「事務(wù)日志」。

圖片

關(guān)于undo日志,我們目前只需要了解這么多即可

5. SQL更新語(yǔ)句的執(zhí)行總結(jié)——初版

有了事務(wù)日志之后,我們來(lái)簡(jiǎn)單總結(jié)一下更新操作的流程,這是一個(gè)簡(jiǎn)化的過(guò)程。

name 原值是chanmufeng

update t_user_innodb set name ='chanmufeng1994' where id = 1;
  1. 事務(wù)開(kāi)始,從內(nèi)存(Buffer Pool)或磁盤(pán)取到包含這條數(shù)據(jù)的數(shù)據(jù)頁(yè),返回給 Server 的執(zhí)行器;
  2. Server 的執(zhí)行器修改數(shù)據(jù)頁(yè)的這一行數(shù)據(jù)的值為 chanmufeng1994;
  3. 記錄 name=chanmufeng 到undo log;
  4. 記錄 name=chanmufeng1994到redo log;
  5. 調(diào)用存儲(chǔ)引擎接口,記錄數(shù)據(jù)頁(yè)到Buffer Pool(修改 name=penyuyan);
  6. 事務(wù)提交。

6. binlog日志

之前我們講過(guò),從MySQL整體架構(gòu)來(lái)看,其實(shí)可以分成兩部分

  • Server 層,它主要做的是 MySQL功能層面的事情,比如處理連接、解析優(yōu)化等;
  • 存儲(chǔ)引擎層,負(fù)責(zé)存儲(chǔ)相關(guān)的具體事宜。

redo日志是InnoDB存儲(chǔ)引擎特有的日志,而Server層也有自己的日志,稱(chēng)為 binlog(歸檔日志),它可以被所有存儲(chǔ)引擎使用。

6.1 為什么有了redo日志還需要 binlog?

我想你可能會(huì)問(wèn)出這個(gè)問(wèn)題,實(shí)際上,更準(zhǔn)確的問(wèn)法是為什么有了binlog還需要有redo日志?主要有以下幾個(gè)原因。

  1. 因?yàn)樽铋_(kāi)始MySQL里并沒(méi)有InnoDB存儲(chǔ)引擎。MySQL自帶的引擎是MyISAM,但是 MyISAM沒(méi)有崩潰恢復(fù)的能力,InnoDB后來(lái)以插件的形式被引入,順便帶來(lái)了redo日志;
  2. binlog日志是用來(lái)歸檔的,binlog以事件的形式記錄了所有的 DDL和 DML 語(yǔ)句(因?yàn)樗涗浀氖遣僮鞫皇?數(shù)據(jù)值,屬于邏輯日志),但是不具備宕機(jī)恢復(fù)的功能,因?yàn)榭赡軟](méi)有來(lái)得及刷新臟頁(yè),造成臟頁(yè)數(shù)據(jù)的丟失,而這些操作也沒(méi)有保存到binlog中從而造成數(shù)據(jù)丟失;
  3. binlog記錄的是關(guān)于一個(gè)事務(wù)的具體操作內(nèi)容,即該日志是邏輯日志。而redo日志記錄的是關(guān)于每個(gè)頁(yè)的更改的物理情況。功能壓根不是一回事兒。

6.2 binlog日志的作用

6.2.1 主從復(fù)制

binlog是實(shí)現(xiàn)MySQL主從復(fù)制功能的核心組件。

master節(jié)點(diǎn)會(huì)將所有的寫(xiě)操作記錄到binlog中,slave節(jié)點(diǎn)會(huì)有專(zhuān)門(mén)的I/O線程讀取master節(jié)點(diǎn)的binlog,將寫(xiě)操作同步到當(dāng)前所在的slave節(jié)點(diǎn)。

圖片

6.2.2 數(shù)據(jù)恢復(fù)

假如你在閱讀這篇文章的時(shí)候覺(jué)得我寫(xiě)得實(shí)在太好,拍案叫絕的時(shí)候一不小心把公司的數(shù)據(jù)庫(kù)給刪了,你該怎么做才能恢復(fù)到你刪庫(kù)之前的那個(gè)時(shí)刻的狀態(tài)?

這個(gè)時(shí)候就要用到binlog了,前提是binlog沒(méi)有被刪除,否則,神仙也救不了你了。

通常情況下,公司會(huì)定期對(duì)數(shù)據(jù)庫(kù)進(jìn)行全量備份,可能隔一個(gè)月,一周,甚至可能每天都備份一次。運(yùn)氣好的話你可以使用前一天的全量備份,恢復(fù)到前一天的某時(shí)刻狀態(tài)(或者一周、一月之前),然后從全量備份的時(shí)刻開(kāi)始,從binlog中提取該時(shí)刻之后(前提是你的binlog里面存放了這段時(shí)間的日志)的所有寫(xiě)操作(當(dāng)然,你得過(guò)濾掉你的刪庫(kù)操作),然后進(jìn)行操作回放就可以了。

是不是很簡(jiǎn)單?

問(wèn)題又來(lái)了。再看一眼我們的更新語(yǔ)句。

update t_user_innodb set name ='chanmufeng1994' where id = 1;

假如這條更新語(yǔ)句已經(jīng)被寫(xiě)入到了redo日志,還沒(méi)來(lái)得及寫(xiě)binlog的時(shí)候,MySQL宕機(jī)重啟了,我們看一下會(huì)發(fā)生什么。

因?yàn)閞edo日志可以在重啟的時(shí)候用于恢復(fù)數(shù)據(jù),所以寫(xiě)入磁盤(pán)的是chanmufeng1994。但是binlog里面沒(méi)有記錄這個(gè)邏輯日志,所以這時(shí)候用binlog去恢復(fù)數(shù)據(jù)或者同步到從庫(kù),就會(huì)出現(xiàn)數(shù)據(jù)不一致的情況。

所以在寫(xiě)兩個(gè)日志的情況下,就類(lèi)似于「分布式事務(wù)」的情況,如果你不清楚分布式事務(wù)是個(gè)什么東西也沒(méi)關(guān)系,我在之后的文章會(huì)介紹到。能夠明確的就是redo日志和binlog日志如果單純依次進(jìn)行提交是無(wú)法保證兩種日志都寫(xiě)成功或者都寫(xiě)失敗的。

我們需要「兩階段提交」。

6.3 兩階段提交

兩階段提交不是MySQL的專(zhuān)利,兩階段提交是一種跨系統(tǒng)維持?jǐn)?shù)據(jù)邏輯一致性的常見(jiàn)方案,尤其在分布式事務(wù)上,所以請(qǐng)讀者重點(diǎn)體會(huì)思想

我們把redo日志的提交分成兩步,兩步中redo日志的狀態(tài)分別是preparecommit。步驟如下

  1. InnoDB存儲(chǔ)引擎將更改更新到內(nèi)存中后,同時(shí)將這個(gè)更新操作記錄到redo日志里面,此時(shí)redo日志處于prepare狀態(tài);
  2. 執(zhí)行器生成這個(gè)操作的binlog,并將binlog刷盤(pán);
  3. 執(zhí)行器調(diào)用InnoDB的提交事務(wù)接口,InnoDB把剛剛寫(xiě)入的redo日志改成commit狀態(tài)。至此,所有操作完成。

圖片

加上兩階段提交之后我們?cè)賮?lái)看一下SQL更新語(yǔ)句的執(zhí)行流程。

7. SQL更新語(yǔ)句的執(zhí)行總結(jié)——終版

圖片

  1. 客戶(hù)端發(fā)送更新命令到MySQL服務(wù)器,經(jīng)過(guò)處理連接、解析優(yōu)化等步驟;
  2. Server層向InnoDB存儲(chǔ)引擎要id=1的這條記錄;
  3. 存儲(chǔ)引擎先從緩存中查找這條記錄,有的話直接返回,沒(méi)有則從磁盤(pán)加載到緩存中然后返回;
  4. Server層執(zhí)行器修改這條記錄的name字段值;
  5. 存儲(chǔ)引擎更新修改到內(nèi)存中;
  6. 存儲(chǔ)引擎記錄redo日志,并將狀態(tài)設(shè)置為prepare狀態(tài);
  7. 存儲(chǔ)引擎通知執(zhí)行器,修改完畢,可以進(jìn)行事務(wù)提交;
  8. Server先寫(xiě)了個(gè)binlog;
  9. Server提交事務(wù);
  10. 存儲(chǔ)引擎將redo日志中和當(dāng)前事務(wù)相關(guān)的記錄狀態(tài)設(shè)置為commit狀態(tài)。

完!

參考資料

  1. MySQL實(shí)戰(zhàn)45講
  2. MySQL是怎樣運(yùn)行的
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 存儲(chǔ)
    +關(guān)注

    關(guān)注

    13

    文章

    4355

    瀏覽量

    86177
  • buffer
    +關(guān)注

    關(guān)注

    2

    文章

    120

    瀏覽量

    30130
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    829

    瀏覽量

    26743
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    STM8L執(zhí)行一條語(yǔ)句大概需要幾個(gè)時(shí)鐘周期?

    STM8L執(zhí)行一條語(yǔ)句大概需要幾個(gè)時(shí)鐘周期
    發(fā)表于 05-06 06:16

    DSP執(zhí)行一條語(yǔ)句的時(shí)間

    CPU配置成150M。高頻時(shí)鐘75M。 那么執(zhí)行一條語(yǔ)句的時(shí)間是多少呢
    發(fā)表于 10-15 11:28

    為什么要?jiǎng)討B(tài)sql語(yǔ)句

    為什么要?jiǎng)討B(tài)sql語(yǔ)句?因?yàn)閯?dòng)態(tài)sql語(yǔ)句能夠提供些比較友好的機(jī)制1、可以使得些在編譯過(guò)程中
    發(fā)表于 12-20 06:00

    MySQL存儲(chǔ)引擎完成更新語(yǔ)句執(zhí)行的方法

    首先肯定是我們的系統(tǒng)通過(guò)個(gè)數(shù)據(jù)庫(kù)連接發(fā)送到了MySQL上,然后肯定會(huì)經(jīng)過(guò)SQL接口、解析器、優(yōu)化器、執(zhí)行器幾個(gè)環(huán)節(jié),解析SQL語(yǔ)句,生成
    的頭像 發(fā)表于 10-21 10:40 ?2092次閱讀
    MySQL存儲(chǔ)引擎完成<b class='flag-5'>更新語(yǔ)句</b><b class='flag-5'>執(zhí)行</b>的方法

    select語(yǔ)句和update語(yǔ)句分別是怎么執(zhí)行

    樣,但是具體的實(shí)現(xiàn)還是有區(qū)別的。 當(dāng)然深入了解select和update的具體區(qū)別并不是只為了面試,當(dāng)希望Mysql能夠高效的執(zhí)行的時(shí)候,最好的辦法就是清楚的了解Mysql是如何執(zhí)行查詢(xún)的,只有更加全面的了解
    的頭像 發(fā)表于 11-03 09:41 ?3620次閱讀
    select<b class='flag-5'>語(yǔ)句</b>和update<b class='flag-5'>語(yǔ)句</b>分別是怎么<b class='flag-5'>執(zhí)行</b>的

    一條SQL語(yǔ)句是怎么被執(zhí)行

    直是想知道一條SQL語(yǔ)句是怎么被執(zhí)行的,它執(zhí)行的順序是怎樣的,然后查看總結(jié)各方資料,就有了下面
    的頭像 發(fā)表于 09-12 09:44 ?1546次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b><b class='flag-5'>語(yǔ)句</b>是怎么被<b class='flag-5'>執(zhí)行</b>的

    簡(jiǎn)述SQL更新語(yǔ)句執(zhí)行流程1

    之前我們講過(guò)了一條SQL查詢(xún)語(yǔ)句是如何執(zhí)行的,那么插入(INSERT)、更新(UPDATE)和刪除(DELETE)操作的
    的頭像 發(fā)表于 02-14 15:40 ?652次閱讀
    簡(jiǎn)述<b class='flag-5'>SQL</b><b class='flag-5'>更新語(yǔ)句</b>的<b class='flag-5'>執(zhí)行</b><b class='flag-5'>流程</b>1

    簡(jiǎn)述SQL更新語(yǔ)句執(zhí)行流程2

    之前我們講過(guò)了一條SQL查詢(xún)語(yǔ)句是如何執(zhí)行的,那么插入(INSERT)、更新(UPDATE)和刪除(DELETE)操作的
    的頭像 發(fā)表于 02-14 15:40 ?579次閱讀
    簡(jiǎn)述<b class='flag-5'>SQL</b><b class='flag-5'>更新語(yǔ)句</b>的<b class='flag-5'>執(zhí)行</b><b class='flag-5'>流程</b><b class='flag-5'>2</b>

    一條SQL查詢(xún)語(yǔ)句是怎么去執(zhí)行的?(上)

    MySQL是典型的`C/S架構(gòu)`(客戶(hù)端/服務(wù)器架構(gòu)),客戶(hù)端進(jìn)程向服務(wù)端進(jìn)程發(fā)送段文本(MySQL指令),服務(wù)器進(jìn)程進(jìn)行語(yǔ)句處理然后返回執(zhí)行結(jié)果。
    的頭像 發(fā)表于 03-03 09:58 ?431次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b>查詢(xún)<b class='flag-5'>語(yǔ)句</b>是怎么去<b class='flag-5'>執(zhí)行</b>的?(上)

    一條SQL查詢(xún)語(yǔ)句是怎么去執(zhí)行的?(中)

    MySQL是典型的`C/S架構(gòu)`(客戶(hù)端/服務(wù)器架構(gòu)),客戶(hù)端進(jìn)程向服務(wù)端進(jìn)程發(fā)送段文本(MySQL指令),服務(wù)器進(jìn)程進(jìn)行語(yǔ)句處理然后返回執(zhí)行結(jié)果。
    的頭像 發(fā)表于 03-03 09:58 ?503次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b>查詢(xún)<b class='flag-5'>語(yǔ)句</b>是怎么去<b class='flag-5'>執(zhí)行</b>的?(中)

    一條SQL查詢(xún)語(yǔ)句是怎么去執(zhí)行的?(下)

    MySQL是典型的`C/S架構(gòu)`(客戶(hù)端/服務(wù)器架構(gòu)),客戶(hù)端進(jìn)程向服務(wù)端進(jìn)程發(fā)送段文本(MySQL指令),服務(wù)器進(jìn)程進(jìn)行語(yǔ)句處理然后返回執(zhí)行結(jié)果。
    的頭像 發(fā)表于 03-03 09:58 ?435次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b>查詢(xún)<b class='flag-5'>語(yǔ)句</b>是怎么去<b class='flag-5'>執(zhí)行</b>的?(下)

    一條SQL更新語(yǔ)句執(zhí)行流程1

    什么是InnoDB頁(yè)?緩存頁(yè)又是什么?為什么這么設(shè)計(jì)? * 什么是表空間?不同存儲(chǔ)引擎的表在文件系統(tǒng)的底層表示上有什么區(qū)別? * Buffer Pool是什么?為什么需要?有哪些我們需要掌握的細(xì)節(jié)? * MySQL
    的頭像 發(fā)表于 03-03 10:02 ?674次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b><b class='flag-5'>更新語(yǔ)句</b>的<b class='flag-5'>執(zhí)行</b><b class='flag-5'>流程</b>1

    sql where條件的執(zhí)行順序

    。 在深入討論WHERE條件的執(zhí)行順序之前,先回顧一下一SQL語(yǔ)句執(zhí)行順序。一條
    的頭像 發(fā)表于 11-23 11:31 ?2299次閱讀

    oracle執(zhí)行sql查詢(xún)語(yǔ)句的步驟是什么

    Oracle數(shù)據(jù)庫(kù)是種常用的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),具有強(qiáng)大的SQL查詢(xún)功能。Oracle執(zhí)行SQL查詢(xún)語(yǔ)句的步驟包括編寫(xiě)
    的頭像 發(fā)表于 12-06 10:49 ?1040次閱讀

    單片機(jī)中for語(yǔ)句的運(yùn)用

    語(yǔ)句,它的基本結(jié)構(gòu)如下: for (初始化語(yǔ)句; 條件表達(dá)式; 更新語(yǔ)句) {循環(huán)體;} for語(yǔ)句執(zhí)行
    的頭像 發(fā)表于 01-05 14:02 ?2618次閱讀
    定做百家乐桌子| 现金百家乐官网赌法| ea百家乐系统| 百人百家乐官网软件供应| 大发888娱乐成| 和林格尔县| 澳门百家乐官网网站| 百家乐官网大轮转| 大发888娱乐城 下载| 百家乐官网的必赢方法| 顶级赌场真假的微博| 网上的百家乐是真是假| 百家乐官网搏牌| 网上百家乐官网优博| 大发888赌场娱乐网规则| 乐天堂百家乐娱乐网| 百家乐官网网上真钱娱乐场开户注册| 元氏县| 棋牌小游戏| 百家乐1元投注| 百家乐官网送彩金平台| 百乐坊娱乐城官网| 网上百家乐作| 博彩百家乐官网画谜网| 轮盘必胜法| 威尼斯人娱乐场色| 百家乐怎样算大小| 百家乐官网牌桌订做| 百家乐官网算牌皇冠网| 大发888登录器下载| 同花顺百家乐的玩法技巧和规则 | 百利宫百家乐的玩法技巧和规则| 菲彩百家乐官网的玩法技巧和规则 | 网络龙虎| 跪求百家乐打法| 博久百家乐论坛| 全讯网址| 百家乐平注法到65| 百家乐开户首选| 百家乐视频交友| 百家乐官网tt赌场娱乐网规则|