在數(shù)據(jù)庫(kù)運(yùn)行時(shí),出現(xiàn)宕機(jī)、停電、系統(tǒng)崩潰等異常情況,造成內(nèi)存和表空間文件在交換過(guò)程中,因?yàn)槌霈F(xiàn)問(wèn)題造成頁(yè)出錯(cuò),形成表空間文件的頁(yè)損壞或者丟失等情況,使表空間的文件無(wú)法正常使用。表空間和緩存是InnoDB引擎的主要組成部分,兩者之間的交互是很頻繁的。這種交互之所以可以實(shí)現(xiàn),依靠的是InnoDB Master線程。InnoDB的主要工作都是在一個(gè)或者多個(gè)單獨(dú)的Master線程中完成的,Master線程的優(yōu)先級(jí)最高,分為主循環(huán)、后臺(tái)循環(huán)、刷新循環(huán)、暫停循環(huán)等循環(huán),最主要的是主循環(huán)。主循環(huán)每秒執(zhí)行一次刷新日志緩沖區(qū),合并插入緩沖,最多刷新100個(gè)臟數(shù)據(jù)頁(yè),如果當(dāng)前用戶沒(méi)有活動(dòng)信息,切換到后臺(tái)循環(huán)等操作。
刷新日志緩沖是必須要做的,將日志緩存中的數(shù)據(jù)寫(xiě)入到磁盤(pán)文件,指的是Redo日志和Undo日志,前者用于重做緩存,后者用來(lái)執(zhí)行撤銷操作。在一個(gè)事物中經(jīng)過(guò)一番數(shù)據(jù)操作后,希望執(zhí)行RollBack回滾來(lái)撤銷操作,就必須用到Undo日志。其余的操作不一定必須發(fā)生。插入緩存是針對(duì)索引而言的,當(dāng)向數(shù)據(jù)表中插入數(shù)據(jù)時(shí),必然涉及對(duì)索引修改,當(dāng)對(duì)數(shù)據(jù)表進(jìn)行頻繁修改時(shí),InnoDB會(huì)將關(guān)于索引的改變信息暫時(shí)寫(xiě)入InnoDB Buffer Pool中的插入緩存中,之后將其合并寫(xiě)入真正的索引文件中。這樣,可以優(yōu)化索引的效率,讓索引中的數(shù)據(jù)盡可能地進(jìn)行序列化存儲(chǔ)。
實(shí)際上,InnoDB Buffer Pool和表空間文件的交互是很頻繁的,表空間文件中存儲(chǔ)了各種數(shù)據(jù),例如數(shù)據(jù)、索引等,都會(huì)被從磁盤(pán)中的存儲(chǔ)文件中抽取出來(lái),放入InnoDB Buffer Pool中緩存起來(lái)。如果出現(xiàn)服務(wù)器宕機(jī)、停電等情況,就會(huì)造成內(nèi)存中的這些動(dòng)態(tài)數(shù)據(jù)的丟失,無(wú)法寫(xiě)入到表空間文件。如果這種損壞超出了InnoDB引擎可以自動(dòng)修復(fù)的范圍,例如,當(dāng)緩存中的Redo日志寫(xiě)入到“ib_logfile”日志文件時(shí)出錯(cuò),造成日志文件損壞,那么InnoDB就無(wú)法對(duì)數(shù)據(jù)進(jìn)行恢復(fù),自然無(wú)法修復(fù)損壞的數(shù)據(jù)表。所謂臟數(shù)據(jù)頁(yè),指的是在緩存中存儲(chǔ)的對(duì)數(shù)據(jù)的改變,寫(xiě)回磁盤(pán)稱為刷新臟數(shù)據(jù)頁(yè)。Master線程每10秒執(zhí)行一次合并最多5個(gè)插入緩沖,刷新日志緩沖,刷新10或100個(gè)臟頁(yè)到磁盤(pán),產(chǎn)生一個(gè)檢查點(diǎn),刪除無(wú)用的Undo也等操作,這些操作必須發(fā)生。當(dāng)沒(méi)有用戶活動(dòng)或關(guān)閉數(shù)據(jù)庫(kù)的情況下,才會(huì)執(zhí)行后臺(tái)循環(huán),操作包括刪除無(wú)用的Undo頁(yè)、合并20個(gè)插入緩沖、跳回主循環(huán)、不斷刷新100個(gè)頁(yè),直到符合條件跳轉(zhuǎn)到刷新循環(huán)。
綜上所述可以看出,InnoDB引擎的內(nèi)存緩沖和磁盤(pán)中的文件是連續(xù)不斷互動(dòng)的。在這些環(huán)節(jié)中,有可能在多個(gè)地方發(fā)生錯(cuò)誤,例如,在InnoDB Buffer Pool中Data page部分在讀寫(xiě)過(guò)程中,如果一些臟頁(yè)(即發(fā)生改變的數(shù)據(jù))沒(méi)有及時(shí)寫(xiě)回磁盤(pán),就容易導(dǎo)致錯(cuò)誤的發(fā)生。當(dāng)然,如果存在Redo Log日志,就有補(bǔ)救的機(jī)會(huì)。當(dāng)Insert Buffer中的數(shù)據(jù)寫(xiě)回到表空間文件的索引部分中時(shí),如果發(fā)生異常,就可能導(dǎo)致索引的結(jié)構(gòu)出現(xiàn)損壞。當(dāng)Redo Log日志寫(xiě)入磁盤(pán)時(shí),也有可能發(fā)生問(wèn)題,導(dǎo)致表空間文件損壞。