innodb日志管理機(jī)制:
1、innodb存儲(chǔ)引擎是支持事務(wù)ACID特性的,這個(gè)理論基本就是一個(gè)關(guān)系型數(shù)據(jù)庫(kù)相關(guān)的數(shù)據(jù)恢復(fù)原形設(shè)計(jì),包括日志、回滾、redo、并發(fā)控制、buffer pool等管理方面,內(nèi)容非常全面;
2、innodb的buffer pool主要用來(lái)存儲(chǔ)訪問(wèn)過(guò)的數(shù)據(jù)頁(yè)面,他就是一塊連續(xù)的內(nèi)存,通過(guò)一定的算法可以使這塊內(nèi)存得到有效的管理,它是數(shù)據(jù)庫(kù)系統(tǒng)中擁有大塊內(nèi)存的系統(tǒng)模塊。
innodb存儲(chǔ)引擎中數(shù)據(jù)的訪問(wèn)是按照頁(yè)(也可以叫塊,默認(rèn)為16KB)的方式從數(shù)據(jù)庫(kù)文件讀取到buffer pool中的,然后在內(nèi)存中用同樣大小的內(nèi)存空間來(lái)做一個(gè)映射;未來(lái)提高數(shù)據(jù)訪問(wèn)效率,數(shù)據(jù)庫(kù)系統(tǒng)預(yù)先就分配了很多這樣的空間,用來(lái)與文件中的數(shù)據(jù)進(jìn)行交換;buffer pool的大小可以在配置文件中配置,有參數(shù)innodb_buffer_pool_size的大小來(lái)決定,默認(rèn)大小為128MB。在MySQL5.7.4以前,一旦MySQL啟動(dòng)這個(gè)值便不能再做修改,如果要修改只能退出MySQL進(jìn)程,然后修改對(duì)應(yīng)的配置文件來(lái)設(shè)置新的buffer pool大小,重啟才能生效。
注意:在MySQL5.7.5之后,可以在MySQL進(jìn)程運(yùn)行的情況下,動(dòng)態(tài)調(diào)整innodb_buffer_pool_size,需要強(qiáng)調(diào)的是,如果buffer pool的大小超過(guò)了1GB,應(yīng)該通過(guò)調(diào)整innodb_buffer_pool_instances=N,把它分成若干個(gè)instance的做法,來(lái)提示MySQL處理請(qǐng)求的并發(fā)能力,因?yàn)閎uffer pool是通過(guò)鏈表的方式來(lái)管理頁(yè)面的,同時(shí)為了保護(hù)頁(yè)面,需要在存取的時(shí)候?qū)︽湵砑渔i,在多線程的情況下,并發(fā)去讀寫(xiě)buffer pool里面緩存的頁(yè)面需要鎖的競(jìng)爭(zhēng)和等待。所以修改為多個(gè)instance,每個(gè)instance各自管理自己的內(nèi)存和鏈表,可以提升效率。
3、buffer pool實(shí)現(xiàn)原理:
buffer pool可以有多個(gè)實(shí)例,可以通過(guò)配置文件中的參數(shù)innodb_buffer_pool_instance來(lái)設(shè)置,默認(rèn)值為1,實(shí)現(xiàn)多個(gè)實(shí)例的buffer pool主要是為了提高數(shù)據(jù)頁(yè)訪問(wèn)時(shí)的并發(fā)度。每個(gè)實(shí)例的空間大小都是相同的,也就是說(shuō)系統(tǒng)會(huì)將整個(gè)配置的buffer pool大小按實(shí)例個(gè)數(shù)平分,然后每個(gè)實(shí)例各自進(jìn)行初始化操作;
--注意:在運(yùn)維過(guò)程中,看到狀態(tài)參數(shù)innodb_buffer_pool_bytes_data總是比innodb_buffer_pool_size小,就是因?yàn)榭刂祁^信息占用了部分空間。實(shí)際的分配方式是,buffer pool頁(yè)面從整個(gè)實(shí)例池中從后向前分配,每次分配一個(gè)頁(yè)面,而控制結(jié)構(gòu)使從前向后分配,每次分配一個(gè)buf_block_t結(jié)構(gòu)的大小,知道相遇為止,這樣就將一個(gè)實(shí)例初始化好了。
第一、redo log日志文件管理:
redo log是用來(lái)做數(shù)據(jù)庫(kù)crash recovery的,這是數(shù)據(jù)庫(kù)保障數(shù)據(jù)安全的重要功能之一。在數(shù)據(jù)庫(kù)操作中,它保存了對(duì)innodb表中數(shù)據(jù)的修改記錄,所以也叫日志文件。在innodb存儲(chǔ)引擎中,一般默認(rèn)包括2個(gè)日志文件,新建數(shù)據(jù)庫(kù)之后會(huì)有名為ib_logfile0 和ib_logfile1的兩個(gè)文件,如果在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),這兩個(gè)文件不存在,則innodb會(huì)根據(jù)配置參數(shù)或默認(rèn)值,重新創(chuàng)建日志文件;
1.1、LSN 全名叫:log sequence number:
在innodb內(nèi)部的日志管理中,一個(gè)很重要的概念是LSN,全名叫l(wèi)og sequence number,它用來(lái)精確記錄日志位置信息,且是連續(xù)增長(zhǎng)的。在innodb中,大小為8個(gè)字節(jié)值,它的增長(zhǎng)量是根據(jù)一個(gè)MTR寫(xiě)入的日志量來(lái)計(jì)算的,寫(xiě)多少日志,LSN就增長(zhǎng)多少。(LSN是一個(gè)完全邏輯的概念,每提交一個(gè)物理事務(wù),LSN就加1)
1.2、在innodb中,通過(guò)日志組來(lái)管理日志文件,是一個(gè)邏輯定義,包含若干個(gè)日志文件,一個(gè)組中的日志文件大小相等,大小通過(guò)參數(shù)來(lái)設(shè)置,現(xiàn)在innodb只持有一個(gè)日志組。(在MySQL5.5以前日志組大4G;MySQL5.6.3以后可以設(shè)置的更大到512G)
1.3、redo日志的寫(xiě)入,都是字節(jié)連續(xù)的,雖然看上去是多個(gè)日志文件,但理解的時(shí)候,完全可以把它想象成一個(gè)文件。(日志組中的每個(gè)日志文件,都有自己的格式,內(nèi)部也是按照大小相等的頁(yè)面切割,每個(gè)頁(yè)面大小是512字節(jié))
---注意:如果每次寫(xiě)入是磁盤(pán)塊大小的倍數(shù),效率才是高的,并且日志將邏輯事務(wù)對(duì)數(shù)據(jù)庫(kù)的分散隨機(jī)寫(xiě)入轉(zhuǎn)化成了順序的512字節(jié)整數(shù)倍數(shù)據(jù)的寫(xiě)入,這樣就大大提高了數(shù)據(jù)庫(kù)的效率。
1.4、redo日志文件的格式:
每個(gè)日志文件,都有文件頭(普通頁(yè)面中,都會(huì)有12個(gè)字節(jié)用來(lái)存儲(chǔ)頁(yè)面頭信息,這些信息主要用于管理這個(gè)頁(yè)面本身的數(shù)據(jù)存儲(chǔ)方式;---注意只有2KB是日志頭,后面是一個(gè)個(gè)連續(xù)的,用來(lái)存儲(chǔ)MTR產(chǎn)生的日志頁(yè)面)
1.5、MTRinnodb物理事務(wù):
它是innodb存儲(chǔ)引擎中一個(gè)很重要的用來(lái)保證物理頁(yè)面寫(xiě)入操作完整性及持久性的機(jī)制。之所以被稱(chēng)為MTR,是因?yàn)樗囊饬x相當(dāng)于一個(gè)mini-transaction,用MTR來(lái)表示,這里吧它稱(chēng)作“物理事務(wù)”,這樣叫是相對(duì)邏輯事務(wù)而言的。
物理事務(wù)既然被稱(chēng)為事務(wù),那它同樣有事務(wù)的開(kāi)始和提交,物理事務(wù)的開(kāi)始其實(shí)就是對(duì)物理事務(wù)結(jié)構(gòu)體mtr_struct的初始化,物理事務(wù)的提交主要是將所有這個(gè)物理事務(wù)產(chǎn)生的日志寫(xiě)入到innodb日志系統(tǒng)的日志緩沖區(qū)中,然后等待srv_master_thread線程定時(shí)將日志系統(tǒng)的日志緩沖區(qū)的日志數(shù)據(jù)刷到日志文件中;
---注意:日志緩沖區(qū)的存儲(chǔ)只是一個(gè)暫時(shí)的中間狀態(tài),日志緩沖區(qū)的大小可以通過(guò)參數(shù)innodb_log_buffer_size來(lái)設(shè)置,一般都比較小,存儲(chǔ)不了多少日志。
--日志是在邏輯事務(wù)對(duì)數(shù)據(jù)庫(kù)做DML操作時(shí),其所包含的物理事務(wù)MTR所記錄的,針對(duì)所有涉及的buffer pool頁(yè)面的修改記錄;
1.6、日志提高性能的關(guān)鍵原因:
①:因?yàn)槿罩臼怯脕?lái)記錄buffer pool中page的修改記錄的,所以把page的寫(xiě)入轉(zhuǎn)化為對(duì)日志的寫(xiě)入,那此時(shí)page就不需要每次都刷盤(pán),寫(xiě)page頁(yè)面只需要在內(nèi)存中寫(xiě)入即可,性能會(huì)非常好;
②:通常,一個(gè)頁(yè)面是16KB,如果不寫(xiě)入職,每次寫(xiě)入的單位還是16KB,即使修改很少的數(shù)據(jù),也是如此,這樣會(huì)導(dǎo)致無(wú)效IO非常嚴(yán)重。
1.7、redo日志大小設(shè)置的問(wèn)題:
①:如果設(shè)置的非常大,固然性能可能會(huì)很好,但是如果數(shù)據(jù)庫(kù)出現(xiàn)異常停機(jī),此時(shí)可能有很多日志都沒(méi)有刷盤(pán),也就是log flushed up to 與 last checkpointat 兩個(gè)值之間相差太多,恢復(fù)需要比較長(zhǎng)的時(shí)間。(redo日志的恢復(fù)是順序的,都是根據(jù)頁(yè)面號(hào)的大小排序恢復(fù)的;)
②:日志容量大小的設(shè)置,最好與buffer pool的總大小匹配。如果日志容量太小,buffer pool太大,這就會(huì)導(dǎo)致buffer pool頻繁做檢查點(diǎn),大的buffer pool不能被好好利用,如果日志容量過(guò)大,而buffer pool很小,此時(shí)buffer page經(jīng)常會(huì)被淘汰出去,增加IO頻次,同時(shí)如果數(shù)據(jù)庫(kù)意外宕機(jī),buffer pool太小,恢復(fù)起來(lái)也會(huì)比較慢;
1.8、redo日志記錄格式:
innodb的日志是具有邏輯意義的物理日志,所以,日志記錄的格式就不完全是物理信息,而是有一定邏輯意義,基本的格式如下: type(日志類(lèi)型),space(表空間ID值),offset(前面space所指定的文件中的頁(yè)面號(hào),以頁(yè)面大小為單位),data(表示這條日志記錄對(duì)應(yīng)的數(shù)據(jù),這個(gè)數(shù)據(jù)是不確定的,根據(jù)不同的type值而不同) ---type類(lèi)型有很多,比較常用的有: ①:mlog_ibyte、mlog_2bytes、mlog_4bytes、mlog_8bytes:這四個(gè)類(lèi)型,表示要在某個(gè)位置,寫(xiě)入一個(gè)(兩個(gè)、四個(gè)、八個(gè))字節(jié)的內(nèi)容; ②:mlog_write_string:這種類(lèi)型的日志,其實(shí)和mlog_ibyte是類(lèi)似的,只是mlog_ibyte是要寫(xiě)一個(gè)固定長(zhǎng)度的數(shù)據(jù),而mlog_write_string是要寫(xiě)一段變長(zhǎng)的數(shù)據(jù)。 ③:mlog_undo_insert:這個(gè)類(lèi)型的日志,是在將一條記錄設(shè)置為頁(yè)面中的最小記錄時(shí)產(chǎn)生的,因?yàn)橹皇谴騻€(gè)標(biāo)記,存儲(chǔ)的內(nèi)容比較簡(jiǎn)單; ④:mlog_init_file_page:這個(gè)類(lèi)型的日志比較簡(jiǎn)單,只有前面的基本頭信息,沒(méi)有data部分; ⑤:mlog_comp_page_create:這個(gè)類(lèi)型只需要村一個(gè)類(lèi)型及要?jiǎng)?chuàng)建的頁(yè)面的位置即可; ⑥:mlog_multi_rec_end:這個(gè)類(lèi)型的記錄是非常特殊的,它只起一個(gè)標(biāo)記的作用,其存儲(chǔ)的內(nèi)容只有占一個(gè)字節(jié)的類(lèi)型值。 ⑦:mlog_comp_rec_clust_delete_mark:這個(gè)類(lèi)型的日志是表示,需要將聚集索引中的某個(gè)記錄打上刪除標(biāo)志; ⑧:mlog_comp_rec_update_in_place:這個(gè)類(lèi)型的日志記錄更新后的記錄信息,包括所有被更新的列的信息。 ⑨:mlog_comp_page_reorganize:這個(gè)類(lèi)型的日志表示的是要重組指定的頁(yè)面,其記錄的內(nèi)容也很簡(jiǎn)單,只需要存儲(chǔ)要重組哪一個(gè)頁(yè)面即可;1.9、日志刷盤(pán)時(shí)機(jī):共有5種時(shí)機(jī):
①:log buffer空間用完了,這就會(huì)將已經(jīng)產(chǎn)生的log buffer中的日志刷到磁盤(pán)中,這是最普遍的一種方式; ②:master線程在后臺(tái)每秒鐘刷一次,將當(dāng)前l(fā)og buffer中的日志刷到磁盤(pán)中; ③:每次執(zhí)行DML操作時(shí),都會(huì)主動(dòng)檢查日志空間是否足夠,如果使用空間的量已經(jīng)超過(guò)了一個(gè)預(yù)設(shè)的經(jīng)驗(yàn)值,就會(huì)主動(dòng)刷日志,以保證在后面真正執(zhí)行時(shí),不會(huì)再執(zhí)行過(guò)程中被動(dòng)的刷盤(pán),但這里只會(huì)是寫(xiě)文件(寫(xiě)入OS緩沖中)不會(huì)刷盤(pán) ④:在做檢查點(diǎn)的時(shí)候,要保證所有要刷的頁(yè)面中LSN值最小的日志已經(jīng)刷入到磁盤(pán),不然,如果此時(shí)數(shù)據(jù)庫(kù)宕機(jī),日志不存在,但數(shù)據(jù)頁(yè)面已經(jīng)被修改,從而導(dǎo)致數(shù)據(jù)不一致,就違背了寫(xiě)日志的原則; ⑤:提交邏輯事務(wù)時(shí),會(huì)因?yàn)閰?shù)innodb_flush_log_at_trx_commit值的不同,產(chǎn)生不同的行為。如果設(shè)置0,則在事務(wù)提交時(shí),根本不會(huì)去刷日志緩沖區(qū),這種設(shè)置是最危險(xiǎn)的;如果設(shè)置2,則在事務(wù)提交時(shí)會(huì)將日志寫(xiě)入到文件中,但不會(huì)去刷盤(pán),只要操作系統(tǒng)不掛,即使數(shù)據(jù)庫(kù)掛了,數(shù)據(jù)還是不會(huì)丟失,一般都是設(shè)置為2;1.10、redo log刷盤(pán)機(jī)制:
當(dāng)提交事務(wù)(邏輯)時(shí),可以通過(guò)參數(shù)innodb_flush_log_at_trx_commit來(lái)控制redo log寫(xiě)入的機(jī)制,參數(shù)值不同,產(chǎn)生的行為不同,主要參數(shù)值如下:
①:innodb_flush_log_at_trx_commit=0 事務(wù)提交時(shí),MySQL不會(huì)去處理日志緩存區(qū)的內(nèi)容,也不會(huì)去處理日志文件的刷盤(pán)操作,由MySQL的后臺(tái)master線程每隔1s將緩存區(qū)的文件刷新到日志文件中;(主機(jī)正常,數(shù)據(jù)庫(kù)宕機(jī)后:一般只會(huì)丟失最近1s的事務(wù)) ②:innodb_flush_log_at_trx_commit=1 事務(wù)提交時(shí),會(huì)將日志緩沖區(qū)的日志寫(xiě)入到文件中,同時(shí)會(huì)刷新到磁盤(pán)中,保證數(shù)據(jù)庫(kù)事務(wù)完全不會(huì)丟失。這種設(shè)置影響數(shù)據(jù)庫(kù)性能;(主機(jī)正常,數(shù)據(jù)庫(kù)宕機(jī)后:數(shù)據(jù)不會(huì)丟失) ③:innodb_flush_log_at_trx_commit=2 事務(wù)提交時(shí),會(huì)將日志緩存區(qū)日志寫(xiě)入到文件中,但是不會(huì)刷新到磁盤(pán)中。由MySQL的后臺(tái)master線程每隔1s將系統(tǒng)緩存的日志文件刷新到磁盤(pán)中;(主機(jī)正常,數(shù)據(jù)庫(kù)宕機(jī)后:數(shù)據(jù)不會(huì)丟失)---注意:如果數(shù)據(jù)庫(kù)所在主機(jī)宕機(jī)后:參數(shù)0 會(huì)丟失最近1s的事務(wù);參數(shù)1 不會(huì)有任何數(shù)據(jù)丟失; 參數(shù)2 會(huì)丟失最近1s的事務(wù);
第二、數(shù)據(jù)庫(kù)undo段管理:
在innodb中支持的回滾段總共有:128X1024=131072個(gè),在每一個(gè)事務(wù)開(kāi)始的時(shí)候,都會(huì)分配一個(gè)rseg,就是從長(zhǎng)度為128的數(shù)組中,根據(jù)最近使用的情況,找到一個(gè)臨近位置的rseg;
在事務(wù)執(zhí)行的過(guò)程中,會(huì)產(chǎn)生兩種回滾日志,一種是insert的undo記錄,一種是update的undo記錄;(因?yàn)閕nnodb把undo分為兩類(lèi),一類(lèi)就是新增,也就是insert,一類(lèi)是修改,就是update,分類(lèi)的依據(jù)就是事務(wù)提交后要不要做purge操作,因?yàn)閕nsert是不需要purge的,只要事務(wù)提交了,那這個(gè)回滾記錄就可以丟掉了,而對(duì)于更新和刪除操作而言,如果事務(wù)提交了,還需要為MVCC服務(wù),那就需要將這些日志放到history list中去,等待去做purge已經(jīng)MVCC的多版本查詢(xún)等,所以分為兩類(lèi))
2.1、數(shù)據(jù)庫(kù)undo日志記錄格式:
undo有4種類(lèi)型:
①:trx_undo_insert_rec:記錄插入的undo日志類(lèi)型,插入記錄用于回滾時(shí),只需要通過(guò)其主鍵就可以實(shí)現(xiàn)回滾操作,所以在undo日志中,只記錄了表ID及主鍵信息; ②:trx_undo_upd_exist_rec:更新一條存在記錄的undo日志類(lèi)型; ③:trx_undo_upd_del_rec:更新一條已經(jīng)打了刪除標(biāo)志記錄的undo日志類(lèi)型; ④:trx_undo_del_mark_rec:刪除記錄時(shí)對(duì)記錄打刪除標(biāo)志的undo日志類(lèi)型; ---注意:與redo日志記錄存儲(chǔ)不同,undo日志的存儲(chǔ),是不會(huì)垮頁(yè)面的; ---注意:使用參數(shù)innodb_force_recovery來(lái)決定要不要做回滾操作,如果設(shè)置3或3以上,那么在啟動(dòng)innodb的時(shí)候就不回滾了,這樣可能導(dǎo)致數(shù)據(jù)庫(kù)邏輯上的不一致;另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)頁(yè)名稱(chēng):MySQL——innodb日志管理-創(chuàng)新互聯(lián)
文章起源:http://chinadenli.net/article46/deegeg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷(xiāo)推廣、微信小程序、響應(yīng)式網(wǎng)站、建站公司、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容