MYSQL 日誌

mysql 日誌,首先記住一個mysql原則 : 日誌先行。
下文總結:html

  1. server層,binlog+relaylog 用於主從複製。可是會出現case-unsave。binlog是邏輯日誌。
  2. 存儲引擎層-innodb,redolog+undolog,解決buffer-pool數據不持久化,實現crash-safe。可是 redolog不具備像binlog同樣歸檔的做用。redolog 是物理日誌。
  3. redolog的兩階段提交,保證了redolog和binlog的數據一致性。

MySQL有兩層,一層是Server層,一層是存儲引擎層。
1.binary log 和 relay log。 它Server層的日誌。
2.redo log 和 undo log。 它是InnoDB引擎特有的日誌mysql


binlog的一主一從複製,基本過程:算法

在 Master 與 Slave 之間實現整個主從複製的過程是由三個線程參與完成的。其中有兩個線程(SQL 線程和 IO 線程)在 Slave 端,另一個線程(IO 線程)在 Master 端。sql

  • a.Master將數據改變記錄到二進制日誌(binary log)中
  • b.Slave上面的IO線程鏈接上Master,並請求從指定日誌文件的指定位置(或者從最開始的日誌)以後的日誌內容
    (日誌文件名和日誌文件存放位置就是在配置主從複製任務時執行change master命令時指定的)
  • c.Master接收到來自Slave的IO線程的請求後, Master 服務器上的 IO 線程根據 Slave服務器的 IO 線程請求的信息, 讀取指定 binlog 日誌文件指定位置以後的 binlog 日誌信息,而後返回給 Slave 端的IO 線程。 返回的信息中除了 binlog 日誌內容外, 還有本次返回日誌內容後在 Master 服務器端的新的 binlog文件名以及在 binlog 中的下一個指定更新位置,也就是是下一次複製內容該從什麼地方開始。
  • d.當 Slave 服務器的 IO 線程獲取來自 Master 服務器上 IO 線程發送的日誌內容及日誌文件和位置點後, 將 binlog日誌內容依次寫入到 Slave 端自身的 relay log(即中繼日誌)文件(mysql-relay-bin.xxxxxx)的最末端,並將新的 binlog 文件名和位置記錄到 master-info 文件中, 以便下一次讀取 Master 端新 binlog 日誌時,能告訴 Master 服務器須要重新 binlog 日誌的哪一個文件哪一個位置開始請求新的 binlog 日誌內容。
  • e.Slave 服務器端的 SQL 線程會實時檢測本地 relay log 中新增長的日誌內容, 而後及時的把 relay log文件中的內容解析成在 Master 端曾經執行的 SQL 語句的內容, 並在自身 Slave 服務器上按語句的順序執行應用這些 SQL語句,同時把執行狀態信息保存在 relay-log.info 文件,應用完畢後清理應用過的日誌。
  • f.通過了上面的過程,就能夠確保在 Master 端和 Slave 端執行了一樣的 SQL 語句。 當複製狀態正常的狀況下,Master端和 Slave 端的數據是徹底同樣的。

    wKiom1N9fw-jbU08AAN-tSxOxl0447.jpg

參看文章:http://www.javashuo.com/article/p-xlecglii-ey.html數據庫


crash-safe 概念
slave crash-unsafe 的緣由在於應用 binlog 和更新文件的非原子性。
也就是上文的第e步驟會有問題。segmentfault

開始解釋:
IO thread 的執行狀態信息保存在 master.info 文件, SQL thread 的執行狀態信息保存在 relay-log.info 文件。緩存

下面出現這樣一個場景:
SQL thread 已經應用 relay-log.01 的4個事務安全

trx1(pos:10)
trx2(pos:20)
trx3(pos:30)
trx4(pos:40) 服務器

可是 SQL thread 更新位點 (relay-log.01,30) 到 relay-log.info 文件中,忽然系統崩潰了。slave 實例重啓的時候 sql thread 會重複執行事務 trx4。這就是典型的crash-unsafe了。併發

crash-safe 的原理:

crash-safe 狀況下 SQL_thread 的工做模式
  SQL thread 執行事務和更新 mysql.slave_replay_log_info 的語句合併爲同一個事務,由 MySQL 系統來保障事務的原子性。

clipboard.png
綠色的表明實際業務的事務,藍色的是開啓 MySQL 執行的更新slave_replay_log_info 相關位點信息的 sql ,而後將這兩個 sql 合併在一個事務中執行,利用 MySQL 事務機制和 InnoDB 表保障原子性。不會出現應用 binlog 和更新位點信息兩個動做割裂致使不一致的問題。


buffer pool 概念 -- innodb存儲引擎帶的一個緩存池

用戶對數據庫的最基本要求就是能高效的讀取和存儲數據,可是讀寫數據都涉及到與低速的設備交互,爲了彌補二者之間的速度差別,全部數據庫都有緩存池,用來管理相應的數據頁,提升數據庫的效率,固然也因  爲引入了這一中間層,數據庫對內存的管理變得相對比較複雜。
 ---buffer pool是innodb存儲引擎帶的一個緩存池,查詢數據的時候,它首先會從內存中查詢,若是內存中存在的話,直接返回,從而提升查詢響應時間。(功能)
 ---修改更新等操做會改變buffer pool的一些數據,經過LRU算法更新,將buffer pool的命中率維持在一個比較高的水平。 (內存管理)
 ---是怎麼將buffer pool中的數據同步到磁盤。想一想若是更新一次buffer pool就寫一次磁盤,那這樣子的效率和直接讀寫磁盤並無提升多少,這裏就須要設計出同步策略來解決這個問題。(redo.log,undo.log)
 ---引入buffer pool會致使更新的數據不會實時地將數據持久化到硬盤,當系統崩潰時,雖然buffer pool中的數據丟失,數據沒有持久化。可是系統能夠根據redo log的內容,將全部數據恢復到最新的狀態。
 ---修改buffer pool的數據後,同時還要將此操做記錄在事務日誌中去,保證事物安全的。事務日誌文件是InnoDB引擎申請連續物理空間的固定大小的一個文件,對日誌文件的讀寫基本上是順序讀寫,尋址操做甚少。(redo.log順序讀寫,減小尋址操做)
 ---Myisam引擎有Key Cache:只緩存索引文件,數據文件的緩存交由操做系統自己來完成。而buffer pool存放各類數據的緩存,包括索引頁和數據頁。

參看文章:https://www.cnblogs.com/iamsu...


redo log

介紹:由於最開始MySQL裏並無InnoDB引擎。MySQL自帶的引擎是MyISAM,可是MyISAM沒有crash-safe的能力,binlog日誌只能用於歸檔。
而InnoDB是另外一個公司以插件形式引入MySQL的,既然只依靠binlog是沒有crash-safe能力的,因此InnoDB使用另一套日誌系統——也就是redo log來實現crash-safe能力。

redo log是固定大小的,好比能夠配置爲一組4個文件,每一個文件的大小是1GB,那麼總共就能夠記錄4GB的操做。從頭開始寫,寫到末尾就又回到開頭循環寫。因此redo log 不想binlog同樣會有歸檔功能。

將redo log的寫入拆成了兩個步驟:prepare和commit,這就是"兩階段提交"。 兩階段提交主要解決 binlog 和 InnoDB redo log 的數據一致性的問題.
以下圖:
MySQL 中 6 個常見的日誌問題


undo log
Undo Log 是爲了實現事務的原子性,在MySQL數據庫InnoDB存儲引擎中,還用Undo Log來實現多版本併發控制(簡稱:MVCC)。

  • Undo + Redo事務的簡化過程
    假設有A、B兩個數據,值分別爲1,2.
    A.事務開始.
    B.記錄A=1到undo log.
    C.修改A=3.
    D.記錄A=3到redo log.
    E.記錄B=2到undo log.
    F.修改B=4.
    G.記錄B=4到redo log.
    H.將redo log寫入磁盤。
    I.事務提交

參看文章:http://www.zhdba.com/mysqlops/2012/04/06/innodb-log1/

相關文章
相關標籤/搜索