Mysql原理(四) 數(shù)據(jù)與日志

WAL機(jī)制

? ???在Mysql中經(jīng)常會(huì)聽(tīng)到WAL機(jī)制(Write-Ahead-Logging),主要講了數(shù)據(jù)在操作的時(shí)候先進(jìn)行寫(xiě)日志怔鳖,然后再將數(shù)據(jù)寫(xiě)入磁盤(pán)的過(guò)程。之前提到過(guò)Mysql中的兩個(gè)重要的日志文件redo log和bin log颜武。
? ??? redo log:Mysql分配給redoLog固定大小區(qū)域記錄日志意狠,該日志采用循環(huán)寫(xiě)從頭寫(xiě)到尾然后在從頭,同時(shí)還有一個(gè)記錄擦除日志位置的標(biāo)記checkpoint地技。當(dāng)寫(xiě)入點(diǎn)和checkpoint在同一個(gè)位置袁翁,則停止寫(xiě)日志柴底。如果數(shù)據(jù)庫(kù)異常后婿脸,提交后的記錄不會(huì)丟失稱(chēng)為crash-safe
? ???bin log:稱(chēng)為歸檔日志粱胜,是追加寫(xiě)不會(huì)覆蓋之前的日志。所以可以根據(jù)binlog日志可以完成主從備份狐树、數(shù)據(jù)訂閱焙压、恢復(fù)數(shù)據(jù)等工作。
? ???之前也提到mysql執(zhí)行一條update語(yǔ)句遵從兩階段提交過(guò)程抑钟,整個(gè)流程如下
1.先通過(guò)引擎找到對(duì)應(yīng)的行數(shù)據(jù)
2.對(duì)行數(shù)據(jù)進(jìn)行修改并調(diào)用引擎接口修改這條數(shù)據(jù)
3.redo log記錄更新流程此時(shí)處于prepare狀態(tài)涯曲,告知mysql執(zhí)行器完成操作
4.執(zhí)行器生成binlog并寫(xiě)入磁盤(pán)
5.執(zhí)行器調(diào)用引擎提交事務(wù)接口,redo log狀態(tài)變?yōu)閏ommit狀態(tài)完成整個(gè)更新操作在塔。
Redo log進(jìn)行flush操作
? ???Mysql在記錄redo log的時(shí)候會(huì)先將數(shù)據(jù)寫(xiě)入到內(nèi)存中幻件,然后通過(guò)flush將內(nèi)存中的數(shù)據(jù)寫(xiě)入磁盤(pán)中。再次期間會(huì)產(chǎn)生臟數(shù)據(jù)頁(yè)導(dǎo)致內(nèi)存和磁盤(pán)的數(shù)據(jù)不一致蛔溃。這時(shí)候mysql就需要刷臟數(shù)據(jù)頁(yè)绰沥。
Mysql什么時(shí)候執(zhí)行flush操作?
1.當(dāng)記錄redo log的內(nèi)存滿了贺待,會(huì)停止寫(xiě)入redo log操作徽曲。
2.寫(xiě)入日志太多,發(fā)現(xiàn)分配的內(nèi)存不夠麸塞,這時(shí)候需要淘汰一部分?jǐn)?shù)據(jù)頁(yè)秃臣。
3.mysql空閑時(shí)會(huì)進(jìn)行flush操作
? ???在flush過(guò)程中如果存在讀入的數(shù)據(jù)頁(yè)沒(méi)有內(nèi)存的時(shí)候,需要到緩沖池中申請(qǐng)數(shù)據(jù)頁(yè)哪工。當(dāng)數(shù)據(jù)頁(yè)不足首先將最久不使用的數(shù)據(jù)從內(nèi)存中淘汰奥此,如果是臟數(shù)據(jù)頁(yè)還得先進(jìn)行刷盤(pán)才能復(fù)用弧哎。可是在刷臟頁(yè)過(guò)程中得院,若淘汰的數(shù)據(jù)頁(yè)太多或者日志寫(xiě)滿會(huì)導(dǎo)致mysql性能降低傻铣。所以InnoDB會(huì)有刷臟頁(yè)的控制策略
InnoDB刷盤(pán)影響因素:臟頁(yè)的比重、redo log寫(xiě)盤(pán)速度
? ???InnoDB_max_dirty_pages_pct臟頁(yè)比重上線默認(rèn)為75%祥绞,合理的設(shè)置innoDb_io_capacity的值不要超過(guò)上限非洲。
? ???同時(shí)在刷盤(pán)的過(guò)程中,mysql會(huì)將旁邊的數(shù)據(jù)頁(yè)也會(huì)刷入蜕径。InnoDB通過(guò)innodb_flush_neighbors參數(shù)用來(lái)控制這個(gè)行為两踏。1表示會(huì)刷入相鄰的數(shù)據(jù)2.表示只刷自己。如果磁盤(pán)寫(xiě)性能高最好設(shè)置為0兜喻,減少sql響應(yīng)時(shí)間梦染。
? ???如果mysql在執(zhí)行操作過(guò)程中出現(xiàn)抖動(dòng)可能由于mysql在flush操作。
? ???Mysql在執(zhí)行Binlog和redoLog過(guò)程有時(shí)什么樣子呢朴皆?
? ???binlog寫(xiě)入機(jī)制
? ???執(zhí)行事務(wù)過(guò)程帕识,先將日志寫(xiě)入binlog cache,事務(wù)提交時(shí)再將cache寫(xiě)入到binlog中遂铡。對(duì)于cache系統(tǒng)會(huì)分配一片內(nèi)存肮疗,每個(gè)線程一個(gè),參數(shù)binlog_cache_size用于控制單個(gè)線程內(nèi)binlog cache所占內(nèi)存的大小扒接。超過(guò)這個(gè)參數(shù)則暫存在磁盤(pán)中伪货。
事務(wù)提交時(shí),執(zhí)行器將binlog cache完整事務(wù)寫(xiě)入binlog中钾怔,并清空binlog cache碱呼。
整個(gè)寫(xiě)入過(guò)程分為兩步 write和fsync
write:指把日志寫(xiě)入到文件系統(tǒng)page cache,并沒(méi)有寫(xiě)入磁盤(pán)中宗侦,速度快
fsync:將數(shù)據(jù)持久化到磁盤(pán)愚臀,該過(guò)程占用磁盤(pán)IOPS。
sync_binlog參數(shù)
等于0:表示每次提交事務(wù)只write不fsync
等于1:表示每次提交事務(wù)都執(zhí)行fsync
等于n:表示事務(wù)在write后矾利,會(huì)累積N個(gè)事務(wù)后才fsync姑裂。
? ???為了提升性能,實(shí)際場(chǎng)景考慮丟失日志量的可控性會(huì)設(shè)置到100-1000之間的值梦皮。風(fēng)險(xiǎn):主機(jī)發(fā)生異常重啟炭分,會(huì)丟失N個(gè)事務(wù)binlog日志。
? ???redoLog寫(xiě)入機(jī)制
? ???首先確定redo log在寫(xiě)入的時(shí)經(jīng)過(guò)redo log buffer剑肯、FSPage cache捧毛、hard disk
redo log buffer:物理上是Mysql進(jìn)程內(nèi)存
FSPage cache:寫(xiě)入磁盤(pán)但沒(méi)有持久化,物理上是在文件系統(tǒng)page cache中hard disk 持久化到磁盤(pán)
? ??? 為了控制redo log寫(xiě)入策略,innodb_flush_log_at_trx_commit參數(shù)
等于0呀忧,表示事務(wù)提交只將redo log留在redo log buffer
等于1师痕,表示每次事務(wù)提交都將redo log持久化到磁盤(pán)中
等于2,每次事務(wù)提交只把redo log寫(xiě)入page cache中而账。
? ???InnoDB后臺(tái)線程胰坟,每秒把redo logbuffer中日志,調(diào)用write寫(xiě)入到文件系統(tǒng)page cache泞辐,然后調(diào)用fsync持久化到磁盤(pán)笔横。
? ??? 所以在事務(wù)執(zhí)行過(guò)程中redo log直接寫(xiě)入redo log buffer,然后隔一秒調(diào)用write寫(xiě)入到page cache中咐吼,最后持久化到磁盤(pán)中吹缔。所以說(shuō)沒(méi)有提交事務(wù)的redo log也有可能持久化到磁盤(pán)中。
? ???還有場(chǎng)景會(huì)將redo log buffer寫(xiě)入磁盤(pán)
1.redo log buffer占用空間達(dá)到innoDB_log_buffer_size一半锯茄,后臺(tái)線程主動(dòng)寫(xiě)入
2.并行事務(wù)提交時(shí)順帶將這個(gè)redo log持久化到磁盤(pán)中厢塘。
? ???innoDB_flush_log_at_trx_commit設(shè)置為1,事務(wù)B將redo log buffer里日志全部持久化到磁盤(pán)肌幽。會(huì)帶上事務(wù)A里的日志晚碾。
? ???雙1配置:sync_binlog和innoDb_flush_log_at_trx_commit都設(shè)置為1,一個(gè)事務(wù)完整提交需要兩次刷盤(pán)喂急,一次redo log(prepare)一次binlog格嘁。
? ???但是Mysql測(cè)試TPS每秒2萬(wàn),刷盤(pán)得四萬(wàn)次煮岁?
? ???日志邏輯序列號(hào)(LSN)用來(lái)對(duì)應(yīng)redo log寫(xiě)入點(diǎn)讥蔽。LSN記錄InnoDB的數(shù)據(jù)頁(yè)涣易,保證數(shù)據(jù)頁(yè)不會(huì)被多次執(zhí)行重復(fù)redo log画机。
redo log組提交:
? ???比如有三個(gè)事務(wù),先到達(dá)的會(huì)選為組leader新症。當(dāng)組成員達(dá)到3個(gè)步氏,事務(wù)1會(huì)帶著3個(gè)事務(wù)一起持久化,事務(wù)2和3直接返回徒爹。
? ???所以一次組提交過(guò)程組成員越多荚醒,fsync越晚調(diào)用,節(jié)約IOPS效果越好隆嗅。
mysql有兩個(gè)參數(shù)
binlog_group_commit_sync_delay:表示延遲多久調(diào)用fsync
binlog_grouo_commit_syn_no_delay_count:表示事務(wù)累積多少次調(diào)用fsync
這兩個(gè)條件只要滿足其一就會(huì)調(diào)用fsync界阁。
? ???mysql出現(xiàn)性能瓶頸,瓶頸為IO上胖喳,可以有哪些方式提升泡躯?
1.設(shè)置binlog_group_commit_sync_delay和binlog_grouo_commit_syn_no_delay_count減少binlog寫(xiě)盤(pán)次數(shù),增加語(yǔ)句響應(yīng)時(shí)間,不會(huì)丟數(shù)據(jù)
2.sync_binlog設(shè)置大于1(常見(jiàn)為100-1000)但有風(fēng)險(xiǎn)主機(jī)異常會(huì)丟失binlog日志较剃。
3.innoDb_flush_log_at_trx_commit設(shè)置2咕别,主機(jī)掉電會(huì)丟數(shù)據(jù) innoDb_flush_log_at_trx_commit為0時(shí),如果mysql本身異常重啟也會(huì)丟數(shù)據(jù)写穴。
最終crash-safe保證
? ???客戶端收到事務(wù)成功惰拱,事務(wù)一定持久化了
? ???客戶端收到事務(wù)失敗,則一定失敗
? ???客戶端收到異常啊送,需要重連數(shù)據(jù)庫(kù)連接偿短,數(shù)據(jù)只要保證內(nèi)部(數(shù)據(jù)和日志、主庫(kù)和備庫(kù)一致)就可以

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末馋没,一起剝皮案震驚了整個(gè)濱河市翔冀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌披泪,老刑警劉巖纤子,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異款票,居然都是意外死亡控硼,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)艾少,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)卡乾,“玉大人,你說(shuō)我怎么就攤上這事缚够♂7粒” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵谍椅,是天一觀的道長(zhǎng)误堡。 經(jīng)常有香客問(wèn)我,道長(zhǎng)雏吭,這世上最難降的妖魔是什么锁施? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮杖们,結(jié)果婚禮上悉抵,老公的妹妹穿的比我還像新娘。我一直安慰自己摘完,他們只是感情好姥饰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著孝治,像睡著了一般列粪。 火紅的嫁衣襯著肌膚如雪栅螟。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天篱竭,我揣著相機(jī)與錄音力图,去河邊找鬼。 笑死掺逼,一個(gè)胖子當(dāng)著我的面吹牛吃媒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吕喘,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼赘那,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了氯质?” 一聲冷哼從身側(cè)響起募舟,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎闻察,沒(méi)想到半個(gè)月后拱礁,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辕漂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年呢灶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钉嘹。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鸯乃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跋涣,到底是詐尸還是另有隱情缨睡,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布陈辱,位于F島的核電站奖年,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏性置。R本人自食惡果不足惜拾并,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一揍堰、第九天 我趴在偏房一處隱蔽的房頂上張望鹏浅。 院中可真熱鬧,春花似錦屏歹、人聲如沸隐砸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)季希。三九已至褪那,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間式塌,已是汗流浹背博敬。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留峰尝,地道東北人偏窝。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像武学,于是被迫代替她去往敵國(guó)和親祭往。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容