MySQL的刷脏页策略
1. MySQL的日志
這篇文章主要以InnoDB引擎為例。
在MySQL的InnoDB當(dāng)中,有兩個(gè)重要日志模塊,一個(gè)是redo log(重做日志) 一個(gè)是binlog(歸檔日志) 。
redo log的好處
1.當(dāng)我們修改一條數(shù)據(jù)時(shí),如果數(shù)據(jù)在內(nèi)存中,我們是先會(huì)去改內(nèi)存的,而不是先去改磁盤。假如數(shù)據(jù)都在內(nèi)存中,這時(shí)候斷電了怎么辦,服務(wù)器宕機(jī)怎么辦,這個(gè)時(shí)候就需要我們的redo log了。
2.redo只是記錄了對(duì)數(shù)據(jù)的修改,數(shù)據(jù)會(huì)比一頁(yè)數(shù)據(jù)小得多。大大減少了IO頻率。并且想比于更新操作,更新過(guò)程是在磁盤上隨機(jī)IO,費(fèi)時(shí)。 而寫redo log 是在磁盤上順序IO。效率要高。
在每一條數(shù)據(jù)更新時(shí),MySQL會(huì)先寫redo log日志,在去寫binlog 日志。在寫這兩個(gè)日志過(guò)程中會(huì)涉及到兩階段提交。他可以保證兩個(gè)日志邏輯上的一致性。所以即使因?yàn)橥k?#xff0c;宕機(jī)等原因,MySQL也可以通過(guò)redo log將數(shù)據(jù)進(jìn)行恢復(fù)。
兩者區(qū)別
redo log 是物理日志,記錄的是“在某個(gè)數(shù)據(jù)頁(yè)上做了什么修改”;binlog 是邏輯日志,記錄的是這個(gè)語(yǔ)句的原始邏輯,比如“給 ID=10 這一行的 c 字段加 10 ”。
redo log 是循環(huán)寫的,空間固定會(huì)用完; binlog 是可以追加寫入的?!白芳訉憽笔侵?binlog 文件寫到一定大小后會(huì)切換到下一個(gè),并不會(huì)覆蓋以前的日志。
有了redlog,為什么還要有binglog
一個(gè)原因是,redolog只有InnoDB有,別的引擎沒(méi)有。另一個(gè)原因是,redolog是循環(huán)寫的,不持久保存,binlog的“歸檔”這個(gè)功能,redolog是不具備的。
redo log 是循環(huán)寫的,固定空間用完會(huì)怎么辦?這個(gè)也就是下面也會(huì)帶著大家去了解的MySQL的刷臟頁(yè)策略。
2.緩沖池(buffer pool)
buffer pool 是數(shù)據(jù)庫(kù)的一個(gè)內(nèi)存組件,里面緩存了磁盤上的真實(shí)數(shù)據(jù),Java系統(tǒng)對(duì)數(shù)據(jù)庫(kù)的增刪改操作,主要是這個(gè)內(nèi)存數(shù)據(jù)結(jié)構(gòu)中的緩存數(shù)據(jù)執(zhí)行的。
MySQL的InnoDB能使用內(nèi)存會(huì)盡量的使用內(nèi)存。這樣是為了加速數(shù)據(jù)訪問(wèn),把查詢數(shù)據(jù)放在MySQL作為一個(gè)存儲(chǔ)系統(tǒng),使用緩沖池(buffer pool)機(jī)制,以避免每次查詢數(shù)據(jù)都進(jìn)行磁盤IO。
它的默認(rèn)大小是128M。在實(shí)際的生產(chǎn)環(huán)境中可以通過(guò)參數(shù)innodb_buffer_pool_size對(duì) buffer pool進(jìn)行調(diào)整
關(guān)于緩沖池大家可以參考這篇文章去深入了解:緩沖池(buffer pool),這次徹底懂了!!!
3.什么時(shí)候會(huì)刷臟頁(yè)
什么是臟頁(yè)
當(dāng)內(nèi)存數(shù)據(jù)頁(yè)跟磁盤數(shù)據(jù)頁(yè)內(nèi)容不一致的時(shí)候,我們稱這個(gè)內(nèi)存頁(yè)為“臟頁(yè)”。
什么是干凈頁(yè)
內(nèi)存數(shù)據(jù)寫入到磁盤后,內(nèi)存和磁盤上的數(shù)據(jù)頁(yè)的內(nèi)容就一致了,稱為“干凈頁(yè)”
MySQL什么時(shí)候會(huì)刷臟頁(yè)
(1)redo log滿了
因?yàn)槲覀價(jià)edo log日志是有固定空間的,如果它滿了的話,就會(huì)進(jìn)行刷臟頁(yè) (flush 臟頁(yè))。MySQL會(huì)先把內(nèi)存數(shù)據(jù)更新到磁盤上,并把redo log進(jìn)行清空。這種情況是 InnoDB所有更新會(huì)為0,因?yàn)槌霈F(xiàn)這種情況的時(shí)候,整個(gè)系統(tǒng)就不能再接受更新了,所有的更新都必須堵住。
(2)內(nèi)存滿了
因?yàn)槲覀僊ySQL的緩沖池是有固定內(nèi)存大小的,當(dāng)我們緩沖池滿了的時(shí)候,這時(shí)候也會(huì)進(jìn)行刷臟頁(yè)。而這時(shí)在內(nèi)存中的數(shù)據(jù)會(huì)有三種類型數(shù)據(jù)頁(yè)
第一種是,還沒(méi)有使用的; 第二種是,使用了并且是干凈頁(yè);第三種是,使用了并且是臟頁(yè)。
而當(dāng)要讀入的數(shù)據(jù)頁(yè)沒(méi)有在內(nèi)存的時(shí)候,就必須到緩沖池中申請(qǐng)一個(gè)數(shù)據(jù)頁(yè)。這時(shí)候只能把最久不使用的數(shù)據(jù)頁(yè)從內(nèi)存中淘汰掉:如果要淘汰的是一個(gè)干凈頁(yè),就直接釋放出來(lái)復(fù)用;但如果是臟頁(yè)呢,就必須將臟頁(yè)先刷到磁盤,變成干凈頁(yè)后才能復(fù)用。
(3)mysql空閑的時(shí)候
這個(gè)時(shí)候就是我們MySQL比較空閑,沒(méi)有請(qǐng)求的時(shí)候。這個(gè)時(shí)候redo log會(huì)flush 臟頁(yè),會(huì)把內(nèi)存中的臟頁(yè)更新到我們的磁盤里。
(4)mysql正常關(guān)閉的時(shí)候
因?yàn)槲覀僊ySQL正常關(guān)閉,肯定是要把內(nèi)存臟頁(yè)更新到磁盤中的。
會(huì)影響性能的刷臟頁(yè)操作
1.比如我們一個(gè)查詢要淘汰的臟頁(yè)個(gè)數(shù)太多,如果MySQL刷臟頁(yè)速度很慢,則會(huì)導(dǎo)致查詢的響應(yīng)時(shí)間明顯變長(zhǎng);
2.redo log 寫滿了,導(dǎo)致這個(gè)系統(tǒng)更新為0;
4.刷臟頁(yè)控制策略
1.設(shè)置系統(tǒng)刷臟頁(yè)的速度和能力
show global variables like ‘innodb_io_capacity’; 查看當(dāng)前系統(tǒng)刷臟頁(yè)的能力
set global innodb_io_capacity=200; 進(jìn)行設(shè)置刷臟頁(yè)速度
2.設(shè)置臟頁(yè)比例
如果我們系統(tǒng)一直全力去刷盤的話,那其他業(yè)務(wù)必定會(huì)受到影響。所以我們需求設(shè)置臟頁(yè)比例,去執(zhí)行刷盤。臟頁(yè)比例默認(rèn)75%,一定不要讓其接近75%**
查看當(dāng)前臟頁(yè)比例
參數(shù)innodb_max_dirty_pages_pct是臟頁(yè)比例上限,默認(rèn)值是75%
select VARIABLE_VALUE into @a from performance_schema.global_status where VARIABLE_NAME = ‘Innodb_buffer_pool_pages_dirty’; select VARIABLE_VALUE into @b from performance_schema.global_status where VARIABLE_NAME = ‘Innodb_buffer_pool_pages_total’; select @a/@b;
3. 刷臟頁(yè)速度 nnodb_io_capacity定義的能力乘以R%(redolog)來(lái)控制刷臟頁(yè)的速度
InnoDB每次寫入的日志都有一個(gè)序號(hào),當(dāng)前寫入的序號(hào)跟checkpoint對(duì)應(yīng)的序號(hào)之間的差值,InnoDB會(huì)將這兩個(gè)值經(jīng)過(guò)一定的計(jì)算得出一個(gè)數(shù),這個(gè)結(jié)果數(shù)就是用來(lái)控制刷臟頁(yè)的速度。
4. innodb_flush_neighbors=0(不開(kāi)啟臟頁(yè)相鄰淘汰) (對(duì)于機(jī)械硬盤順序讀寫會(huì)有提升,ssd無(wú)提升。iops普通機(jī)械硬盤只有幾百,ssd有上千,可以不開(kāi)啟)
在MySQL 8.0中,innodb_flush_neighbors參數(shù)的默認(rèn)值已經(jīng)是0了。
總結(jié)
以上是生活随笔為你收集整理的MySQL的刷脏页策略的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 推荐五款好用的项目管理系统
- 下一篇: SQL存储过程来调用webservice