国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

MySQL數據庫丟失數據的場(chǎng)景分析

發(fā)布時(shí)間:2021-09-27 17:43 來(lái)源:億速云 閱讀:0 作者:chen 欄目: Mysql 歡迎投稿:712375056

本篇內容主要講解“數據丟失數據的場(chǎng)景分析”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強。下面就讓小編來(lái)帶大家學(xué)習“MySQL數據庫丟失數據的場(chǎng)景分析”吧!

MySQL數據庫丟失數據場(chǎng)景分析

1.引擎層數據丟失場(chǎng)景

1.1.InnoDB丟失數據場(chǎng)景分析

InnoDB作為MySQL支持事務(wù)的存儲引擎,同Oracle類(lèi)似,事務(wù)提交時(shí)需要寫(xiě)redo、undo log。 InnoDB采用預寫(xiě)日志(Write Ahead Log)策略,數據頁(yè)的變更會(huì )首先在內存中完成,同時(shí)將事務(wù)操作順序記錄到redo log中。完成上述的操作后表示該事務(wù)已經(jīng)完成,可以返回給應用已提交的信息。 但此時(shí)實(shí)際被更改的數據頁(yè)還保存在內存中(稱(chēng)為臟頁(yè)),并沒(méi)有flush到磁盤(pán)上即沒(méi)有落地。刷盤(pán)操作一般會(huì )在達到一定條件后,觸發(fā)checkpoint機制,此時(shí)會(huì )將內存中的臟頁(yè)合并寫(xiě)入到磁盤(pán)里,完成數據同步。刷盤(pán)策略由innodb_flush_log_at_trx_commit參數控制的策略。

    注:這里應為redo log 而非 binlog。

參數innodb_flush_log_at_trx_commit:

     =0 :每秒 write os cache & flush disk

     =1 :每次commit都 write os cache & flush disk

     =2 :每次commit都 write os cache,然后根據innodb_flush_log_at_timeout參數(默認為1s) flush disk

    innodb_flush_log_at_trx_commit=1最為安全,因為每次commit都保證redo log寫(xiě)入了disk。但是這種方式性能對DML性能來(lái)說(shuō)比較低,在我們的測試中發(fā)現,如果設置為2,DML性能要比設置為1高10倍左右(所以在短信平臺出現寫(xiě)入問(wèn)題時(shí),已將該參數設置為2)。

innodb_flush_log_at_trx_commit為0或2的區別主要體現在在mysql service crash或system crash時(shí)丟失事務(wù)的類(lèi)型:

1)當mysql service crash時(shí),設置為0就會(huì )丟失1秒內的所有已提交及未提交的事務(wù),且無(wú)法回滾(因為redo log還記錄在log buffer中,沒(méi)有落盤(pán)到redo log)。而設置為2時(shí),每次提交都會(huì )寫(xiě)入到os cache中,即使service crash掉,也只會(huì )丟失1秒內所有未提交的事務(wù),而已提交的事務(wù)已經(jīng)寫(xiě)入redo log中,可以回滾。

2)當system crash時(shí),與上述類(lèi)似。

   因此,業(yè)內的共識是在一些DML操作頻繁的場(chǎng)景下,參數innodb_flush_log_at_trx_commit設置為2。

雖然這樣就存在丟數據的風(fēng)險:當出現mysql service crash時(shí),重啟后InnoDB會(huì )進(jìn)行crash recovery,則會(huì )丟失innodb_flush_log_at_timeout秒內的已提交的數據。未提交的數據則可由應用中的事務(wù)補償機制處理。但是IO性能可以提高至少10倍。  

PS:當開(kāi)啟了內部XA事務(wù)(默認開(kāi)啟),且開(kāi)啟binlog,情況稍有不一樣。見(jiàn)下文。

1.2.MyISAM丟失數據場(chǎng)景分析

    MyISAM存儲引擎在我們的生產(chǎn)環(huán)境中基本沒(méi)有使用。而且我們線(xiàn)上的5.6版本已將系統的數據字典表元數據表等系統表的默認存儲引擎修改為InnoDB。

    由于MyISAM不支持事務(wù),且沒(méi)有data cache,所有DML操作只寫(xiě)到OS cache中,flush disk操作均由OS來(lái)完成,因此如果宕機,這部分數據肯定會(huì )丟失。

2.主從復制導致數據不一致的場(chǎng)景

    MySQL主從復制原理:MySQL主庫在事務(wù)提交時(shí)寫(xiě)binlog,并通過(guò)sync_binlog參數來(lái)控制binlog刷新到磁盤(pán)“落地”。從庫中有兩個(gè)線(xiàn)程: IO線(xiàn)程負責從主庫讀取binlog,并記錄到本地的relay log中;SQL線(xiàn)程再將relay log中的記錄應用到從庫。如下圖所示:

        

2.1.binlog刷新機制

    master寫(xiě)binlog與innodb引擎寫(xiě)redo類(lèi)似,由參數sync_binlog控制:

     = 0 :表示MySQL不控制binlog的刷新,由文件系統控制binlog cache的刷盤(pán)操作

     = N :表示每sync_binlog在N次事務(wù)提交后,MySQL調用文件系統的flush操作將binlog cache中的內容刷盤(pán)

sync_binlog=1時(shí)最安全,即表示每次事務(wù)提交,MySQL都會(huì )把binlog cache中的內容flush disk。這樣在掉電等情況下,系統只有可能丟失1個(gè)事務(wù)的數據。但是sync_binlog為1時(shí),系統的IO消耗非常大。

但是N的值也不易過(guò)大,否則在系統掉電時(shí)會(huì )丟失較多的事務(wù)。當前我們生產(chǎn)系統設置為100.

2.2.內部XA事務(wù)原理

    MySQL的存儲引擎與MySQL服務(wù)層之間,或者存儲引擎與存儲引擎之間的分布式事務(wù),稱(chēng)之為MySQL內部XA事務(wù)。最為常見(jiàn)的內部XA事務(wù)存在與binlog與InnoDB存儲引擎之間。在事務(wù)提交時(shí),先寫(xiě)二進(jìn)制日志,再寫(xiě)InnoDB存儲引擎的redo log。對于這個(gè)操作要求必須是原子的,即需要保證兩者同時(shí)寫(xiě)入。內部XA事務(wù)機制就是保證兩者的同時(shí)寫(xiě)入。

XA事務(wù)的大致流程:

1)事務(wù)提交后,InnoDB存儲引擎會(huì )先做一個(gè)PREPARE操作,將事務(wù)的XID寫(xiě)入到redo log中

2)寫(xiě)binlog

3)將該事務(wù)的commit信息寫(xiě)到redo log中
        

     如果在步驟1和步驟2失敗的情況下,整個(gè)事務(wù)會(huì )回滾,如果在步驟3失敗的情況下,MySQL數據庫在重啟后會(huì )先檢查PREPARE的XID事務(wù)是否已經(jīng)提交,若沒(méi)有,則在存儲引擎層再進(jìn)行一次提交操作。這樣就保證了redo與binlog的一致性,防止丟失事務(wù)。

2.3.主庫寫(xiě)redo log、binlog不實(shí)時(shí)造成的數據不一致

    上面我們介紹了MySQL的內部XA事務(wù)流程,但是這個(gè)流程并不是天衣無(wú)縫的,redo的ib_logfile與binlog日志如果被設置非實(shí)時(shí)flush,就有可能出現以下數據不一致的情況:

1)Redo log的trx_prepare未寫(xiě)入,但binlog已寫(xiě)入,則crash recovery后從庫數據比主庫多。

2)Redo log的trx_prepare與commit都寫(xiě)入了,但binlog未寫(xiě)入,則crash recovery后從庫數據量比主庫少。

從目前來(lái)看,只能犧牲性能去換取數據的安全性,必須要設置redo log和binlog為實(shí)時(shí)刷盤(pán),如果對性能要求很高,則考慮使用SSD來(lái)替代機械盤(pán)。

2.4.從庫寫(xiě)redo log、binlog不實(shí)時(shí)造成的數據不一致

    主庫正常,但是從庫出現異常情況宕機,如果數據丟失,從庫的SQL線(xiàn)程還會(huì )重新應用嗎?這個(gè)我們需要先了解SQL線(xiàn)程的機制。

    從庫讀取主庫的binlog日志后,需要落地3個(gè)文件:

    relay log:即IO Thread讀取過(guò)來(lái)的主庫binlog,內容格式與主庫的binlog一致

    relay log info:記錄SQL Thread應用的relay log的位置、文件號等信息

    master info:記錄IO Thread讀取主庫的binlog的位置、文件號、延遲等信息

    因此如果當這3個(gè)文件如果不及時(shí)落地,則system crash后會(huì )導致數據的不一致。

在MySQL 5.6.2之前,從庫記錄的主庫信息以及從庫應用binlog的信息存放在文件中,即master.info與relay-log.info。在5.6.2版本之后,允許記錄到table中,參數設置如下:

master-info-repository  = TABLE  relay-log-info-repository = TABLE  對應的表分別為mysql.slave_master_info與mysql.slave_relay_log_info,且這兩個(gè)表均為innodb引擎表。

master info與relay info還有3個(gè)參數控制刷新:

1)sync_relay_log:默認為10000,即每10000次sync_relay_log事件會(huì )刷新到磁盤(pán)。為0則表示不刷新,交由OS的cache控制。

2)sync_master_info:若master-info-repository為FILE,當設置為0時(shí),則每次sync_master_info事件都會(huì )刷新到磁盤(pán),默認為10000次刷新到磁盤(pán);若master-info-repository為T(mén)ABLE,當設置為0時(shí),則表不做任何更新,設置為1,則每次事件會(huì )更新表。默認為10000。

3)sync_relay_log_info:若relay_log_info_repository為FILE,當設置為0時(shí),交由OS刷新磁盤(pán),默認為10000次刷新到磁盤(pán);若relay_log_info_repository為T(mén)ABLE,則無(wú)論為任何值,每次evnet都會(huì )更新表。

如果參數設置如下:

sync_relay_log = 1 

sync_master_info = 1  sync_relay_log_info = 1  master-info-repository  = TABLE  relay-log-info-repository = TABLE 

將導致調用fsync()/fdatasync()隨著(zhù)master的事務(wù)的增加而增加,且若slave的binlog和redo也實(shí)時(shí)刷新的話(huà),會(huì )帶來(lái)很?chē)乐氐腎O性能瓶頸。

2.5.主庫宕機后無(wú)法及時(shí)恢復造成的數據不一致

當主庫出現故障后,binlog未及時(shí)拉到從庫中,或者各個(gè)從庫收到的binlog不一致(多數是由于網(wǎng)絡(luò )原因)。且主庫無(wú)法在第一時(shí)間恢復:

    1)如果主庫不切換,則應用只能讀寫(xiě)主庫。如果有讀寫(xiě)分離的場(chǎng)景則會(huì )影響應用(讀寫(xiě)分離場(chǎng)景中從庫會(huì )從)。

    2)如果將某一從庫提升為新的主庫(如MHA),那么原主庫未來(lái)得及傳到從庫的binlog數據則會(huì )丟失,并且還涉及到下面2個(gè)問(wèn)題:

     a)各個(gè)從庫之間接收到的binlog不一致,如果強制拉起一個(gè)從庫做新主庫,則從庫之間數據會(huì )不一致。

b)原主庫恢復正常后,由于新的主庫日志丟棄了部分原主庫的binlog日志,那么會(huì )多出來(lái)故障時(shí)期的這部分binlog。

對于上面出現的問(wèn)題,業(yè)內已經(jīng)有較成熟的方法來(lái)解決:

2.5.1確保binlog全部傳到從庫

   方案一:使用semisync replication(半同步復制)插件。半同步復制的特點(diǎn)是從庫中有一臺提交后,主庫才能提交事務(wù)。優(yōu)點(diǎn)是保證了主、從庫的數據一致性;缺點(diǎn)是對性能影響很大,依賴(lài)網(wǎng)絡(luò ),適合tps壓力小的場(chǎng)景。

   方案二:雙寫(xiě)binlog,通過(guò)DBDR OS層的文件系統復制到備機,或者使用共享盤(pán)保存binlog日志。優(yōu)點(diǎn)和方案一類(lèi)似,但此方案缺點(diǎn)較明顯:

1)DBDR需要部署自己的服務(wù)

2)DBDR腦裂嚴重。在發(fā)生災難場(chǎng)景時(shí),往往不能正確切換。

3)需要建立heartbeat機制。保證被監控機的存活。

   方案三:架構層面調整,引入消息隊列做異步消息處理。比如保證數據庫寫(xiě)成功后,再異步隊列的方式寫(xiě)一份,部分業(yè)務(wù)可以借助設計和數據流解決。

2.5.2保證數據最小化丟失

   上面的方案設計及架構比較復雜,如果能容忍數據的丟失,可以考慮使用MHA。

當master宕機后,MHA可以指定一臺或者選延遲最低或者binlog pos最新的一臺從庫,并將其提升為主庫。

MHA在切換master后,原master可以修復后以新master的slave角色重新加入集群。從而達到高可用。

3.總結

     通過(guò)上面的總結分析,MySQL丟數據的場(chǎng)景眾多,主要還是涉及到引擎層數據丟失場(chǎng)景、主從的數據不一致場(chǎng)景等。     

     根據分布式領(lǐng)域的CAP理論(Consistency一致性、Availability高可用性、Partition tolerance分區耐受性),在任何的分布式系統只能同時(shí)滿(mǎn)足2點(diǎn),沒(méi)辦法三者兼顧。MySQL的主從環(huán)境滿(mǎn)足Availability,且在半同步場(chǎng)景中數據可以做到數據強一致性,可以滿(mǎn)足Consistency。但是不能完全滿(mǎn)足Partition tolerance。

因此現在業(yè)內對于事務(wù)(數據)丟失的處理有很多解決方案,如事務(wù)補償機制、半同步復制、雙寫(xiě)機制、異步消息隊列等等。甚至,還可以針對業(yè)務(wù)對CAP中哪兩者更有需求來(lái)選擇相應的數據產(chǎn)品,如需要分區耐受性和高可用兼顧時(shí),可以使用Cassandra等列式存儲。都可以達到業(yè)務(wù)相應的數據一致性需求。

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

内射少妇一区27P| 国产精品久久久久9999吃药| 无码尹人久久相蕉无码| 国产成人亚洲精品无码MP4| 无遮挡啪啪摇乳动态图| 中文字幕乱码熟妇五十中出|