回覆列表
  • 1 # 大國師魂系列

    引數設定如下:mysql的innodb中事務日誌ib_logfile(0/1)

    概念:

    事務日誌或稱redo日誌,在mysql中預設以ib_logfile0,ib_logfile1名稱存在,可以手工修改引數,調節開啟幾組日誌來服務於當前mysql資料庫,mysql採用順序,迴圈寫方式,每開啟一個事務時,會把一些相關資訊記錄事務日誌中(記錄對資料檔案資料修改的物理位置或叫做偏移量);

    這個系列檔案個數由引數innodb_log_files_in_group控制,若設定為4,則命名為ib_logfile0~3。

    這些檔案的寫入是順序、迴圈寫的,logfile0寫完從logfile1繼續,logfile3寫完則logfile0繼續。

    作用:

    在系統崩潰重啟時,作事務重做;在系統正常時,每次checkpoint時間點,會將之前寫入事務應用到資料檔案中。

    Ib_logfile的checkpoint field

    實際上不僅要記錄checkpoint做到哪兒(LOG_CHECKPOINT_LSN),還要記錄用到了哪個位置(LOG_CHECKPOINT_OFFSET)等其他資訊。所以在ib_logfile0的頭部預留了空間,用於記錄這些資訊。

    因此即使使用後面的logfile,每次checkpoint完成後,ib_logfile0都是要更新的。同時你會發現所謂的順序寫盤,也並不是絕對的

    相關的一些數字

    a) InnoDB留了兩個checkpoint filed,按照註釋的解釋,目的是為了能夠“write alternately”

    b) 每個checkpint field需要的大小空間為304位元組。(相關定義在log0log.h)

    c) 第一個checkpoint的起始位置在ib_logfile0的第512位元組(OS_FILE_LOG_BLOCK_SIZE)處;

    d) 第二個在1536 (3 * OS_FILE_LOG_BLOCK_SIZE)位元組處。

    特點:

    redo log只是記錄所有innodb表資料的變化。

    redo log只是記錄正在執行中的dml以及ddl語句。

    redo log可以作為異常down機或者介質故障後的資料恢復使用

    引入一個問題:

    在m/s環境中,innodb寫完ib_logfile後,服務異常關閉,會不會主庫能用ib_logfile恢復資料,而

    binlog沒寫導致從庫同步時少了這個事務?從而導致主從不一致;

    redo日誌寫入方式:1.ib_logfile寫入當前事務更新資料,並標上事務準備trx_prepare2.寫入bin-log3.ib_logfile當前事務提交提交trx_commit

    恢復方式:

    如果ib_logfile已經寫入事務準備,那麼在恢復過程中,會依據bin-log中該事務是否存在恢復資料。

    假設:1)結束後異常,因沒有寫入bin-log,從庫不會同步這個事務,主庫上,重啟時,在恢復日誌中這個事務沒有commit,即rollback這個事務.2)結束後異常,這會bin-log已經寫入,從庫會同步這個事務。主庫依據恢復日誌和bin-log,也正常恢復此事務

    綜上描述:

    bin-log寫入完成,主從會正常完成事務;bin-log沒有寫入,主從庫rollback事務;不會出現主從庫不一致問題.

    相關引數(全域性&靜態):

    innodb_log_buffer_size

    innodb_log_file_size

    innodb_log_files_in_group

    innodb_log_group_home_dir

    innodb_flush_log_at_trx_commit

    innodb_log_buffer_size:

    事務日誌快取區,可設定1M~8M,預設8M,延遲事務日誌寫入磁碟,把事務日誌快取區想象形如"漏斗"狀,會不停向磁碟記錄快取的日誌記錄,而何時寫入透過引數innodb_flush_log_at_trx_commit控制,稍後解釋,啟用大的事務日誌快取,可以將完整執行大事務日誌,

    暫時存放在事務快取區中,不必(事務提交前)寫入磁碟儲存,同時也起到節約磁碟空間佔用;

    innodb_log_file_size:控制事務日誌ib_logfile的大小,範圍5MB~4G;所有事務日誌ib_logfile0+ib_logfile1+..累加大小不能超過4G,事務日誌大,checkpoint會少,節省磁碟IO,但是大的事務日誌意味著資料庫crash時,恢復起來較慢.

    引入問題:修改該引數大小,導致ib_logfile檔案的大小和之前存在的檔案大小不匹配

    innodb_log_files_in_group:DB中設定幾組事務日誌,預設是2;

    innodb_log_group_home_dir:事務日誌存放目錄,不設定,ib_logfile0...存在在資料檔案目錄下

    innodb_flush_log_at_trx_commit:控制事務日誌何時寫盤和刷盤,安全遞增:0,2,1事務快取區:log_buffer;0:每秒一次事務快取區重新整理到檔案系統,同時檔案系統到磁碟同步,但是事務提交時,不會觸發log_buffer到檔案系統同步;2:每次事務提交時,會把事務快取區日誌重新整理到檔案系統中去,且每秒檔案系統到磁碟同步;1:每次事務提交時重新整理到磁碟,最安全;

    適用環境:0:磁碟IO能力有限,安全方便較差,無複製或複製延遲可以接受,如日誌性業務,mysql損壞丟失1s事務資料;2:資料安全性有要求,可以丟失一點事務日誌,複製延遲也可以接受,OS損壞時才可能丟失資料;1:資料安全性要求非常高,且磁碟IO能力足夠支援業務,如充值消費,敏感業務;

    引入ib_logfile的寫入策略

    1、基本概念

    a)、ib_logfile檔案個數由innodb_log_files_in_group配置決定,若為2,則在datadir目錄下有兩個檔案,命令從0開始,分別為ib_logfile0和ib_logfile.

    b)、檔案為順序寫入,當達到最後一個檔案末尾時,會從第一個檔案開始順序複用。

    c)、lsn: Log Sequence Number,是一個遞增的整數。 Ib_logfile中的每次寫入操作都包含至少1個log,每個log都帶有一個lsn。在記憶體page修復過程中,只有大於page_lsn的log才會被使用。

    d)、lsn的儲存在全域性變數log_sys中。遞增數值等於每個log的實際內容長度。即如果新增的一個log長度是len,則log_sys->lsn += len.

    e)、ib_logfile每次寫入以512(OS_FILE_LOG_BLOCK_SIZE)位元組為單位。實際寫入函式 log_group_write_buf (log/log0log.c)

    f)、每次寫盤後是否flush,由引數innodb_flush_log_at_trx_commit控制。

    2、log_sys介紹

    log_sys是一個全域性記憶體結構。以下說明幾個成員的意義。

    lsn

    表示已經分配的最後一個lsn的值。

    written_to_all_lsn

    n表示實際已經寫盤的lsn。需要這個值是因為並非每次生成log後就寫盤。

    flushed_to_disk_lsn

    表示刷到磁碟的lsn。需要這個值是因為並非每次寫盤後就flush。

    buf

    待寫入的內容儲存在buf中

    buf_size

    buf的大小。由配置中innodb_log_buffer_size決定,實際大小為innodb_log_buffer_size /16k * 16k。

    buf_next_to_write

    buf中下一個要寫入磁碟的位置

    buf_free

    buf中實際內容的最後位置。當buf_free> buf_next_to_write時,說明記憶體中還有資料未寫盤。

    3、相關更新

    用一個簡單的更新語句來說明log_sys以及ib_logfile的更新內容的過程。假設我們的更新只涉及到非索引的固定長度欄位。

    a) 在bufferpool中寫入undo log。 對於一個單一的語句,需要先建立一個undolog頭。

    b) 在bufferpool中寫入undo log的實際內容。

    c) 在log_sys->buf中寫入buffer page的更新內容。此處儲存了更新的完整資訊。

    d) 在log_sys->buf中寫入啟動事務(trx_prepare)的日誌

    e) 將c、d更新的log內容寫入ib_logfile中。

    f) 在log_sys->buf中寫入事務結束(trx_commit)的日誌

    g) 將f步驟的log內容寫入ib_logfile中。

    4、說明

    a) 完成上述所有操作時,資料檔案還沒有更新。

    b) 每次寫入log_sys->buf時同時更新lsn和buf_free。 每次寫ib_logfile時同時更新written_to_all_lsn和buf_next_to_write;

    c) 每次寫ib_logfile時以512位元組為對齊,如需寫入600位元組,則實際寫入1k。寫到最後一個檔案末尾則從第一個檔案重複使用。

    d) 從上述流程看到,在a~d過程中若出現異常關閉,由於沒有寫入到磁碟中,因此整個事務放棄;若在e剛完成時出現異常關閉,雖然事務內容已經寫盤,但沒有提交。在重啟恢復的時候,發現這個事務還沒有提交,邏輯上整個事務放棄。 (重啟日誌中會有Found 1 prepared transaction(s) in InnoDB字樣)。在g完成後出現異常關閉,則能夠在重啟恢復中正常提交。

    在e和f之間會寫mysql的bin-log,若bin-log寫完前異常關閉,事務無效,bin-log寫入成功後,則異常重啟後能夠根據bin-log恢復事務的修改。

    e) 若涉及到索引更新,在步驟c之後會增加索引更新的log。由於索引可能有merge過程,因此在merge過程中會另外增加寫入一個log。但事務完全提交仍在步驟g中。索引的更新由於已經寫盤,並不會因此丟失。

  • 中秋節和大豐收的關聯?
  • hello樹先生想要表達的意思是什麼?