溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

MySQL double write

發(fā)布時(shí)間:2020-08-09 17:28:56 來(lái)源:ITPUB博客 閱讀:301 作者:哎呀我的天吶 欄目:MySQL數(shù)據(jù)庫(kù)

double write 技術(shù)的引入就是為了提高數(shù)據(jù)寫(xiě)入的可靠性。當(dāng)寫(xiě)入部分?jǐn)?shù)據(jù)的時(shí)候,比如:512bytes。

為什么Oracle沒(méi)有解決這個(gè)問(wèn)題,而MySQL通過(guò)double write去解決這個(gè)事情呢。

 doublewrite 默認(rèn)存放在ibdata1中共享表空間里,默認(rèn)大小2M,寫(xiě)之前將臟頁(yè)寫(xiě)入到innodb buffer中的doublewrite buffer(2M)中,將2M的buffer數(shù)據(jù)直接寫(xiě)入到共享表空間的doublewrite段中,當(dāng)寫(xiě)共享表空間的doublewrite失敗了,沒(méi)有關(guān)系,因?yàn)榇藭r(shí)的數(shù)據(jù)文件ibd中的數(shù)據(jù)是干凈的,處于一致的狀態(tài),可以通過(guò)redo進(jìn)行恢復(fù),【先寫(xiě)共享表空間的double 再寫(xiě)數(shù)據(jù)文件ibd】,doublewrite是覆蓋寫(xiě),共享表空間只存2M給doublewrite用。Redo能恢復(fù)的頁(yè)一定是干凈的完整的一致的,因?yàn)閙ysql會(huì)有partial write所以引入doublewrite機(jī)制。

  double write buffer à double write(ibdata1) à ibd

MySQL double write                        

doublewrite 對(duì)性能影響大嗎

如果頁(yè)大小是 16k ,那么就有 128 個(gè)頁(yè) (1M) 需要寫(xiě),但是 128 個(gè)頁(yè)寫(xiě)入到共享表空間是 1 IO 完成,也就是說(shuō) doublewrite 寫(xiě)開(kāi)銷(xiāo)是 1+128 次。其中 128 次是寫(xiě)數(shù)據(jù)文件表空間。

 

doublewrite 寫(xiě)入是順序的,性能開(kāi)銷(xiāo)取決于寫(xiě)入量,通常 5%-25% 的性能影響。

當(dāng)系統(tǒng)負(fù)載非常高的情況下,性能開(kāi)銷(xiāo)減少 25%

 

對(duì)應(yīng)數(shù)據(jù)庫(kù)參數(shù)

Double write 技術(shù)對(duì)用戶(hù)來(lái)說(shuō)是透明的,我們只關(guān)注下面參數(shù)開(kāi)啟或關(guān)閉即可。

mysql> show variables like '%double%write%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| innodb_doublewrite | ON    |
+--------------------+-------+
1 row in set (0.00 sec)

什么情況下可以關(guān)閉 doublewrite 特性能

1、Fursion-io 原子寫(xiě),如果每次寫(xiě)16k就是16k,每次寫(xiě)都是16k不會(huì)出現(xiàn)部分寫(xiě)partial write寫(xiě)4k的情況。設(shè)備帶來(lái)的益處。

2、 特定的文件系統(tǒng),支持原子寫(xiě)。 b-tree file system





介紹double write之前我們有必要了解partial page write 問(wèn)題 : 
    InnoDB 的Page Size一般是16KB,其數(shù)據(jù)校驗(yàn)也是針對(duì)這16KB來(lái)計(jì)算的,將數(shù)據(jù)寫(xiě)入到磁盤(pán)是以Page為單位進(jìn)行操作的。而計(jì)算機(jī)硬件和操作系統(tǒng),在極端情況下(比如斷電)往往并不能保證這一操作的原子性,16K的數(shù)據(jù),寫(xiě)入4K 時(shí),發(fā)生了系統(tǒng)斷電/os crash ,只有一部分寫(xiě)是成功的,這種情況下就是 partial page write 問(wèn)題。
很多DBA 會(huì)想到系統(tǒng)恢復(fù)后,MySQL 可以根據(jù)redolog 進(jìn)行恢復(fù),而mysql在恢復(fù)的過(guò)程中是檢查page的checksum,checksum就是pgae的最后事務(wù)號(hào),發(fā)生partial page write 問(wèn)題時(shí),page已經(jīng)損壞,找不到該page中的事務(wù)號(hào),就無(wú)法恢復(fù)。

一 double write是什么?
    Double write 是InnoDB在 tablespace上的128個(gè)頁(yè)(2個(gè)區(qū))是2MB;
其原理:
    為了解決 partial page write 問(wèn)題 ,當(dāng)mysql將臟數(shù)據(jù)flush到data file的時(shí)候, 先使用memcopy 將臟數(shù)據(jù)復(fù)制到內(nèi)存中的double write buffer ,之后通過(guò)double write buffer再分2次,每次寫(xiě)入1MB到共享表空間,然后馬上調(diào)用fsync函數(shù),同步到磁盤(pán)上,避免緩沖帶來(lái)的問(wèn)題,在這個(gè)過(guò)程中,doublewrite是順序?qū)?,開(kāi)銷(xiāo)并不大,在完成doublewrite寫(xiě)入后,在將double write buffer寫(xiě)入各表空間文件,這時(shí)是離散寫(xiě)入。
如果發(fā)生了極端情況(斷電),InnoDB再次啟動(dòng)后,發(fā)現(xiàn)了一個(gè)Page數(shù)據(jù)已經(jīng)損壞,那么此時(shí)就可以從doublewrite buffer中進(jìn)行數(shù)據(jù)恢復(fù)了。
MySQL double write

二double write的缺點(diǎn)是什么?
     位于共享表空間上的double write buffer實(shí)際上也是一個(gè)文件,寫(xiě)DWB會(huì)導(dǎo)致系統(tǒng)有更多的fsync操作, 而硬盤(pán)的fsync性能, 所以它會(huì)降低mysql的整體性能. 但是并不會(huì)降低到原來(lái)的50%. 這主要是因?yàn)? 
1) double write 是一個(gè)連接的存儲(chǔ)空間, 所以硬盤(pán)在寫(xiě)數(shù)據(jù)的時(shí)候是順序?qū)? 而不是隨機(jī)寫(xiě), 這樣性能更高. 
2) 將數(shù)據(jù)從double write buffer寫(xiě)到真正的segment中的時(shí)候, 系統(tǒng)會(huì)自動(dòng)合并連接空間刷新的方式, 每次可以刷新多個(gè)pages; 三 double write在恢復(fù)的時(shí)候是如何工作的?
If there’s a partial page write to the doublewrite buffer itself, the original page will still be on disk in its real location.-
--如果是寫(xiě)doublewrite buffer本身失敗,那么這些數(shù)據(jù)不會(huì)被寫(xiě)到磁盤(pán),InnoDB此時(shí)會(huì)從磁盤(pán)載入原始的數(shù)據(jù),然后通過(guò)InnoDB的事務(wù)日志來(lái)計(jì)算出正確的數(shù)據(jù),重新 寫(xiě)入到doublewrite buffer.
When InnoDB recovers, it will use the original page instead of the corrupted copy in the doublewrite buffer. However, if the doublewrite buffer succeeds and the write to the page’s real location fails, InnoDB will use the copy in the doublewrite buffer during recovery. 
--如果 doublewrite buffer寫(xiě)成功的話,但是寫(xiě)磁盤(pán)失敗,InnoDB就不用通過(guò)事務(wù)日志來(lái)計(jì)算了,而是直接用buffer的數(shù)據(jù)再寫(xiě)一遍.
InnoDB knows when a page is corrupt because each page has a checksum at the end; the checksum is the last thing to be written, so if the page’s contents don’t match the checksum, the page is corrupt. Upon recovery, therefore, InnoDB just reads each page in the doublewrite buffer and verifies the checksums. If a page’s checksum is incorrect, it reads the page from its original location.
--在恢復(fù)的時(shí)候,InnoDB直接比較頁(yè)面的checksum,如果不對(duì)的話,就從硬盤(pán)載入原始數(shù)據(jù),再由事務(wù)日志 開(kāi)始推演出正確的數(shù)據(jù).所以InnoDB的恢復(fù)通常需要較長(zhǎng)的時(shí)間. 四 我們是否一定需要 double write ?
In some cases, the doublewrite buffer really isn’t necessary—for example, you might want to disable it on slaves. Also, some filesystems (such as ZFS) do the same thing themselves, so it is redundant for InnoDB to do it. You can disable the doublewrite buffer by setting InnoDB_doublewrite to 0.

五  如何使用 double write
InnoDB_doublewrite=1表示啟動(dòng)double write
show status like 'InnoDB_dblwr%'可以查詢(xún)double write的使用情況;
相關(guān)參數(shù)與狀態(tài)
Double write的使用情況:
show status like  "%InnoDB_dblwr%"; InnoDB_dblwr_pages_written 從bp flush 到 DBWB的個(gè)數(shù)
InnoDB_dblwr_writes            寫(xiě)文件的次數(shù)
每次寫(xiě)操作合并page的個(gè)數(shù)= InnoDB_dblwr_pages_written/InnoDB_dblwr_writes   

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI