mysql优化原理_【MySQL】我必须得告诉你们的MySQL优化原理3(下)INNODB配置
INNODB:使用最廣的存儲(chǔ)引擎
innodb-buffer-pool-size
若是大部分是InnoDB表,那么InnoDB緩沖池或許比其余任何東西都更須要內(nèi)存,InnoDB緩沖池緩沖的數(shù)據(jù):索引、行數(shù)據(jù)、自適應(yīng)哈希索引、插入緩沖、鎖以及其余內(nèi)部數(shù)據(jù)結(jié)構(gòu)。InnoDB還使用緩沖池來幫助延遲寫入,這樣就能夠合并多個(gè)寫入操做,而后一塊兒順序?qū)懭?#xff0c;提高性能。總之,InnoDB嚴(yán)重依賴緩沖池,必須為其分配足夠的內(nèi)存。html
固然,若是數(shù)據(jù)量不大且不會(huì)快速增加,就沒有必要為緩沖池分配過多的內(nèi)存,把緩沖池配置得比須要緩存的表和索引還要大不少,實(shí)際上也沒有什么意義。很大的緩沖池也會(huì)帶來一些挑戰(zhàn),例如,預(yù)熱和關(guān)閉都會(huì)花費(fèi)很長(zhǎng)的時(shí)間。若是有不少臟頁在緩沖池里,InnoDB關(guān)閉時(shí)可能會(huì)花很長(zhǎng)時(shí)間來把臟頁寫回?cái)?shù)據(jù)文件。雖然能夠快速關(guān)閉,可是在啟動(dòng)時(shí)須要作更多的恢復(fù)工做,也就是說咱們沒法同時(shí)加速關(guān)閉和重啟兩個(gè)操做。當(dāng)有一個(gè)很大的緩沖池,重啟服務(wù)須要花費(fèi)很長(zhǎng)時(shí)間(幾小時(shí)或者幾天)來預(yù)熱,尤為是磁盤很慢的時(shí)候,若是想加快預(yù)熱時(shí)間,能夠在重啟后馬上進(jìn)行全表掃描或者索引掃描,把索引載入緩沖池。mysql
能夠看到示例的配置文件中把這個(gè)值配置為12G,這不是一個(gè)標(biāo)準(zhǔn)配置,須要根據(jù)具體的硬件來估算。那如何估算?前面的小節(jié),咱們說到,MySQL中最重要的緩存有5種,能夠簡(jiǎn)單的使用下面的公式計(jì)算:sql
InnoDB緩沖池 = 服務(wù)器總內(nèi)存 - OS預(yù)留 - 服務(wù)器上的其余應(yīng)用占用內(nèi)存 - MySQL自身須要的內(nèi)存 - InnoDB日志文件占用內(nèi)存 - 其它內(nèi)存(MyISAM鍵緩存、查詢緩存等)windows
具體來看,至少須要為OS保留1~2G內(nèi)存,若是機(jī)器內(nèi)存大的話能夠預(yù)留多一些,建議2GB和總內(nèi)存的5%為基準(zhǔn),以較大者為準(zhǔn),若是機(jī)器上還運(yùn)行著一些內(nèi)存密集型任務(wù),好比,備份任務(wù),那么能夠?yàn)镺S再預(yù)留多一些內(nèi)存。不要為OS緩存增長(zhǎng)任何內(nèi)存,由于OS一般會(huì)利用全部剩下的內(nèi)存來作文件緩存。緩存
通常來講,運(yùn)行MySQL的服務(wù)器不多會(huì)運(yùn)行其余應(yīng)用程序,但若是有的話,請(qǐng)為這些應(yīng)用程序預(yù)留足夠多的內(nèi)存。安全
MySQL自身運(yùn)行還須要一些內(nèi)存,但一般都不會(huì)太大。須要考慮MySQL每一個(gè)鏈接須要的內(nèi)存,雖然每一個(gè)鏈接須要的內(nèi)存都不多,但它還要求一個(gè)基本量的內(nèi)存來執(zhí)行任何給定的查詢,并且查詢過程當(dāng)中還須要為排序、GROUP BY等操做分配臨時(shí)表內(nèi)存,所以須要為高峰期執(zhí)行大量的查詢預(yù)留足夠的內(nèi)存。這個(gè)內(nèi)存有多大?只能在運(yùn)行過程當(dāng)中監(jiān)控。服務(wù)器
若是大部分表都是InnoDB,MyISAM鍵緩存配置一個(gè)很小值足矣,查詢緩存也建議關(guān)閉。數(shù)據(jù)結(jié)構(gòu)
innodb-log-file-size && innodb-log-files-in-group
若是對(duì)InnoDB數(shù)據(jù)表有大量的寫入操做,那么選擇合適的innodb-log-file-size值對(duì)提高M(jìn)ySQL性能很重要。InnoDB使用日志來減小提交事務(wù)時(shí)的開銷。日志中記錄了事務(wù),就無須在每一個(gè)事務(wù)提交時(shí)把緩沖池的臟塊(緩存中與磁盤上數(shù)據(jù)不一致的頁)刷新到磁盤。事務(wù)修改的數(shù)據(jù)和索引一般會(huì)映射到表空間的隨機(jī)位置,因此刷新這些變動(dòng)到磁盤須要不少隨機(jī)I/O。一旦日志安全的寫入磁盤,事務(wù)就持久化了,即便變動(dòng)尚未寫到數(shù)據(jù)文件,在一些意外狀況發(fā)生時(shí)(好比斷電),InnoDB能夠重放日志而且恢復(fù)已經(jīng)提交的事務(wù)。并發(fā)
InnoDB使用一個(gè)后臺(tái)線程智能地刷新這些變動(dòng)到數(shù)據(jù)文件。實(shí)際上,事務(wù)日志把數(shù)據(jù)文件的隨機(jī)I/O轉(zhuǎn)換為幾乎順序地日志文件和數(shù)據(jù)文件I/O,讓刷新操做在后臺(tái)能夠更快的完成,而且緩存I/O壓力。async
總體的日志文件大小受控于innodb-log-file-size和innodb-log-files-in-group兩個(gè)參數(shù),這對(duì)寫性能很是重要。日志文件的總大小是每一個(gè)文件的大小之和。默認(rèn)狀況下,只有兩個(gè)5M的文件,總共10M,對(duì)高性能工做來講過小了,至少須要幾百M(fèi)或者上G的日志文件。這里要注意innodb-log-files-in-group這個(gè)參數(shù),它控制日志文件的數(shù)量,log group表示一個(gè)重作日志的文件集合,沒有參數(shù)也沒有必要配置有多少個(gè)日志組。
修改日志文件的大小,須要徹底關(guān)閉MySQL,而后將舊的日志文件遷移到其余地方,從新配置參數(shù),而后重啟。重啟時(shí)須要將舊的日志遷移回來,而后等待MySQL恢復(fù)數(shù)據(jù)后,再刪除舊的日志文件,請(qǐng)必定要查看錯(cuò)誤日志,確認(rèn)MySQL重啟成功后再刪除舊的日志文件。
想要肯定理想的日志文件大小,須要權(quán)衡正常數(shù)據(jù)變動(dòng)的開銷,以及崩潰時(shí)恢復(fù)須要的時(shí)間。
若是日志過小,InnoDB將必需要作更多的檢查點(diǎn),致使更多的日志寫,在極個(gè)別狀況下,寫語句還會(huì)被拖累,在日志沒有空間繼續(xù)寫入前,必須等待變動(dòng)被刷新到數(shù)據(jù)文件。
另外一方面,若是日志太大,在崩潰時(shí)恢復(fù)就得作大量的工做,這可能增大恢復(fù)時(shí)間。InnoDB會(huì)采用checkpoint機(jī)制來刷新和恢復(fù)數(shù)據(jù),這會(huì)加快恢復(fù)數(shù)據(jù)的時(shí)間,具體能夠參考:
innodb-flush-log-at-trx-commit
前面討論了不少緩存,InnoDB日志也是有緩存的。當(dāng)InnoDB變動(dòng)任何數(shù)據(jù)時(shí),會(huì)寫一條變動(dòng)記錄到日志緩存區(qū)。在緩沖慢的時(shí)候、事務(wù)提交的時(shí)候,或者每一秒鐘,InnoDB都會(huì)將緩沖區(qū)的日志刷新到磁盤的日志文件。若是有大事務(wù),增長(zhǎng)日志緩沖區(qū)大小能夠幫助減小I/O,變量innodb-log-buffer-size能夠控制日志緩沖區(qū)的大小。一般不須要把日志緩沖區(qū)設(shè)置的很是大,畢竟上述3個(gè)條件,任一條件先觸發(fā)都會(huì)把緩沖區(qū)的內(nèi)容刷新到磁盤,因此緩沖區(qū)的數(shù)據(jù)確定不會(huì)太多,出入你的數(shù)據(jù)中有不少至關(guān)大的BLOB記錄。一般來講,配置1M~8M便可。
既然存在緩沖區(qū),怎樣刷新日志緩沖就是咱們須要關(guān)注的問題。日志緩沖必須刷新到磁盤,以確保提交的事務(wù)徹底被持久化。若是和持久化相比,更在意性能,能夠修改innodb-flush-log-at-trx-commit變量來控制日志緩沖刷新的頻率。
0:每1秒鐘將日志緩沖寫到日志文件并刷新到磁盤,事務(wù)提交時(shí)不作任何處理
1:每次事務(wù)提交時(shí),將日志緩沖寫到日志文件并刷新到磁盤
2:每次事務(wù)提交時(shí),將日志緩沖寫到日志文件,而后每秒刷新一次到磁盤
1是最安全的設(shè)置,保證不會(huì)丟失任何已經(jīng)提交的事務(wù),這也是默認(rèn)的設(shè)置。0和2最主要的區(qū)別是,若是MySQL掛了,2不會(huì)丟失事務(wù),但0有可能,2在每次事務(wù)提交時(shí),至少將日志緩沖刷新到操做系統(tǒng)的緩存,而0則不會(huì)。若是整個(gè)服務(wù)器掛了或者斷電了,則仍是可能會(huì)丟失一些事務(wù)。
innodb-flush-method
innodb-flush-method選項(xiàng)能夠配置InnoDB如何跟文件系統(tǒng)相互做用。從名字上看,影響InnoDB怎么寫讀數(shù)據(jù)。windows和非Windows操做系統(tǒng)下這個(gè)選項(xiàng)的值是互斥的,也就是說有些值只能Windows下使用,有些只能在非Windows下使用,其中Windows下可取值:async_unbuffered、unbuffered、normal、Nosync與littlesync,非Windows取值:fdatasync、0_DIRECT、 0_DSYNC。
這個(gè)選項(xiàng)既會(huì)影響日志文件,也會(huì)影響數(shù)據(jù)文件,并且有時(shí)候?qū)Σ灰粯宇愋偷奈募奶幚硪膊煌?#xff0c;致使這個(gè)選項(xiàng)有些難以理解。若是有一個(gè)選項(xiàng)來配置日志文件,一個(gè)選項(xiàng)來配置數(shù)據(jù)文件,應(yīng)該會(huì)更好,但實(shí)際上它們混合在同一個(gè)配置項(xiàng)中。這里只介紹類Unix操做系統(tǒng)下的選項(xiàng)。
fdatasync
InnoDB調(diào)用fsync()和fdatasync()函數(shù)來刷新數(shù)據(jù)和日志文件,其中fdatasync()只刷文件的數(shù)據(jù),但不包含元數(shù)據(jù)(好比:訪問權(quán)限、文件擁有者、最后修改時(shí)間等描述文件特征的系統(tǒng)數(shù)據(jù)),所以fsync()相比fdatasync()會(huì)產(chǎn)生更多的I/O,但在某些場(chǎng)景下fdatasync()會(huì)致使數(shù)據(jù)損壞,所以InnoDB開發(fā)者決定用fsync()來代替fdatasync()。
fsync()的缺點(diǎn)是操做系統(tǒng)會(huì)在本身的緩存中緩沖一些數(shù)據(jù),理論上雙重緩沖是浪費(fèi)的,由于InnoDB本身會(huì)管理緩沖,并且比操做系統(tǒng)更加智能。但若是文件系統(tǒng)能有更智能的I/O調(diào)度和批量操做,雙重緩沖也并不必定是壞事:
有的文件系統(tǒng)和os能夠累積寫操做后合并執(zhí)行,經(jīng)過對(duì)I/O的重排序來提高效率、或者并發(fā)寫入多個(gè)設(shè)備
有的還能夠作預(yù)讀優(yōu)化,好比連續(xù)請(qǐng)求幾個(gè)順序的塊,它會(huì)通知硬盤預(yù)讀下一個(gè)塊
這些優(yōu)化在特定的場(chǎng)景下才會(huì)起做用,fdatasync為innodb-flush-method的默認(rèn)值。
0_DIRCET
這個(gè)設(shè)置不影響日志文件而且不是全部的類Unix系統(tǒng)都有效,但至少在Linux、FreeBSD以及Solaris是支持的。這個(gè)設(shè)置依然使用fsync來刷新文件到磁盤,可是它徹底關(guān)閉了操做系統(tǒng)緩存,而且是全部的讀和寫都直接經(jīng)過存儲(chǔ)設(shè)置,避免了雙重緩沖。若是存儲(chǔ)設(shè)備支持寫緩沖或預(yù)讀,那么這個(gè)選項(xiàng)并不會(huì)影響到設(shè)備的設(shè)置,好比RAID卡。
0_DSYNC
這個(gè)選項(xiàng)使得全部的寫同步,即只有數(shù)據(jù)寫到磁盤后寫操做才返回,但它只影響日志文件,而不影響數(shù)據(jù)文件。
建議:若是使用類Unix操做系統(tǒng)而且RAID控制器帶有電池保護(hù)的寫緩存,建議使用0_DIRECT,若是不是,默認(rèn)值或者0_DIRECT均可能是最好的選擇。
innodb-file-per-table
最后一個(gè)配置,說說InnoDB表空間,InnoDB把數(shù)據(jù)保存在表空間內(nèi),它本質(zhì)上是一個(gè)由一個(gè)或者多個(gè)磁盤文件組成的虛擬文件系統(tǒng)。InnoDB表空間并不僅是存儲(chǔ)表和索引,它還保存了回滾日志、插入緩沖、雙寫緩沖以及其余內(nèi)部數(shù)據(jù)結(jié)構(gòu),除此以外,表空間還實(shí)現(xiàn)了不少其它的功能。能夠經(jīng)過innodb-data-file-path配置項(xiàng)定制表空間文件,innodb-data-home-dir配置表空間文件存放的位置,好比:
innodb-data-home-dir = /var/lib/mysql
innodb-data-file-path = ibdata1:1G;ibdata2:1G;ibdata3:1G
這里在3個(gè)文件中建立了3G表空間,為了容許表空間在超過了分配的空間時(shí)還能增加,能夠像這樣配置最后一個(gè)文件自動(dòng)擴(kuò)展
innodb-data-file-path =ibdata1:1G;ibdata2:1G;ibdata3:1G:autoextend
innodb-file-per-table選項(xiàng)讓InnoDB為每張表使用一個(gè)文件,這使得在刪除一張表時(shí)回收空間容易不少,并且特別容易管理,而且能夠經(jīng)過查看文件大小來肯定表大小,因此這里建議打開這個(gè)配置。
總結(jié)
MySQL有太多的配置項(xiàng),這里沒有辦法一一列舉,重要的是了解每一個(gè)配置的工做原理,從一個(gè)基礎(chǔ)配置文件開始,設(shè)置符合服務(wù)器軟硬件環(huán)境與工做負(fù)載的基本選項(xiàng)。
參考資料
做者:CHEN川
連接:https://www.jianshu.com/p/78b6b7e2bb7f
來源:簡(jiǎn)書
簡(jiǎn)書著做權(quán)歸做者全部,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系做者得到受權(quán)并注明出處。
總結(jié)
以上是生活随笔為你收集整理的mysql优化原理_【MySQL】我必须得告诉你们的MySQL优化原理3(下)INNODB配置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unicode、UTF-8 和 ISO8
- 下一篇: 手机号码校验