<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          不會吧,不會吧,還有人不知道 binlog ?

          共 1625字,需瀏覽 4分鐘

           ·

          2021-08-24 17:55

          redo log它是物理日志,記錄內(nèi)容是“在某個數(shù)據(jù)頁上做了什么修改”,屬于InnoDB存儲引擎。

          binlog是邏輯日志,記錄內(nèi)容是語句的原始邏輯,類似于“給ID=2這一行的c字段加1”,屬于MySQL Server層。

          binlog

          不管用什么存儲引擎,只要發(fā)生了表數(shù)據(jù)更新,都會產(chǎn)生binlog日志。

          binlog到底是用來干嘛的?

          可以說MySQL數(shù)據(jù)庫的數(shù)據(jù)備份、主備、主主、主從都離不開binlog,需要依靠binlog來同步數(shù)據(jù),保證數(shù)據(jù)一致性。


          binlog會記錄所有涉及更新數(shù)據(jù)的邏輯操作,并且是順序?qū)憽?/span>

          記錄格式

          binlog日志有三種格式,可以通過binlog_format參數(shù)指定。

          • statement

          • row

          • mixed

          指定statement,記錄的內(nèi)容是SQL語句原文,比如執(zhí)行一條update T set update_time=now() where id=1,記錄的內(nèi)容如下。

          同步數(shù)據(jù)時,會執(zhí)行記錄的SQL語句,但是有個問題,update_time=now()這里會獲取當前系統(tǒng)時間,直接執(zhí)行會導致與原庫的數(shù)據(jù)不一致。

          為了解決這種問題,我們需要指定為row,記錄的內(nèi)容不再是簡單的SQL語句了,還包含操作的具體數(shù)據(jù),記錄內(nèi)容如下。

          row格式記錄的內(nèi)容看不到詳細信息,要通過mysqlbinlog工具解析出來。

          update_time=now()變成了具體的時間update_time=1627112756247,條件后面的@1、@2、@3都是該行數(shù)據(jù)第1個~3個字段的原始值(假設(shè)這張表只有3個字段)。

          這樣就能保證同步數(shù)據(jù)的一致性,通常情況下都是指定為row,這樣可以為數(shù)據(jù)庫的恢復與同步帶來更好的可靠性。

          但是這種格式,需要更大的容量來記錄,比較占用空間,恢復與同步時會更消耗IO資源,影響執(zhí)行速度。

          所以就有了一種折中的方案,指定為mixed,記錄的內(nèi)容是前兩者的混合。

          MySQL會判斷這條SQL語句是否可能引起數(shù)據(jù)不一致,如果是,就用row格式,否則就用statement格式。

          寫入機制

          binlog的寫入時機也非常簡單,事務(wù)執(zhí)行過程中,先把日志寫到binlog cache,事務(wù)提交的時候,再把binlog cache寫到binlog文件中。

          因為一個事務(wù)的binlog不能被拆開,無論這個事務(wù)多大,也要確保一次性寫入,所以系統(tǒng)會給每個線程分配一個塊內(nèi)存作為binlog cache。

          我們可以通過binlog_cache_size參數(shù)控制單個線程binlog cache大小,如果存儲內(nèi)容超過了這個參數(shù),就要暫存到磁盤(Swap)。

          binlog日志刷盤流程如下


          • 上圖的write,是指把日志寫入到文件系統(tǒng)的page cache,并沒有把數(shù)據(jù)持久化到磁盤,所以速度比較快

          • 上圖的fsync,才是將數(shù)據(jù)持久化到磁盤的操作

          writefsync的時機,可以由參數(shù)sync_binlog控制,默認是0。

          0的時候,表示每次提交事務(wù)都只write,由系統(tǒng)自行判斷什么時候執(zhí)行fsync。

          雖然性能得到提升,但是機器宕機,page cache里面的binglog會丟失。

          為了安全起見,可以設(shè)置為1,表示每次提交事務(wù)都會執(zhí)行fsync,就如同binlog日志刷盤流程一樣。

          最后還有一種折中方式,可以設(shè)置為N(N>1),表示每次提交事務(wù)都write,但累積N個事務(wù)后才fsync。

          在出現(xiàn)IO瓶頸的場景里,將sync_binlog設(shè)置成一個比較大的值,可以提升性能。

          同樣的,如果機器宕機,會丟失最近N個事務(wù)的binlog日志。


          有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)

          歡迎大家關(guān)注Java之道公眾號


          好文章,我在看??

          瀏覽 30
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久天天射一射 | 成人做爱无码 | 无码专区一区二区三区 | 夜夜草视频 | 麻豆人妻精品无码区 |