mysql查詢以及日誌總結

1、mysql基本架構以及查詢流程

  • MySQL拿到一個查詢請求後,會先到查詢緩存看看,之前是不是執行過這條語句。
  • 只要是你之前執行過的語句,都會在內存裏面用key-value形式存儲着。查詢的時候就會拿着語句先去緩存中查詢,如果能夠命中就返回緩存的value,如果不命中就執行後面的階段。

  • 只要對錶有任何的更新,這個表的所有查詢緩存就會全部被清空

  • 緩存在MySQL8.0之後就取消了。

  • 在緩存沒有命中的情況下,就開始執行語句了,你寫的語句有沒有語法錯誤,這是接下來MySQL比較關心的點。

  • 會先做詞法分析,你的語句有這麼多單詞、空格,MySQL就需要識別每個字符串所代表的是什麼,是關鍵字,還是表名,還是列名等等。然後就開始語法分析,根據詞法分析的結果,語法分析會判斷你sql的對錯,錯了會提醒你的,並且會提示你哪裏錯了。

  • 之後就是優化器,因爲我們建立表可能會建立很多索引,優化有一步就是要確認使用哪個索引,比如使用你的主鍵索引,聯合索引還是什麼索引更好。還有就是對執行順序進行優化,條件那麼多,先查哪個表,還是先關聯,會出現很多方案,最後由優化器決定選用哪種方案。

  • 最後就是執行了,執行就交給執行器去做。

  • 參考文章

2、Mysql數據庫都有哪些日誌呢?分別什麼作用?

  • 一般常見的有下面幾種
  • binlog日誌:主要是恢復數據,主從複製
  • redo log日誌:保證事物中的持久化操作
  • undo log日誌:回滾和多版本控制(MVCC)

3、binlog 介紹:

  • binlog記錄了數據庫表結構和表數據變更,比如update/delete/insert/truncate/create。它不會記錄select
  • 主要有兩個作用:複製和恢復數據
  • MySQL在公司使用的時候往往都是一主多從結構的,從服務器需要與主服務器的數據保持一致,這就是通過binlog來實現的

  • 數據庫的數據被幹掉了,我們可以通過binlog來對數據進行恢復。

  • 主從複製原理在這裏插入圖片描述

4、redo log 介紹:

  • 假設我們有一條sql語句:update user_table set name='java3y' where id = '3'
  • MySQL執行這條SQL語句,肯定是先把id=3的這條記錄查出來,然後將name字段給改掉。
  • 實際上Mysql的基本存儲結構是(記錄都存在頁裏邊),所以MySQL是先把這條記錄所在的找到,然後把該頁加載到內存中,將對應記錄進行修改。

  • 現在就可能存在一個問題:如果在內存中把數據改了,還沒來得及落磁盤,而此時的數據庫掛了怎麼辦?顯然這次更改就丟了。

  • 如果每個請求都需要將數據立馬落磁盤之後,那速度會很慢,MySQL可能也頂不住。所以MySQL是怎麼做的呢?

  • MySQL引入了redo log,內存寫完了,會先寫到buffer中,再真正落到磁盤中的redo log,這份redo log記載着這次在某個頁上做了什麼修改

                    

  • redo log也是需要寫磁盤的,但它的好處就是順序IO(我們都知道順序IO比隨機IO快非常多)。
  • 所以,redo log的存在爲了:當我們修改的時候,寫完內存了,但數據還沒真正寫到磁盤的時候。此時我們的數據庫掛了,我們可以根據redo log來對數據進行恢復。因爲redo log是順序IO,所以寫入的速度很快,並且redo log記載的是物理變化(xxxx頁做了xxx修改),文件的體積很小,恢復速度很快

5、binlog和redo log區別

  • 看到這裏,你可能會想:binlogredo log 這倆也太像了吧,都是用作”恢復“的。其實他倆除了"恢復"這塊是相似的,很多都不一樣

  • binlog記載的是update/delete/insert這樣的SQL語句,而redo log記載的是物理修改的內容(xxxx頁修改了xxx)。

  • 所以在搜索資料的時候會有這樣的說法:redo log 記錄的是數據的物理變化binlog 記錄的是數據的邏輯變化

  • redo log的作用是爲持久化而生的。寫完內存,如果數據庫掛了,那我們可以通過redo log來恢復內存還沒來得及刷到磁盤的數據,將redo log加載到內存裏邊,那內存就能恢復到掛掉之前的數據了。

  • binlog的作用是複製和恢復而生的。

    • 主從服務器需要保持數據的一致性,通過binlog來同步數據

    • 如果整個數據庫的數據都被刪除了,binlog存儲着所有的數據變更情況,那麼可以通過binlog來對數據進行恢復。

  • 又看到這裏,你會想:”如果整個數據庫的數據都被刪除了,那我可以用redo log的記錄來恢復嗎?“不能

  • 因爲功能的不同,redo log 存儲的是物理數據的變更,如果我們內存的數據已經刷到了磁盤了,那redo log的數據就無效了。所以redo log不會存儲着歷史所有數據的變更,文件的內容會被覆蓋的

  • redo log是MySQL的InnoDB引擎所產生的,binlog無論MySQL用什麼引擎,都會有的。

  • redo log事務開始的時候,就開始記錄每次的變更信息,而binlog是在事務提交的時候才記錄。

    • 如果寫redo log失敗了,那我們就認爲這次事務有問題,回滾,不再寫binlog

    • 如果寫redo log成功了,寫binlog,寫binlog寫一半了,但失敗了怎麼辦?我們還是會對這次的事務回滾,將無效的binlog給刪除(因爲binlog會影響從庫的數據,所以需要做刪除操作)

    • 如果寫redo logbinlog都成功了,那這次算是事務纔會真正成功。

    • 簡單來說:MySQL需要保證redo logbinlog數據是一致的,如果不一致,那就亂套了。

    • MySQL通過兩階段提交來保證redo logbinlog的數據是一致的。

6、undo log 介紹:

  • undo log主要有兩個作用:回滾和多版本控制(MVCC)
  • 在數據修改的時候,不僅記錄了redo log,還記錄undo log,如果因爲某些原因導致事務失敗或回滾了,可以用undo log進行回滾
  • undo log主要存儲的也是邏輯日誌,比如我們要insert一條數據了,那undo log會記錄的一條對應的delete日誌。我們要update一條記錄時,它會記錄一條對應相反的update記錄。
  • 這也應該容易理解,畢竟回滾嘛,跟需要修改的操作相反就好,這樣就能達到回滾的目的。因爲支持回滾操作,所以我們就能保證:“一個事務包含多個操作,這些操作要麼全部執行,要麼全都不執行
  • 因爲undo log存儲着修改之前的數據,相當於一個前版本,MVCC實現的是讀寫不阻塞,讀的時候只要返回前一個版本的數據就行了。
  • 參考文章

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章