在线观看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)不再提示

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

數(shù)據(jù)分析與開(kāi)發(fā) ? 來(lái)源:CSDN博客 ? 作者:CSDN博客 ? 2020-10-21 10:40 ? 次閱讀

假設(shè)我們有一條SQL語(yǔ)句是這樣的:

updatet_usersetname='月伴飛魚(yú)'whereid=1;

那么我們先想一下這條SQL語(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ǔ)句,生成執(zhí)行計(jì)劃,接著去由執(zhí)行器負(fù)責(zé)這個(gè)計(jì)劃的執(zhí)行,調(diào)用InnoDB存儲(chǔ)引擎的接口去執(zhí)行。

大致會(huì)走下圖的這個(gè)流程

我們就來(lái)探索一下這個(gè)存儲(chǔ)引擎里的架構(gòu)設(shè)計(jì),以及如何基于存儲(chǔ)引擎完成一條更新語(yǔ)句的執(zhí)行

緩沖池

InnoDB存儲(chǔ)引擎中有一個(gè)非常重要的放在內(nèi)存里的組件,就是緩沖池(Buffer Pool),這里面會(huì)緩存很多的數(shù)據(jù), 以便于以后在查詢的時(shí)候,萬(wàn)一你要是內(nèi)存緩沖池里有數(shù)據(jù),就可以不用去查磁盤了

所以當(dāng)我們的InnoDB存儲(chǔ) 引擎要執(zhí)行更新語(yǔ)句的時(shí)候 ,比如對(duì)“id=1”這一行數(shù)據(jù),他其實(shí)會(huì)先將“id=1”這一行數(shù)據(jù)看看是否在緩沖池里,如果不在的 話,那么會(huì)直接從磁盤里加載到緩沖池里來(lái),而且接著還會(huì)對(duì)這行記錄加獨(dú)占鎖。

因?yàn)槲覀兿胍幌拢谖覀兏隆癷d=1”這一行數(shù)據(jù)的時(shí)候,肯定是不允許別人同時(shí)更新的,所以必須要對(duì)這行記錄加 獨(dú)占鎖

undo日志文件

如何讓你更新的數(shù)據(jù)可以回滾?

接著下一步,假設(shè)“id=1”這行數(shù)據(jù)的name原來(lái)是“周星星”,現(xiàn)在我們要更新為“月伴飛魚(yú)”,那么此時(shí)我們得先 把要更新的原來(lái)的值“周星星”和“id=1”這些信息,寫入到undo日志文件中去。

數(shù)據(jù)庫(kù)中,如果我們執(zhí)行一個(gè)更新語(yǔ)句,要是他是在一個(gè)事務(wù)里的話,那么事 務(wù)提交之前我們都是可以對(duì)數(shù)據(jù)進(jìn)行回滾的,也就是把你更新為“月伴飛魚(yú)”的值回滾到之前的“周星星”去。

所以為了考慮到未來(lái)可能要回滾數(shù)據(jù)的需要,這里會(huì)把你更新前的值寫入undo日志文件,我們看下圖。

更新buffer pool中的緩存數(shù)據(jù)

這里所謂的更新內(nèi)存緩沖池里的數(shù)據(jù),意思就是把內(nèi)存里的“id=1”這行數(shù)據(jù)的name字段修改為“月伴飛魚(yú)”

當(dāng)我們把要更新的那行記錄從磁盤文件加載到緩沖池,同時(shí)對(duì)他加鎖之后,而且還把更新前的舊值寫入undo日志文件 之后,我們就可以正式開(kāi)始更新這行記錄了,更新的時(shí)候,先是會(huì)更新緩沖池中的記錄,此時(shí)這個(gè)數(shù)據(jù)就是臟數(shù)據(jù) 了。

那么為什么說(shuō)此時(shí)這行數(shù)據(jù)就是臟數(shù)據(jù)了呢?

因?yàn)檫@個(gè)時(shí)候磁盤上“id=1”這行數(shù)據(jù)的name字段還是“周星星”,但是內(nèi)存里這行數(shù)據(jù)已經(jīng)被修改了,所以 就會(huì)叫他是臟數(shù)據(jù)。

redo log

接著我們來(lái)思考一個(gè)問(wèn)題,按照上圖的說(shuō)明,現(xiàn)在已經(jīng)把內(nèi)存里的數(shù)據(jù)進(jìn)行了修改,但是磁盤上的數(shù)據(jù)還沒(méi)修改

那么此時(shí)萬(wàn)一MySQL所在的機(jī)器宕機(jī)了,必然會(huì)導(dǎo)致內(nèi)存里修改過(guò)的數(shù)據(jù)丟失,這可怎么辦呢?這個(gè)時(shí)候,就必須要把對(duì)內(nèi)存所做的修改寫入到一個(gè)Redo Log Buffer里去,這也是內(nèi)存里的一個(gè)緩沖區(qū),是用來(lái)存 放redo日志的

所謂的redo日志,就是記錄下來(lái)你對(duì)數(shù)據(jù)做了什么修改,比如對(duì)“id=1這行記錄修改了name字段的值為“月伴飛魚(yú)”,這 就是一個(gè)日志。我們先看下圖

這個(gè)redo日志其實(shí)是用來(lái)在MySQL突然宕機(jī)的時(shí)候,用來(lái)恢復(fù)你更新過(guò)的數(shù)據(jù)的

提交事務(wù)的時(shí)候?qū)edo日志寫入磁盤中

接著我們想要提交一個(gè)事務(wù)了,此時(shí)就會(huì)根據(jù)一定的策略把redo日志從redo log buffer里刷入到磁盤文件里去。

此時(shí)這個(gè)策略是通過(guò)innodb_flush_log_at_trx_commit來(lái)配置的,他有幾個(gè)選項(xiàng)。當(dāng)這個(gè)參數(shù)的值為0的時(shí)候,那么你提交事務(wù)的時(shí)候,不會(huì)把redo log buffer里的數(shù)據(jù)刷入磁盤文件的,此時(shí)可能你都 提交事務(wù)了,結(jié)果mysql宕機(jī)了,然后此時(shí)內(nèi)存里的數(shù)據(jù)全部丟失。相當(dāng)于你提交事務(wù)成功了,但是由于MySQL突然宕機(jī),導(dǎo)致內(nèi)存中的數(shù)據(jù)和redo日志都丟失了

當(dāng)這個(gè)參數(shù)的值為1的時(shí)候,你提交事務(wù)的時(shí)候,就必須把redo log從內(nèi)存刷入到磁盤文件里去,只要事務(wù)提交成功,那么redo log就 必然在磁盤里了

那么只要提交事務(wù)成功之后,redo日志一定在磁盤文件里,此時(shí)你肯定會(huì)有一條redo日志說(shuō)了,“我此時(shí)對(duì)哪個(gè)數(shù)據(jù)做了一個(gè)什么修 改,比如name字段修改為月伴飛魚(yú)了”。

然后哪怕此時(shí)buffer pool中更新過(guò)的數(shù)據(jù)還沒(méi)刷新到磁盤里去,此時(shí)內(nèi)存里的數(shù)據(jù)是已經(jīng)更新過(guò)的“name=月伴飛魚(yú)”,然后磁盤上的數(shù) 據(jù)還是沒(méi)更新過(guò)的“name=周星星”。

此時(shí)如果說(shuō)提交事務(wù)后處于上圖的狀態(tài),然后mysql系統(tǒng)突然崩潰了,此時(shí)會(huì)如何?會(huì)丟失數(shù)據(jù)嗎?

肯定不會(huì)啊,因?yàn)殡m然內(nèi)存里的修改成name=月伴飛魚(yú)的數(shù)據(jù)會(huì)丟失,但是redo日志里已經(jīng)說(shuō)了,對(duì)某某數(shù)據(jù)做了修改 name=月伴飛魚(yú)。

所以此時(shí)mysql重啟之后,他可以根據(jù)redo日志去恢復(fù)之前做過(guò)的修改

最后來(lái)看看,如果innodb_flush_log_at_trx_commit參數(shù)的值是2呢?

他的意思就是,提交事務(wù)的時(shí)候,把redo日志寫入磁盤文件對(duì)應(yīng)的os cache緩存里去,而不是直接進(jìn)入磁盤文件,可 能1秒后才會(huì)把os cache里的數(shù)據(jù)寫入到磁盤文件里去。

這種模式下,你提交事務(wù)之后,redo log可能僅僅停留在os cache內(nèi)存緩存里,沒(méi)實(shí)際進(jìn)入磁盤文件,萬(wàn)一此時(shí)你要 是機(jī)器宕機(jī)了,那么os cache里的redo log就會(huì)丟失,同樣會(huì)讓你感覺(jué)提交事務(wù)了,結(jié)果數(shù)據(jù)丟了

三種redo日志刷盤策略到底選擇哪一種?

innodb_flush_log_at_trx_commit=0提交事務(wù)的時(shí)候,不會(huì)將內(nèi)存中的redo log刷入磁盤

優(yōu)點(diǎn),純內(nèi)存操作速度快,缺點(diǎn),redo日志沒(méi)有落地磁盤,如果提交事務(wù)的一瞬間,MySQL宕機(jī),那么如果是修改數(shù)據(jù),內(nèi)存數(shù)據(jù)沒(méi)了,磁盤也沒(méi)來(lái)的及更新,就丟失了本次修改操作。

innodb_flush_log_at_trx_commit=1,提交事務(wù)之前一定會(huì)將redo log 刷入磁盤

優(yōu)點(diǎn),事務(wù)提交之前,事務(wù)操作log一定刷入磁盤,事務(wù)成功,磁盤一定有redo日志,如果事務(wù)提交成功,內(nèi)存修改,磁盤還沒(méi)有更新,完全可以讀取redo日志恢復(fù)數(shù)據(jù)。缺點(diǎn),寫磁盤確實(shí)會(huì)消耗很多性能,如果是高并發(fā),大量寫入,一定會(huì)影響寫入性能,吞吐量和處理時(shí)間都會(huì)影響到。

innodb_flush_log_at_trx_commit=2,將redo日志刷入OS cache,間隔可能一秒寫入磁盤。方案鑒于一和二方案之間。

優(yōu)點(diǎn),利用OS cache去緩存部分日志,可以提高吞吐量,間隔時(shí)間,異步刷入磁盤。缺點(diǎn),提交事務(wù)之后,可能redo日志還在cache中。此時(shí),日志存在丟失的風(fēng)險(xiǎn)。

三種方案,第一種方案適用于,允許不重要的數(shù)據(jù),但是大批量插入的場(chǎng)景,可能丟失,比如一些大批量的任務(wù)執(zhí)行日志上報(bào)的數(shù)據(jù)。

方案二適用于數(shù)據(jù)不可丟失的插入更新,比如訂單,用戶等核心數(shù)據(jù)。

方案三,適用于高并發(fā)插入,允許一定數(shù)據(jù)丟失,但是大部分可靠的場(chǎng)景,比如用戶行為日志,APP異常上報(bào)等。

一般建議redo日志刷盤策略設(shè)置為1,保證事務(wù)提交之后,數(shù)據(jù)絕對(duì)不能丟失,MySQL中這個(gè)參數(shù)默認(rèn)值為1

責(zé)任編輯人:CC

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(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

    文章

    4509

    瀏覽量

    87154
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    849

    瀏覽量

    27655

原文標(biāo)題:MySQL 存儲(chǔ)引擎如何完成一條更新語(yǔ)句的執(zhí)行

文章出處:【微信號(hào):DBDevs,微信公眾號(hào):數(shù)據(jù)分析與開(kāi)發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    【工具分享】labview與MYsql語(yǔ)句使用判斷

    語(yǔ)句執(zhí)行1.寫入MYSQL語(yǔ)句2.執(zhí)行語(yǔ)句3.語(yǔ)句
    發(fā)表于 05-08 16:00

    詳解Mysql數(shù)據(jù)庫(kù)InnoDB存儲(chǔ)引擎事務(wù)

    關(guān)于Mysql數(shù)據(jù)庫(kù)InnoDB存儲(chǔ)引擎事務(wù)的一點(diǎn)理解
    發(fā)表于 05-13 10:11

    mysql存儲(chǔ)引擎選擇方法

    mysql怎么選擇合適的存儲(chǔ)引擎
    發(fā)表于 08-08 07:26

    MySQL存儲(chǔ)引擎簡(jiǎn)析

    MySQL存儲(chǔ)引擎InnoDB??InnoDB 的存儲(chǔ)文件有兩個(gè),后綴名分別是.frm和.idb,其中.frm是表的定義文件,而.idb是數(shù)據(jù)文件。InnoDB 中存在表鎖和行鎖,不過(guò)
    發(fā)表于 09-06 06:07

    mysql基本語(yǔ)句詳細(xì)教程

    mysql基本語(yǔ)句詳細(xì)教程
    發(fā)表于 12-15 22:15 ?0次下載

    怎樣選擇存儲(chǔ)引擎MySQL存儲(chǔ)引擎怎么樣?

    MySQL是我們經(jīng)常使用的數(shù)據(jù)庫(kù)處理系統(tǒng)(DBMS),不知小伙伴們有沒(méi)有注意過(guò)其中的“存儲(chǔ)引擎”(storage_engine)呢?有時(shí)候面試題中也會(huì)問(wèn)道MySQL幾種常用的
    的頭像 發(fā)表于 09-02 10:15 ?5115次閱讀

    關(guān)于mysql存儲(chǔ)引擎你知道多少

    Mysql中用的最多的兩種存儲(chǔ)引擎就是MyISAM和InnDB,其中MyISAM是5.1版本之前的默認(rèn)存儲(chǔ)引擎,InnoDB是5.1版本之后
    發(fā)表于 08-23 10:52 ?942次閱讀

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

    一樣,但是具體的實(shí)現(xiàn)還是有區(qū)別的。 當(dāng)然深入了解select和update的具體區(qū)別并不是只為了面試,當(dāng)希望Mysql能夠高效的執(zhí)行的時(shí)候,最好的辦法就是清楚的了解Mysql是如何執(zhí)行
    的頭像 發(fā)表于 11-03 09:41 ?3799次閱讀
    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é)各方資料,就有了下面這一篇博文了。 本文將從MySQL總體架構(gòu)---》查詢
    的頭像 發(fā)表于 09-12 09:44 ?1692次閱讀
    一條SQL<b class='flag-5'>語(yǔ)句</b>是怎么被<b class='flag-5'>執(zhí)行</b>的

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

    之前我們講過(guò)了一條SQL查詢語(yǔ)句是如何執(zhí)行的,那么插入(INSERT)、更新(UPDATE)和刪除(DELETE)操作的流程又是什么樣子呢? 其實(shí)對(duì)于MySQL而言,只有兩種通常
    的頭像 發(fā)表于 02-14 15:40 ?798次閱讀
    簡(jiǎn)述SQL<b class='flag-5'>更新語(yǔ)句</b>的<b class='flag-5'>執(zhí)行</b>流程1

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

    之前我們講過(guò)了一條SQL查詢語(yǔ)句是如何執(zhí)行的,那么插入(INSERT)、更新(UPDATE)和刪除(DELETE)操作的流程又是什么樣子呢? 其實(shí)對(duì)于MySQL而言,只有兩種通常
    的頭像 發(fā)表于 02-14 15:40 ?714次閱讀
    簡(jiǎn)述SQL<b class='flag-5'>更新語(yǔ)句</b>的<b class='flag-5'>執(zhí)行</b>流程2

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

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

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

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

    mysql基礎(chǔ)語(yǔ)句大全

    MySQL是一個(gè)開(kāi)放源碼的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),使用SQL作為其查詢語(yǔ)言。它是Web開(kāi)發(fā)中常用的數(shù)據(jù)庫(kù)管理系統(tǒng)之一。MySQL的語(yǔ)法十分豐富,可以執(zhí)行各種數(shù)據(jù)庫(kù)操作,包括創(chuàng)建、修改、刪除和查詢等
    的頭像 發(fā)表于 11-16 16:42 ?2287次閱讀

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

    語(yǔ)句,它的基本結(jié)構(gòu)如下: for (初始化語(yǔ)句; 條件表達(dá)式; 更新語(yǔ)句) {循環(huán)體;} for語(yǔ)句執(zhí)行流程: 運(yùn)行初始化
    的頭像 發(fā)表于 01-05 14:02 ?3194次閱讀
    主站蜘蛛池模板: 国产美女一区二区三区 | 久久福利免费视频 | 国产欧美精品一区二区色综合 | 日日干夜夜操s8 | 欧美一卡二三卡四卡不卡 | 18美女扒开尿口无遮挡 | 欧美一级看片免费观看视频在线 | 色人阁婷婷 | 手机在线视频你懂的 | 亚洲三级在线看 | 国产精品三级a三级三级午夜 | 三级视频欧美 | 欧洲亚洲一区 | 欧美人与zoxxxx| 欧洲妇女成人淫片aaa视频 | 嫩草影院播放地址一二三 | 国产亚洲精品仙踪林在线播放 | 国产做a爰片久久毛片 | 久热久 | 欧美综合国产精品日韩一 | 天天做天天爱天天大综合 | 天天综合天天做天天综合 | 色视频在线免费 | 午夜毛片在线观看 | 欧美jizzhd精品欧美4k | 中文字幕在线一区 | 久久精品看片 | 狠狠色色综合网站 | 国产精品午夜自在在线精品 | bt种子在线搜索 | 国产亚洲精品久久久极品美女 | 天天操91| 欧美三级日韩三级 | 国产一级久久免费特黄 | 国产国拍亚洲精品mv在线观看 | 亚州一级毛片在线 | 亚洲成人免费看 | 岛国午夜 | 欧美日韩一区在线观看 | 黄频网| 老外一级黄色片 |