提出問題
- 服務(wù)器數(shù)據(jù)庫(kù)異常重啟了會(huì)造成什么樣的影響海铆?
- 不小心刪除了數(shù)據(jù)庫(kù)怎么辦种蝶,或者不小心刪除了數(shù)據(jù)庫(kù)表中數(shù)據(jù)怎么辦扩借?
- 一條更新語(yǔ)句在數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)部執(zhí)行時(shí)與數(shù)據(jù)庫(kù)日志系統(tǒng)有什么聯(lián)系襟铭?
- 數(shù)據(jù)庫(kù)備份薄货,是每天一備比較好翁都,還是每周一備比較好?
接下來(lái)在講解日志系統(tǒng)的同時(shí)谅猾,回答上面的幾個(gè)問題柄慰。
日志系統(tǒng)詳解:
redo日志(重做日志)
redo是引擎層的日志,而且是InnoDB特有的税娜。InnoDB的redo log是有固定大小的坐搔,比如可以配置為 一組4個(gè)文件(logfile-1,logfile-2敬矩,logfile-3概行,logfile-4),每個(gè)文件的大小是1GB弧岳,那么它總共可以記錄4GB的操作凳忙。一個(gè)環(huán)狀循環(huán)結(jié)構(gòu),從頭開始寫禽炬,寫到末尾又回到開始循環(huán)寫涧卵。
- redo中的環(huán)狀結(jié)構(gòu)
write pos是當(dāng)前記錄的位置,一邊寫一邊后移瞎抛,環(huán)狀結(jié)構(gòu)艺演,寫到3號(hào)文件末尾就會(huì)回到0號(hào)文件開頭。checkpoint是當(dāng)前擦除的位置桐臊,也是往后推移并且循環(huán)的。注意擦除記錄前要把記錄更新到數(shù)據(jù)文件(這里可以聯(lián)想 粉板 老板正式記賬本的例子)
- redo日志作用(回答提出問題1)
- 在MySQL中晓殊,如果每一次的更新操作都寫進(jìn)磁盤断凶,然后磁盤也找到對(duì)應(yīng)的那條記錄,然后再更新巫俺,整個(gè)過程io成本认烁,查找成本都很高,為了解決這個(gè)問題,提升效率却嗡,就會(huì)用到redo日志舶沛,MySQL經(jīng)常說(shuō)的的WAL技術(shù),WAL的全稱是write-Ahead-Logging窗价,它的關(guān)鍵點(diǎn)就是先寫日志如庭,再寫磁盤痹雅。具體說(shuō)颖低,當(dāng)有一條記錄需要更新的時(shí)候跋涣,InoDB引擎會(huì)先記錄到redo log鸠珠,并更新內(nèi)存猜谚,這時(shí)候更新就算完成了婴洼。同時(shí)InnoDb引擎會(huì)在適當(dāng)?shù)臅r(shí)候蒂阱,將這個(gè)操作記錄更新到磁盤里面洪乍,而這個(gè)更新往往是在系統(tǒng)比較空閑的時(shí)候做靶溜。
- 正是因?yàn)橛辛藃edo log ,InnoDB就可以保證即使數(shù)據(jù)庫(kù)發(fā)生異常重啟开瞭,之前提交的記錄多不會(huì)消失,這個(gè)能力叫crash-safe罩息。只要數(shù)據(jù)庫(kù)的物理記錄還在redo log中嗤详,就是服務(wù)器數(shù)據(jù)庫(kù)出現(xiàn)問題重啟,數(shù)據(jù)庫(kù)恢復(fù)后扣汪,數(shù)據(jù)記錄仍然可以恢復(fù)断楷。
binlog日志(歸檔日志)
Mysql基礎(chǔ)架構(gòu)整體分為兩部分:Server層和引擎層,引擎層主要負(fù)責(zé)存儲(chǔ)相關(guān)的事宜崭别。上面說(shuō)到在引擎層有自己的日志冬筒,而且只在InnoDB引擎中才有。Server層也有自己的日志茅主,稱為binlog(歸檔日志)舞痰。它是采用追寫入日志的方式。追加寫是指binlog文件寫到一定大小后會(huì)切換到下一個(gè)诀姚,并不會(huì)覆蓋以前的日志响牛。
- binlog日志作用(回答提出問題2)
只依靠redo日志的crash-safe特性在應(yīng)對(duì)數(shù)據(jù)庫(kù)誤刪,表數(shù)據(jù)誤刪等操作時(shí)候赫段,有些時(shí)候redo日志是無(wú)力的呀打,但是binlog日志解決這些問題,因?yàn)閎inlog會(huì)記錄所有的邏輯操作糯笙,并且采用“追加寫”的形式贬丛。
舉個(gè)例子如果公司老大發(fā)現(xiàn)某天下午有一個(gè)誤刪表數(shù)據(jù)操作,要求找回?cái)?shù)據(jù)给涕,應(yīng)該怎么做豺憔?(注:這里要考慮是在剛備份之后誤刪除额获,還是備份之前誤刪除,下面的例子是在備份之前刪除的恭应,找之前刪除的數(shù)據(jù))
- 首先抄邀,找到最近的一次全量備份,這要看你們公司的數(shù)據(jù)庫(kù)是多久備份一次(有的公司是一天昼榛,有的公司是一周境肾,而且會(huì)定期刪除,很多公司只保留最近一個(gè)月的數(shù)據(jù)庫(kù)備份)褒纲,拿到備份數(shù)據(jù)后准夷,把這個(gè)備份數(shù)據(jù)恢復(fù)到臨時(shí)表
- 然后從備份的時(shí)間點(diǎn)開始,將備份的binlog依次取出來(lái)莺掠,重放到誤刪表之前的那個(gè)時(shí)刻
- 這時(shí)候臨時(shí)庫(kù)跟誤刪之前的線上庫(kù)一樣了衫嵌,然后把表數(shù)據(jù)從臨時(shí)數(shù)據(jù)取出來(lái),按需恢復(fù)到線上庫(kù)去彻秆。
redo日志與binlog日志對(duì)比
redo日志與binlog日志有哪些不同楔绞? 其實(shí)上面好多都提到過,再次總結(jié)一遍唇兑,加深印象酒朵。
- redo log是InnoDB引擎特有的;binlog是MySQL的Server層實(shí)現(xiàn)的扎附,所有的引擎都可以使用蔫耽。
- redo log是物理日志,記錄的是某個(gè)數(shù)據(jù)頁(yè)上做了什么修改留夜;binlog是邏輯日志匙铡,記錄的是這個(gè)語(yǔ)句的原始邏輯,比如“給ID=2這一行的c字段加一”
- redo log是環(huán)狀結(jié)構(gòu)碍粥,循環(huán)寫鳖眼,空間固定會(huì)用完,用完后需要擦除嚼摩;binlog是可以追加寫入的钦讳。“追加寫”是只belog文件寫到一定大小后會(huì)切換到下一個(gè)枕面,并不會(huì)覆蓋以前的日志愿卒。
更新語(yǔ)句執(zhí)行流程(與日志關(guān)系)
數(shù)據(jù)庫(kù)語(yǔ)句:
mysql> update Student set c=c+1 where ID=2;
通過分析這一條更新語(yǔ)句,畫出流程圖潮秘,
問題3也就得到解決掘猿。
紅色是執(zhí)行器完成的部分,黑色時(shí)候引擎完成的部分唇跨。注意流程圖的最后三步稠通,這是更新語(yǔ)句和日志關(guān)系密切的地方,將redo日志拆成了兩個(gè)步驟:prepare和commit买猖,它倆的中間是執(zhí)行器寫入binlog改橘。(注:如果不這么做,假如一個(gè)日志提交成功的時(shí)候玉控,另一個(gè)日志提交之前發(fā)生了數(shù)據(jù)庫(kù)發(fā)生了崩潰飞主,但是crash-safe恢復(fù)或者誤刪庫(kù)恢復(fù)的時(shí)候可能造成二者數(shù)據(jù)不統(tǒng)一出現(xiàn)問題。)
開發(fā)過程中如何為mysql設(shè)置這兩種保存日志的配置
-
redo log
innodb_flush_log_at_trx_commit 這個(gè)參數(shù)設(shè)置成 1 的時(shí)候高诺,表示每次事務(wù)的 redo log 都直接持久化到磁盤碌识。這個(gè)參數(shù)我建議你設(shè)置成 1,這樣可以保證 MySQL 異常重啟之后數(shù)據(jù)不丟失虱而。
-
binlog
sync_binlog 這個(gè)參數(shù)設(shè)置成 1 的時(shí)候筏餐,表示每次事務(wù)的 binlog 都持久化到磁盤。這個(gè)參數(shù)我也建議你設(shè)置成 1牡拇,這樣可以保證 MySQL 誤刪除操作(刪除表數(shù)據(jù)魁瞪,刪除庫(kù)數(shù)據(jù)) 通過binlog 仍可恢復(fù)。
關(guān)于日志系統(tǒng)的一些誤區(qū)和疑問
-
大家會(huì)不會(huì)想有了redo日志就可以了惠呼,為什么還要出現(xiàn)binlog日志呢导俘?
解答:
- redo日志是只要InnoDB引擎才提供的一個(gè)內(nèi)容。
- redo日志是環(huán)狀結(jié)構(gòu)循環(huán)寫入剔蹋,并且到了配置的固定大小后會(huì)被擦除旅薄,誤刪除數(shù)據(jù)庫(kù)或表數(shù)據(jù)的時(shí)候,備份可能會(huì)出現(xiàn)無(wú)法全部還原泣崩。
這里有一個(gè)問題:如果在擦除和記賬重合那一刻少梁,數(shù)據(jù)庫(kù)異常重啟了,新的數(shù)據(jù)庫(kù)操作會(huì)怎么記錄律想,是擦除一部分猎莲,記錄上,會(huì)丟失技即,還是等待重啟后往上添加數(shù)據(jù)著洼?
-
關(guān)于數(shù)據(jù)庫(kù)備份,是一天一備比較好而叼,還是一周一備份比較好身笤,一般備份文件保留多久?提出問題4解決
解答:對(duì)于數(shù)據(jù)庫(kù)備份周期這個(gè)問題葵陵,需要考慮以下指標(biāo):數(shù)據(jù)存量液荸、增量、備份成本脱篙、恢復(fù)效率娇钱。
- 如果數(shù)據(jù)存量大到一天都沒法備份完成伤柄,只能一周一次甚至更長(zhǎng)時(shí)間
- 業(yè)務(wù)數(shù)據(jù)的增量,如果增量非常大文搂,如果一周備份一次适刀,可能會(huì)出現(xiàn)增量備份失敗問題,而且恢復(fù)時(shí)長(zhǎng)和成功率也比較困難煤蹭,則可以考慮一日一備笔喉。
- 業(yè)務(wù)比較重要,且對(duì)恢復(fù)時(shí)間的忍耐程度低硝皂,之前多次發(fā)生過數(shù)據(jù)回滾的需求常挚,數(shù)據(jù)增量還不小,可以考慮一天一備稽物。相反業(yè)務(wù)實(shí)際不重要奄毡,出問題可以容忍一定的不可用,增量還不多姨裸,可以考慮一周一備份秧倾。
總的來(lái)說(shuō)就是和項(xiàng)目,需求傀缩,場(chǎng)景有很多關(guān)系那先。
-
寫入redo日志也是io操作,數(shù)據(jù)更新直接寫入磁盤也是io操作赡艰,為什么說(shuō)寫入redo日志效率高節(jié)省io成本呢售淡?
解答:redo日志的寫入是順序?qū)懭氲模挥萌ァ罢椅恢谩笨犊澹苯痈聰?shù)據(jù)到磁盤的話揖闸,需要到磁盤中找到位置再寫入,肯定前者的效率高料身。
總結(jié)
以上內(nèi)容是關(guān)于數(shù)據(jù)庫(kù)日志系統(tǒng)的講解汤纸,同時(shí)解決了我開篇提出的幾個(gè)數(shù)據(jù)庫(kù)日志相關(guān)的問題,希望能幫助大家更好的了解學(xué)習(xí)數(shù)據(jù)庫(kù)芹血,如果有問題可以隨時(shí)關(guān)注公眾號(hào)聯(lián)系贮泞,互相學(xué)習(xí)哦。
<center>覺得本文對(duì)你有幫助幔烛?請(qǐng)分享給更多人<center>
歡迎大家關(guān)注我的公眾號(hào)——程序員成長(zhǎng)指北啃擦。請(qǐng)自行微信搜索——“程序員成長(zhǎng)指北”