1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        面試官:你說(shuō)說(shuō)一條更新SQL的執(zhí)行過(guò)程?

        共 2203字,需瀏覽 5分鐘

         ·

        2021-08-18 10:12

        在上一篇《面試官:你說(shuō)說(shuō)一條查詢(xún)SQL的執(zhí)行過(guò)程?》中描述了Mysql的架構(gòu)分層,通過(guò)解析器、優(yōu)化器和執(zhí)行引擎完成一條SQL查詢(xún)的過(guò)程,那這一篇續(xù)上繼續(xù)說(shuō)明一條更新SQL的執(zhí)行過(guò)程。

        對(duì)于一個(gè)SQL語(yǔ)句的更新來(lái)說(shuō),前面的流程都可以說(shuō)類(lèi)似的,通過(guò)解析器進(jìn)行語(yǔ)法分析,優(yōu)化器優(yōu)化,執(zhí)行引擎去執(zhí)行,這個(gè)都沒(méi)有什么問(wèn)題,重點(diǎn)在于多了一點(diǎn)東西,那就是redo_logundo_logbinlog。

        執(zhí)行流程大致如下:

        1. 首先客戶端發(fā)送請(qǐng)求到服務(wù)端,建立連接。
        2. 服務(wù)端先看下查詢(xún)緩存,對(duì)于更新某張表的SQL,該表的所有查詢(xún)緩存都失效。
        3. 接著來(lái)到解析器,進(jìn)行語(yǔ)法分析,一些系統(tǒng)關(guān)鍵字校驗(yàn),校驗(yàn)語(yǔ)法是否合規(guī)。
        4. 然后優(yōu)化器進(jìn)行SQL優(yōu)化,比如怎么選擇索引之類(lèi),然后生成執(zhí)行計(jì)劃。
        5. 執(zhí)行引擎去存儲(chǔ)引擎查詢(xún)需要更新的數(shù)據(jù)。
        6. 存儲(chǔ)引擎判斷當(dāng)前緩沖池中是否存在需要更新的數(shù)據(jù),存在就直接返回,否則去從磁盤(pán)加載數(shù)據(jù)。
        7. 執(zhí)行引擎調(diào)用存儲(chǔ)引擎API去更新數(shù)據(jù)。
        8. 存儲(chǔ)引擎更新數(shù)據(jù),同時(shí)寫(xiě)入undo_log、redo_log信息。
        9. 執(zhí)行引擎寫(xiě)binlog,提交事務(wù),流程結(jié)束。

        可以看到相比于查詢(xún)流程,實(shí)際上更新多了關(guān)于undo_log和redo_log的流程,接下來(lái)再具體探討一下這幾個(gè)流程的執(zhí)行過(guò)程是什么樣子。

        redo_log

        redo_log按照字面翻譯稱(chēng)為重做日志,是InnoDB存儲(chǔ)引擎特有的,用于保證事務(wù)的原子性和持久性。怎么理解呢?簡(jiǎn)單來(lái)說(shuō)就是保存我們執(zhí)行的更新語(yǔ)句的記錄,如果服務(wù)器或者M(jìn)ysql宕機(jī),通過(guò)redo_log可以恢復(fù)更新的數(shù)據(jù)。

        按照上述流程來(lái)舉例的話,比如update user set age=20 where id=1這樣的簡(jiǎn)單更新SQL,我們不管執(zhí)行引擎怎么拿到的數(shù)據(jù),不管是從緩沖池拿的還是磁盤(pán)拿到的,這條現(xiàn)在數(shù)據(jù)都在緩沖池里面,然后去緩沖池的數(shù)據(jù)把age改成10。

        緩沖池內(nèi)存中的數(shù)據(jù)已經(jīng)更新好了,那么接下來(lái)就該開(kāi)始寫(xiě)redo_log了,只是redo_log也不是直接寫(xiě)文件的,一般都是這樣對(duì)吧,直接寫(xiě)的話性能太差了,所以就有redo_log_buffer叫做redo_log緩沖。

        在寫(xiě)redo_log的時(shí)候先把數(shù)據(jù)寫(xiě)到redo_log緩沖區(qū),然后異步寫(xiě)入磁盤(pán),很顯然,極端情況下會(huì)有丟失數(shù)據(jù)的可能。

        控制這個(gè)刷盤(pán)策略的的參數(shù)叫做innodb_flush_log_at_trx_commit

        這個(gè)參數(shù)有3個(gè)值:0|1|2,默認(rèn)的話是1。

        0代表提交事務(wù)時(shí)不會(huì)寫(xiě)入磁盤(pán),這樣的話性能當(dāng)然最好,但是在Mysql宕機(jī)的情況會(huì)丟失上一秒的事務(wù)的數(shù)據(jù)。

        1代表提交事務(wù)一定會(huì)進(jìn)行一次刷盤(pán),同步當(dāng)然性能最差,但是也最安全。

        2代表寫(xiě)入文件系統(tǒng)的緩存,不進(jìn)行刷盤(pán)。這個(gè)選項(xiàng)性能略差于1,Mysql宕機(jī)的話對(duì)數(shù)據(jù)沒(méi)有任何影響,只有在操作系統(tǒng)宕機(jī)才會(huì)丟失數(shù)據(jù),這種情況下默認(rèn)Mysql每秒會(huì)執(zhí)行一次刷盤(pán)。

        使用0或者2雖然提高了性能,但是變相的也喪失了事務(wù)的持久性。

        undo_log

        重做日志保證了事務(wù)的持久性,保證能夠在宕機(jī)后恢復(fù)事務(wù)的數(shù)據(jù),那么另外一種情況就是事務(wù)在需要回滾的時(shí)候怎么辦?這時(shí)候就是undo_log的作用了,它保證了事務(wù)的一致性。

        對(duì)于undo_log來(lái)說(shuō),簡(jiǎn)單理解就是做了逆向操作。

        比如insert一條數(shù)據(jù),就對(duì)應(yīng)生成delete,update語(yǔ)句則生成相反的更新語(yǔ)句,這樣做到將數(shù)據(jù)修改回之前的狀態(tài)。

        binlog

        binlog稱(chēng)為二進(jìn)制日志,大家都很熟悉,記錄了改變數(shù)據(jù)庫(kù)的那些SQL語(yǔ)句,對(duì)于這里來(lái)說(shuō),更新語(yǔ)句當(dāng)然是了。

        通過(guò)不同于redo_log是獨(dú)屬于存儲(chǔ)引擎獨(dú)有的東西,binlog則是Mysql本身產(chǎn)生的日志。

        不同于redo_log是物理日志,binlog和undo_log都屬于邏輯日志。

        這有什么區(qū)別呢?

        簡(jiǎn)單來(lái)說(shuō),邏輯日志可以認(rèn)為就是存儲(chǔ)的SQL本身,而物理日志看看redo_log存儲(chǔ)的是啥就知道了,關(guān)于page_id頁(yè)ID,offset偏移量啊這些東西,記錄的是對(duì)頁(yè)的修改。

        另外物理日志可以保證冪等性,而邏輯日志則不一定能,除非本身SQL就是冪等的。

        上面我們提到了redo_log的刷盤(pán)策略,binlog就和它非常類(lèi)似了,控制參數(shù)是sync_binlog

        默認(rèn)值為0,相當(dāng)于是innodb_flush_log_at_trx_commit的值為2,由文件系統(tǒng)控制,同樣如果服務(wù)器宕機(jī),binlog丟失,當(dāng)然我們也可以改成1,就和redo_log的效果是一樣,每1次事務(wù)提交都同步寫(xiě)入磁盤(pán)。

        事務(wù)

        為了保證寫(xiě)redo_log和binlog的一致性,實(shí)際采用了二階段提交的方式。

        prepare階段:根據(jù)innodb_flush_log_at_trx_commit設(shè)置的刷盤(pán)策略決定是否寫(xiě)入磁盤(pán),標(biāo)記為prepare狀態(tài)。

        commit階段:寫(xiě)入binlog日志,事務(wù)標(biāo)記為提交狀態(tài)。

        總結(jié)

        ·················END·················



        往期推薦

        聽(tīng)說(shuō)你對(duì)explain 很懂?

        面試官:你說(shuō)說(shuō)一條查詢(xún)SQL的執(zhí)行過(guò)程?| 文末送書(shū)

        不管卷不卷,面試還是得問(wèn)問(wèn)你G1原理!


        瀏覽 113
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            日本熟妇HD | 欧美草逼网 | 国产成人偷拍视频 | 麻豆成人视频 | 看全色黄大色大片 | 韩国黄色1级片 | 娇妻被别人调教成绿奴电影 | 午夜男女福利免费区 | 黄片免费链接 | 国产三男一女免费视频观看 |