流程圖

          這是在網(wǎng)上找到的一張流程圖,寫的比較好,大家可以先看圖,然后看詳細(xì)閱讀下面的各個步驟。


          執(zhí)行流程:

          1.連接驗證及解析

          客戶端與MySQL Server建立連接,發(fā)送語句給MySQL
          Server,接收到后會針對這條語句創(chuàng)建一個解析樹,然后進行優(yōu)化,(解析器知道語句是要執(zhí)行什么,會評估使用各種索引的代價,然后去使用索引,以及調(diào)節(jié)表的連接順序)然后調(diào)用innodb引擎的接口來執(zhí)行語句。

          2.寫undo log

          innodb 引擎首先開啟事務(wù),對舊數(shù)據(jù)生成一個UPDATE的語句(如果是INSERT會生成UPDATE語句),用于提交失敗后回滾,寫入undo
          log,得到回滾指針,并且更新這個數(shù)據(jù)行的回滾指針和版本號(會設(shè)置為更新的事務(wù)id)。

          3.從索引中查找數(shù)據(jù)

          根據(jù)查詢條件去B+樹中找到這一行數(shù)據(jù)(如果是唯一性索引,查到第一個數(shù)據(jù)就可以了(因為有唯一性約束),如果是普通索引,會把所有數(shù)據(jù)查找出來。)

          4.更新數(shù)據(jù)

          首先判斷數(shù)據(jù)頁是否在內(nèi)存中?

          4.1 如果數(shù)據(jù)頁在內(nèi)存中

          先判斷更新的索引是普通索引還是唯一性索引?

          4.1.1 普通索引

          如果更新的索引是普通索引,直接更新內(nèi)存中的數(shù)據(jù)頁

          4.1.2 唯一性索引

          如果更新的索引是唯一性索引,判斷更新后是否會破壞數(shù)據(jù)的唯一性,不會的話就更新內(nèi)存中的數(shù)據(jù)頁。

          4.2 如果數(shù)據(jù)頁不在內(nèi)存中

          先判斷更新的索引是普通索引還是唯一性索引?

          4.2.1 普通索引

          如果是更新的索引是普通索引,將對數(shù)據(jù)頁的更新操作記錄到change buffer,change buffer會在空閑時異步更新到磁盤。

          4.2.2 唯一性索引

          如果是更新的索引是唯一性索引,因為需要保證更新后的唯一性,所以不能延遲更新,必須把數(shù)據(jù)頁從磁盤加載到內(nèi)存,然后判斷更新后是否會數(shù)據(jù)沖突,不會的話就更新數(shù)據(jù)頁。

          5.寫undo log(prepare狀態(tài))

          將對數(shù)據(jù)頁的更改寫入到redo log,將redo log設(shè)置為prepare狀態(tài)。

          6.寫bin log(commit狀態(tài)),提交事務(wù)

          通知MySQL server已經(jīng)更新操作寫入到redo log 了,隨時可以提交,將執(zhí)行的SQL寫入到bin log日志,將redo
          log改成commit狀態(tài),事務(wù)提交成功。(一個事務(wù)是否執(zhí)行成功的判斷依據(jù)是是否在bin log中寫入成功。寫入成功后,即便MySQL
          Server崩潰,之后恢復(fù)時也會根據(jù)bin log, redo log進行恢復(fù)。具體可以看看下面的崩潰恢復(fù)原則)

          補充資料:

          二段提交制是什么?

          更新時,先改內(nèi)存中的數(shù)據(jù)頁,將更新操作寫入redo log日志,此時redo log進入prepare狀態(tài),然后通知MySQL
          Server執(zhí)行完了,隨時可以提交,MySQL Server將更新的SQL寫入bin log,然后調(diào)用innodb接口將redo
          log設(shè)置為提交狀態(tài),更新完成。
          如果只是寫了bin log就提交,那么忽然發(fā)生故障,主節(jié)點可以根據(jù)redo log恢復(fù)數(shù)據(jù)到最新,但是主從同步時會丟掉這部分更新的數(shù)據(jù)。
          如果只是寫binlog,然后寫redo log,如果忽然發(fā)生故障,主節(jié)點根據(jù)redo log恢復(fù)數(shù)據(jù)時就會丟掉這部分?jǐn)?shù)據(jù)。
          MySQL崩潰后,事務(wù)恢復(fù)時的判斷規(guī)則是怎么樣的?(以redolog是否commit或者binlog是否完整來確定)
          如果 redo log 里面的事務(wù)是完整的,也就是已經(jīng)有了 commit 標(biāo)識,則直接提交;

          如果 redo log 里面的事務(wù)只有完整的 prepare,則判斷對應(yīng)的事務(wù) binlog 是否存在并完整:a. 如果是,則提交事務(wù);b. 否則,回滾事務(wù)。

          undo log是什么?

          undo log主要是保證事務(wù)的原子性,事務(wù)執(zhí)行失敗就回滾,用于在事務(wù)執(zhí)行失敗后,對數(shù)據(jù)回滾。undo
          log是邏輯日志,記錄的是SQL。(可以認(rèn)為當(dāng)delete一條記錄時,undo
          log中會記錄一條對應(yīng)的insert記錄,反之亦然,當(dāng)update一條記錄時,它記錄一條對應(yīng)相反的update記錄。)
          在事務(wù)提交后,undo
          log日志不會立即刪除,會放到一個待刪除的鏈表中,有purge線程判斷是否有其他事務(wù)在使用上一個事務(wù)之前的版本信息,然后決定是否可以清理,簡單的來說就是前面的事務(wù)都提交成功了,這些undo才能刪除。
          change buffer是什么(就是將更新數(shù)據(jù)頁的操作緩存下來)
          在更新數(shù)據(jù)時,如果數(shù)據(jù)行所在的數(shù)據(jù)頁在內(nèi)存中,直接更新內(nèi)存中的數(shù)據(jù)頁。
          如果不在內(nèi)存中,為了減少磁盤IO的次數(shù),innodb會將這些更新操作緩存在change
          buffer中,在下一次查詢時需要訪問這個數(shù)據(jù)頁時,在執(zhí)行change buffer中的操作對數(shù)據(jù)頁進行更新。

          適合寫多讀少的場景,因為這樣即便立即寫了,也不太可能會被訪問到,延遲更新可以減少磁盤I/O,只有普通索引會用到,因為唯一性索引,在更新時就需要判斷唯一性,所以沒有必要。

          redo log 是什么?

          redo log就是為了保證事務(wù)的持久性。因為change buffer是存在內(nèi)存中的,萬一機器重啟,change
          buffer中的更改沒有來得及更新到磁盤,就需要根據(jù)redo log來找回這些更新。
          優(yōu)點是減少磁盤I/O次數(shù),即便發(fā)生故障也可以根據(jù)redo log來將數(shù)據(jù)恢復(fù)到最新狀態(tài)。
          缺點是會造成內(nèi)存臟頁,后臺線程會自動對臟頁刷盤,或者是淘汰數(shù)據(jù)頁時刷盤,此時收到的查詢請求需要等待,影響查詢。

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                美女操逼黄网站 | 我要看老女人黄色一结片 | 男人操女人的视频 | 臭小子啊轻点灬太粗太长了的视频 | 国产熟女一区二区三区五月婷 |