<a href="http://dwchaoyue.blog.51cto.com/2826417/1784509" target="_blank">http://dwchaoyue.blog.51cto.com/2826417/1784509</a>
mysql如何保證redolog和binlog的一緻性,安全性,效率。
和資料安轉相關的參數
sync_binlog:控制binlog的重新整理方式(寫入到磁盤)
innodb_flush_log_at_trx_commit:在innodb下控制着redo的寫入方式
innodb_support_xa:外部事務,用來保證binlog和redo一緻性的,俗稱兩段式送出
binlog_order_commits:按照binlog的寫入順序送出事務,保證redo和binlog的已執行
binlog_max_flush_queue_time: leader線程搜集binlog的逾時時間
2pc送出(官方支援)
(redo日志在prepare階段就已經sync),絕大部分都比較支援這種說法
<a href="http://dev.mysql.com/doc/refman/5.6/en/binary-log.html" target="_blank">http://dev.mysql.com/doc/refman/5.6/en/binary-log.html</a>
<a href="http://blog.itpub.net/15480802/viewspace-1411356" target="_blank">http://blog.itpub.net/15480802/viewspace-1411356</a>
<a href="http://www.linuxidc.com/Linux/2015-11/124942.htm" target="_blank">http://www.linuxidc.com/Linux/2015-11/124942.htm</a>
<a href="http://www.2cto.com/database/201306/221413.html" target="_blank">http://www.2cto.com/database/201306/221413.html</a>
2pc流程:(sync_binlog = 1,innodb_flush_log_at_trx_commit = 1 )
1.prepare階段:sync redo 日志(未sync的redo存放于innodb_log_buffer_size中),系統自動完成
擷取prepare_commit_mutex(一個全局鎖,一次隻能被一個事務擷取)
2.生成binlog,将binlog寫入檔案系統(未送出之前binlog存放在binlog_cache_size中),sync binlog,這一步受sync_binlog控制
3.送出commit 将commit标志sync ,釋放prepare_commit_mutex(這一步應該受innodb_flush_log_at_trx_commit的控制)
違背了這個參數的定義:innodb_flush_log_at_trx_commit
觀點二:redo日志在最後的commit的時候才sync
<a href="http://blog.itpub.net/28218939/viewspace-1975809" target="_blank">http://blog.itpub.net/28218939/viewspace-1975809</a>
2pc流程:(官方沒有明顯的支援這種說法)
1.prepare階段:擷取prepare_commit_mutex
2.生成binlog,将binlog寫入檔案系統(未送出之前binlog存放在binlog_cache_size中),sync binlog
3.送出commit 将redo log sync ,釋放prepare_commit_mutex
這種方式會造成binlog的日志記錄多餘redo日志記錄,在恢複的時候是如何恢複? 難道是以binlog為準,
不管這個事務的redo有沒有送出 ,隻要寫binlog就認為該事務以送出(現階段還沒有找到有關該說法).
innodb資料恢複流程
1.查找未送出的redo日志(找xid)
2.用xid去binlog查找對應的日志記錄
3.如果有就認為這個事務是送出的,并補充commit。如果沒有就認為是沒有送出的,在恢複的時候就rollback事務
###################################################################################################
以上2pc日志寫入方式是在 mysql5.6之前的方式,當sync_binlog=1的時候 系統的性能非常糟糕。
從5.6 之後就開始采用BLGC方式寫2pc日志,來提升性能
BLGC具體流程如下:(每一個階段隻有一個活躍的線程)
flush stage:已完成perpare階段的線程隊列
sync stage:flush隊列逾時(binlog_max_flush_queue_time)或者沒有線程産生binlog了 ,flush隊列開始sync隊列,将binlog寫入磁盤(合并io)
commit stage:隊列進入送出階段(這裡隻做送出操作,redo日志的寫入已經在prepare寫入)
個人了解:
flush stage:隊列中的第一個線程為leader線程,後面的線程為follower線程,leader線程主要負責收集待送出binlog的線程(線程準備階段之後自動進入flush階段),直到隊列為空,或者逾時(binlog_max_flush_queue_time),才進入sync stage
sync stage:如果flush stage隊列為空,則之前leader線程依然為leader線程,負責binlog的sync,否則變成follower線程(合并執行sync)
commit stage:sync完binlog的線程被放入commit隊列的末尾,等待送出
5.7 的組送出:
Step1. InnoDB Prepare,記錄目前的LSN到thd中。
Step2. 進入 Group Commit 的flush stage;Leader搜集隊列,同時算出隊列中最大的LSN。
Step3. 将InnoDB的redo log write/fsync到指定的LSN
Step4. 寫Binlog并進行随後的工作(sync Binlog, InnoDB commit
也就是将 redo log的write/sync延遲到了 binlog group commit的 flush stage 之後,sync binlog之前。
通過延遲寫redo log的方式,顯式的為redo log做了一次組寫入(redo log group write),并減少了(redo log) log_sys->mutex的競争。
組送出
<a href="http://www.tuicool.com/articles/rEZr2q" target="_blank">http://www.tuicool.com/articles/rEZr2q</a>
<a href="http://mysqllover.com/?p=581" target="_blank">http://mysqllover.com/?p=581</a>
innodb資料丢失的問題:
<a href="http://www.360doc.com/content/14/1019/00/12904276_418041635.shtml" target="_blank">http://www.360doc.com/content/14/1019/00/12904276_418041635.shtml</a>
組送出的了解:
<a href="http://www.bitscn.com/pdb/mysql/201407/226226.html" target="_blank">http://www.bitscn.com/pdb/mysql/201407/226226.html</a>
<a href="http://www.cnblogs.com/cchust/p/4439107.html" target="_blank">http://www.cnblogs.com/cchust/p/4439107.html</a>
本文轉自 lirulei90 51CTO部落格,原文連結:http://blog.51cto.com/lee90/1969656,如需轉載請自行聯系原作者