在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

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

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

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

這是圖解MySQL的第2篇文章,這篇文章會(huì)通過一條SQL更新語句的執(zhí)行流程讓大家清楚地明白:

  • 什么是InnoDB頁?緩存頁又是什么?為什么這么設(shè)計(jì)?
  • 什么是表空間?不同存儲(chǔ)引擎的表在文件系統(tǒng)的底層表示上有什么區(qū)別?
  • Buffer Pool是什么?為什么需要?有哪些我們需要掌握的細(xì)節(jié)?
  • MySQL的三種日志文件redo日志、undo日志、binlog分別是什么?為什么需要這么多種類型的日志?

正文開始!


之前我們講過了一條SQL查詢語句是怎么去執(zhí)行的,那么插入(INSERT)、更新(UPDATE)和刪除(DELETE)操作的流程又是什么樣子呢?

其實(shí)對(duì)于MySQL而言,只有兩種通常意義的操作,一種是Query(查詢),另一種是Update(更新),后者包含了我們平常使用的INSERT、UPDATE和DELETE操作。

那么MySQL的更新流程和查詢流程有什么區(qū)別呢?

其實(shí)基本的流程是一致的,也要經(jīng)過 處理連接解析優(yōu)化存儲(chǔ)引擎幾個(gè)步驟。主要區(qū)別在更新操作涉及到了MySQL更多的細(xì)節(jié)。

圖片

注:我們接下來的所有描述,針對(duì)的都是InnoDB存儲(chǔ)引擎,如果涉及到其他存儲(chǔ)引擎,將會(huì)特殊說明

1. 一些需要知道的概念

對(duì)于MySQL任何存儲(chǔ)引擎來說,數(shù)據(jù)都是存儲(chǔ)在磁盤中的,存儲(chǔ)引擎要操作數(shù)據(jù),必須先把磁盤中的數(shù)據(jù)加載到內(nèi)存中才可以。

那么問題來了,一次性從磁盤中加載多少數(shù)據(jù)到內(nèi)存中合適呢?當(dāng)獲取記錄時(shí),InnoDB存儲(chǔ)引擎需要一條條地把記錄從磁盤中讀取出來嗎?

當(dāng)然不行!我們知道磁盤的讀寫速度和內(nèi)存讀寫速度差了幾個(gè)數(shù)量級(jí),如果我們需要讀取的數(shù)據(jù)恰好運(yùn)行在磁盤的不同位置,那就意味著會(huì)產(chǎn)生多次I/O操作。

因此,無論是操作系統(tǒng)也好,MySQL存儲(chǔ)引擎也罷,都有一個(gè)預(yù)讀取的概念。概念的依據(jù)便是統(tǒng)治計(jì)算機(jī)界的局部性原理。

空間局部性:如果當(dāng)前數(shù)據(jù)是正在被使用的,那么與該數(shù)據(jù)空間地址臨近的其他數(shù)據(jù)在未來有更大的可能性被使用到,因此可以優(yōu)先加載到寄存器或主存中提高效率

就是當(dāng)磁盤上的一塊數(shù)據(jù)被讀取的時(shí)候,我們干脆多讀一點(diǎn),而不是用多少讀多少。

1.1 InnoDB頁

InnoDB存儲(chǔ)引擎將數(shù)據(jù)劃分為若干個(gè)頁,以頁作為磁盤和內(nèi)存之間交互的最小單位。InnoDB中頁的大小默認(rèn)為16KB。也就是默認(rèn)情況下,一次最少從磁盤中讀取16KB的數(shù)據(jù)到內(nèi)存中,一次最少把內(nèi)存中16KB的內(nèi)容刷新到磁盤上。

圖片

對(duì)于InnoDB存儲(chǔ)引擎而言,所有的數(shù)據(jù)(存儲(chǔ)用戶數(shù)據(jù)的索引、各種元數(shù)據(jù)、系統(tǒng)數(shù)據(jù))都是以頁的形式進(jìn)行存儲(chǔ)的。

1.2 表空間

為了更好地管理頁,MySQL又設(shè)計(jì)了「表空間」的概念。表空間又有很多類型,具體類型我們不需要知道,我們只需要知道,一個(gè)表空間可以劃分成很多個(gè)InnoDB頁,InnoDB表數(shù)據(jù)都存儲(chǔ)在某個(gè)表空間的頁中。

為了方便我們定位,MySQL貼心地為表空間設(shè)計(jì)了一個(gè)唯一標(biāo)識(shí)——表空間ID(space ID)。同理,InnoDB頁也有自己的唯一編號(hào)——頁號(hào)(page number)。

因此,我們可以這么認(rèn)為。給定表空間ID和頁號(hào)以及頁的偏移量,我們就可以定位到InnoDB頁的某條記錄,也就是數(shù)據(jù)庫表的某條記錄。

1.2.1 數(shù)據(jù)表在文件系統(tǒng)中的表示

為了更好地讓大家理解這個(gè)抽象的概念,我創(chuàng)建了名為test的數(shù)據(jù)庫,在其下分別創(chuàng)建了3張表t_user_innodbt_user_myisamt_user_memory,對(duì)應(yīng)的存儲(chǔ)引擎分別為InnoDBMyISAMMEMORY

進(jìn)入MySQL的數(shù)據(jù)目錄,找到test目錄,看一下test數(shù)據(jù)庫下所有表對(duì)應(yīng)的本地文件目錄

drwxr-x--- 2 mysql mysql  4096 Jan 26 09:28 .
drwxrwxrwt 6 mysql mysql  4096 Jan 26 09:24 ..
-rw-r----- 1 mysql mysql    67 Jan 26 09:24 db.opt
-rw-r----- 1 mysql mysql  8556 Jan 26 09:28 t_user_innodb.frm
-rw-r----- 1 mysql mysql 98304 Jan 26 09:28 t_user_innodb.ibd
-rw-r----- 1 mysql mysql  8556 Jan 26 09:27 t_user_memory.frm
-rw-r----- 1 mysql mysql     0 Jan 26 09:28 t_user_myisam.MYD
-rw-r----- 1 mysql mysql  1024 Jan 26 09:28 t_user_myisam.MYI
-rw-r----- 1 mysql mysql  8556 Jan 26 09:28 t_user_myisam.frm

1.2.2 InnoDB是如何存儲(chǔ)表數(shù)據(jù)的

「表空間」是InnoDB存儲(chǔ)引擎獨(dú)有的概念。

我們看到t_user_innodb表在數(shù)據(jù)庫對(duì)應(yīng)的test目錄下會(huì)生成以下兩個(gè)文件

  • t_user_innodb.frm
  • t_user_innodb.ibd

其中,t_user_innodb.ibd就是t_user_innodb表對(duì)應(yīng)的表空間在文件系統(tǒng)上的表示;t_user_innodb.frm用來描述表的結(jié)構(gòu),如表有哪些列,列的類型是什么等。

1.2.3 MyISAM是如何存儲(chǔ)表數(shù)據(jù)的

和InnoDB不同,MyISAM沒有表空間的概念,表的數(shù)據(jù)和索引全都直接存放在對(duì)應(yīng)的數(shù)據(jù)庫子目錄下,可以看到t_user_myisam對(duì)應(yīng)了三個(gè)文件

  • t_user_myisam.MYD
  • t_user_myisam.MYI
  • t_user_myisam.frm

其中,t_user_myisam.MYD表示表的數(shù)據(jù)文件,也就是我們實(shí)際看到的數(shù)據(jù)表的內(nèi)容;t_user_myisam.MYI表示表的索引文件,為該表創(chuàng)建的索引都會(huì)存放在這個(gè)文件中;t_user_myisam.frm用來描述表的結(jié)構(gòu)。

1.2.4 MEMORY是如何存儲(chǔ)表數(shù)據(jù)的

MEMORY存儲(chǔ)引擎對(duì)應(yīng)的數(shù)據(jù)表只有一個(gè)描述表結(jié)構(gòu)的文件t_user_memory.frm。

2. 緩沖池Buffer Pool

為了更好的利用局部性原理帶給我們的優(yōu)勢(shì),InnoDB在處理客戶端請(qǐng)求時(shí),如果需要訪問某個(gè)頁的數(shù)據(jù),會(huì)把該數(shù)據(jù)所在的頁的全部數(shù)據(jù)加載到內(nèi)存中。哪怕是只需要訪問一個(gè)頁中的一條數(shù)據(jù),也需要加載整個(gè)頁。

從磁盤中加載數(shù)據(jù)到內(nèi)存中的操作太昂貴了!有什么辦法可以提高數(shù)據(jù)操作的效率呢?緩存!

為了緩存磁盤的頁,InnoDB在MySQL服務(wù)器啟動(dòng)時(shí)會(huì)向操作系統(tǒng)申請(qǐng)一片連續(xù)的內(nèi)存區(qū)域,這片內(nèi)存區(qū)域就是 Buffer Pool

很容易理解,為了更好地緩存頁數(shù)據(jù),Buffer Pool對(duì)應(yīng)的一片連續(xù)內(nèi)存空間也被劃分為若干個(gè)頁,而且默認(rèn)情況下,Buffer Pool頁的大小和InnoDB頁大小一樣,都是16KB。為了區(qū)分兩種不同的頁,我們將Buffer Pool中的頁面稱為緩沖頁。

圖片

讀取數(shù)據(jù)的時(shí)候,InnoDB先判斷數(shù)據(jù)是否在Buffer Pool中,如果是,則直接讀取數(shù)據(jù)進(jìn)行操作,不用再次從磁盤加載;如果不是,則從磁盤加載到Buffer Pool中,然后讀取數(shù)據(jù)進(jìn)行操作。

修改數(shù)據(jù)的時(shí)候,也是將數(shù)據(jù)先寫到Buffer Pool緩沖頁中,而不是每次更新操作都直接寫入磁盤。當(dāng)緩沖頁中的數(shù)據(jù)和磁盤文件不一致的時(shí)候,緩沖頁被稱為臟頁。

那么臟頁是什么時(shí)候被同步到磁盤呢?

InnoDB中有專門的后臺(tái)線程每隔一段時(shí)間會(huì)把臟頁的多個(gè)修改刷新到磁盤上,這個(gè)動(dòng)作叫做「刷臟」。

3. redo日志

3.1 為什么需要redo日志

不定時(shí)刷臟又帶來一個(gè)問題。如果臟頁的數(shù)據(jù)還沒有刷新到磁盤上,此時(shí)數(shù)據(jù)庫突然宕機(jī)或重啟,這些數(shù)據(jù)就會(huì)丟失。

首先想到的最簡單粗暴的解決方案就是在事務(wù)提交之前,把該事務(wù)修改的所有頁面都刷新到磁盤。但是上文說過,頁是內(nèi)存和磁盤交互的最小單位,如果只修改了1個(gè)字節(jié),卻要刷新16KB的數(shù)據(jù)到磁盤上,不得不說太浪費(fèi)了,此路不通!

所以,必須要有一個(gè)持久化的措施。

為了解決這個(gè)問題,InnoDB把對(duì)所有頁的更新操作(再強(qiáng)調(diào)一遍,包含INSERT、UPDATE、DELETE)專門寫入一個(gè)日志文件。

當(dāng)有未同步到磁盤中的數(shù)據(jù)時(shí),數(shù)據(jù)庫在啟動(dòng)的時(shí)候,會(huì)根據(jù)這個(gè)日志文件進(jìn)行數(shù)據(jù)恢復(fù)。我們常說的關(guān)系型數(shù)據(jù)庫的ACID特性中的D(持久性),就是通過這個(gè)日志來實(shí)現(xiàn)的。

這個(gè)日志文件就是大名鼎鼎的 redo日志

「re」在英文中的詞根含義是“重新”,redo就是「重新做」的意思,顧名思義就是MySQL根據(jù)這個(gè)日志文件重新進(jìn)行操作

圖片

這就出現(xiàn)了一個(gè)有意思的問題,刷新磁盤和寫redo日志都是進(jìn)行磁盤操作,為什么不直接把數(shù)據(jù)刷新到磁盤中呢?

3.2 磁道尋址

我們需要稍微了解一下磁道尋址的過程。磁盤的構(gòu)造如下圖所示。

圖片

每個(gè)硬盤都有若干個(gè)盤片,上圖的硬盤有4個(gè)盤片。

每個(gè)盤片的盤面上有一圈圈的同心圓,叫做「磁道」。

從圓心向外畫直線,可以將磁道劃分為若干個(gè)弧段,每個(gè)磁道上一個(gè)弧段被稱之為一個(gè)「扇區(qū)」(右上圖白色部分)。數(shù)據(jù)是保存在扇區(qū)當(dāng)中的,扇區(qū)是硬盤讀寫的最小單元,如果要讀寫數(shù)據(jù),必須找到對(duì)應(yīng)的扇區(qū),這個(gè)過程叫做「尋址」。

3.2.1 隨機(jī)I/O

如果我們需要的數(shù)據(jù)是隨機(jī)分散在磁盤上不同盤片的不同扇區(qū)中,那么找到相應(yīng)的數(shù)據(jù)需要等到磁臂旋轉(zhuǎn)到指定的盤片然后繼續(xù)尋找對(duì)應(yīng)的扇區(qū),才能找到我們所需要的一塊數(shù)據(jù),持續(xù)進(jìn)行此過程直到找完所有數(shù)據(jù),這個(gè)就是隨機(jī)I/O,讀取數(shù)據(jù)速度非常慢。

3.2.2 順序I/O

假設(shè)我們已經(jīng)找到了第一塊數(shù)據(jù),并且其他所需的數(shù)據(jù)就在這一塊數(shù)據(jù)之后,那么就不需要重新尋址,可以依次拿到我們所需的數(shù)據(jù),這個(gè)就叫順序 I/O。

現(xiàn)在回答之前的問題。因?yàn)樗⑴K是隨機(jī)I/O,而記錄日志是順序I/O(連續(xù)寫的),順序I/O效率更高,本質(zhì)上是數(shù)據(jù)集中存儲(chǔ)和分散存儲(chǔ)的區(qū)別。因此先把修改寫入日志文件,在保證了內(nèi)存數(shù)據(jù)的安全性的情況下,可以延遲刷盤時(shí)機(jī),進(jìn)而提升系統(tǒng)吞吐。

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

    關(guān)注

    13

    文章

    4358

    瀏覽量

    86192
  • buffer
    +關(guān)注

    關(guān)注

    2

    文章

    120

    瀏覽量

    30137
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    830

    瀏覽量

    26751
收藏 人收藏

    評(píng)論

    相關(guān)推薦

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

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

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

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

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

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

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

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

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

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

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

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

    簡述SQL更新語句執(zhí)行流程1

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

    簡述SQL更新語句執(zhí)行流程2

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

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

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

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

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

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

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

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

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

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

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

    oracle執(zhí)行sql查詢語句的步驟是什么

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

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

    語句,它的基本結(jié)構(gòu)如下: for (初始化語句; 條件表達(dá)式; 更新語句) {循環(huán)體;} for語句執(zhí)行
    的頭像 發(fā)表于 01-05 14:02 ?2634次閱讀
    主站蜘蛛池模板: 天堂中文资源在线地址 | 大色视频| 午夜影院在线观看 | www.亚洲成人 | 爱操成人网 | 你懂的手机在线观看 | 嫩草影院国产 | 老师今晚让你爽个够 | 1024手机看片国产旧版你懂的 | www毛片 | 2016天天干| 四虎影院免费视频 | 日本黄在线 | 欧美性色xo影院永久禁欲 | 97玖玖| 国产黄色在线视频 | 国产成人精品亚洲日本在线观看 | 哟交小u女国产精品视频 | 天天操天天操天天操香蕉 | 青草悠悠视频在线观看 | 午夜国产精品视频 | 丁香五月欧美成人 | 亚洲国产婷婷香蕉久久久久久 | 婷婷香蕉 | 黄色激情小说视频 | 国产小福利 | 天天天天天天干 | 黄色网址你懂的 | 韩国韩宝贝2020vip福利视频 | 天天做天天爱夜夜想毛片 | 色综合亚洲天天综合网站 | 国产伦一区二区三区免费 | 理论毛片| 一级做a爱免费观看视频 | 天天干天天干天天干 | 五月激情婷婷网 | 人人人插| 午夜黄色福利 | 午夜免费观看福利片一区二区三区 | 国产午夜精品久久久久免费视 | 亚洲视频一区在线观看 |