接上篇?。?!
5. MySQL的復(fù)制原理以及流程
主從復(fù)制:將主數(shù)據(jù)庫(kù)中的DDL和DML操作通過(guò)二進(jìn)制日志(BINLOG)傳輸?shù)綇臄?shù)據(jù)庫(kù)上,然后將這些日志重新執(zhí)行(重做);從而使得從數(shù)據(jù)庫(kù)的數(shù)據(jù)與主數(shù)據(jù)庫(kù)保持一致。
主從復(fù)制的作用
主數(shù)據(jù)庫(kù)出現(xiàn)問(wèn)題,可以切換到從數(shù)據(jù)庫(kù)。
可以進(jìn)行數(shù)據(jù)庫(kù)層面的讀寫(xiě)分離。
可以在從數(shù)據(jù)庫(kù)上進(jìn)行日常備份。
MySQL主從復(fù)制解決的問(wèn)題
數(shù)據(jù)分布:隨意開(kāi)始或停止復(fù)制,并在不同地理位置分布數(shù)據(jù)備份
負(fù)載均衡:降低單個(gè)服務(wù)器的壓力
高可用和故障切換:幫助應(yīng)用程序避免單點(diǎn)失敗
升級(jí)測(cè)試:可以用更高版本的MySQL作為從庫(kù)
MySQL主從復(fù)制工作原理
在主庫(kù)上把數(shù)據(jù)更高記錄到二進(jìn)制日志
從庫(kù)將主庫(kù)的日志復(fù)制到自己的中繼日志
從庫(kù)讀取中繼日志的事件,將其重放到從庫(kù)數(shù)據(jù)中
基本原理流程,3個(gè)線程以及之間的關(guān)聯(lián)
主:binlog線程——記錄下所有改變了數(shù)據(jù)庫(kù)數(shù)據(jù)的語(yǔ)句,放進(jìn)master上的binlog中;
從:io線程——在使用start slave 之后,負(fù)責(zé)從master上拉取 binlog 內(nèi)容,放進(jìn)自己的relay log中;
從:sql執(zhí)行線程——執(zhí)行relay log中的語(yǔ)句;
復(fù)制過(guò)程
Binary log:主數(shù)據(jù)庫(kù)的二進(jìn)制日志
Relay log:從服務(wù)器的中繼日志
第一步:master在每個(gè)事務(wù)更新數(shù)據(jù)完成之前,將該操作記錄串行地寫(xiě)入到binlog文件中。
第二步:salve開(kāi)啟一個(gè)I/O Thread,該線程在master打開(kāi)一個(gè)普通連接,主要工作是binlog dump process。如果讀取的進(jìn)度已經(jīng)跟上了master,就進(jìn)入睡眠狀態(tài)并等待master產(chǎn)生新的事件。I/O線程最終的目的是將這些事件寫(xiě)入到中繼日志中。
第三步:SQL Thread會(huì)讀取中繼日志,并順序執(zhí)行該日志中的SQL事件,從而與主數(shù)據(jù)庫(kù)中的數(shù)據(jù)保持一致。
6. 讀寫(xiě)分離有哪些解決方案?
讀寫(xiě)分離是依賴于主從復(fù)制,而主從復(fù)制又是為讀寫(xiě)分離服務(wù)的。因?yàn)橹鲝膹?fù)制要求slave不能寫(xiě)只能讀(如果對(duì)slave執(zhí)行寫(xiě)操作,那么show slave status將會(huì)呈現(xiàn)Slave_SQL_Running=NO,此時(shí)你需要按照前面提到的手動(dòng)同步一下slave)。
方案一
使用mysql-proxy代理
優(yōu)點(diǎn):直接實(shí)現(xiàn)讀寫(xiě)分離和負(fù)載均衡,不用修改代碼,master和slave用一樣的帳號(hào),mysql官方不建議實(shí)際生產(chǎn)中使用
缺點(diǎn):降低性能, 不支持事務(wù)
方案二
使用AbstractRoutingDataSource+aop+annotation在dao層決定數(shù)據(jù)源。
如果采用了mybatis, 可以將讀寫(xiě)分離放在ORM層,比如mybatis可以通過(guò)mybatis plugin攔截sql語(yǔ)句,所有的insert/update/delete都訪問(wèn)master庫(kù),所有的select 都訪問(wèn)salve庫(kù),這樣對(duì)于dao層都是透明。plugin實(shí)現(xiàn)時(shí)可以通過(guò)注解或者分析語(yǔ)句是讀寫(xiě)方法來(lái)選定主從庫(kù)。不過(guò)這樣依然有一個(gè)問(wèn)題, 也就是不支持事務(wù), 所以我們還需要重寫(xiě)一下DataSourceTransactionManager, 將read-only的事務(wù)扔進(jìn)讀庫(kù), 其余的有讀有寫(xiě)的扔進(jìn)寫(xiě)庫(kù)。
方案三
使用AbstractRoutingDataSource+aop+annotation在service層決定數(shù)據(jù)源,可以支持事務(wù).
缺點(diǎn):類內(nèi)部方法通過(guò)this.xx()方式相互調(diào)用時(shí),aop不會(huì)進(jìn)行攔截,需進(jìn)行特殊處理。
7. 備份計(jì)劃,mysqldump以及xtranbackup的實(shí)現(xiàn)原理
(1)備份計(jì)劃
視庫(kù)的大小來(lái)定,一般來(lái)說(shuō) 100G 內(nèi)的庫(kù),可以考慮使用 mysqldump 來(lái)做,因?yàn)?mysqldump更加輕巧靈活,備份時(shí)間選在業(yè)務(wù)低峰期,可以每天進(jìn)行都進(jìn)行全量備份(mysqldump 備份出來(lái)的文件比較小,壓縮之后更小)。
100G 以上的庫(kù),可以考慮用 xtranbackup 來(lái)做,備份速度明顯要比 mysqldump 要快。一般是選擇一周一個(gè)全備,其余每天進(jìn)行增量備份,備份時(shí)間為業(yè)務(wù)低峰期。
(2)備份恢復(fù)時(shí)間
物理備份恢復(fù)快,邏輯備份恢復(fù)慢
這里跟機(jī)器,尤其是硬盤(pán)的速率有關(guān)系,以下列舉幾個(gè)僅供參考
20G的2分鐘(mysqldump)
80G的30分鐘(mysqldump)
111G的30分鐘(mysqldump)
288G的3小時(shí)(xtra)
3T的4小時(shí)(xtra)
邏輯導(dǎo)入時(shí)間一般是備份時(shí)間的5倍以上
(3)備份恢復(fù)失敗如何處理
首先在恢復(fù)之前就應(yīng)該做足準(zhǔn)備工作,避免恢復(fù)的時(shí)候出錯(cuò)。比如說(shuō)備份之后的有效性檢查、權(quán)限檢查、空間檢查等。如果萬(wàn)一報(bào)錯(cuò),再根據(jù)報(bào)錯(cuò)的提示來(lái)進(jìn)行相應(yīng)的調(diào)整。
(4)mysqldump和xtrabackup實(shí)現(xiàn)原理
mysqldump
mysqldump 屬于邏輯備份。加入–single-transaction 選項(xiàng)可以進(jìn)行一致性備份。后臺(tái)進(jìn)程會(huì)先設(shè)置 session 的事務(wù)隔離級(jí)別為 RR(SET SESSION TRANSACTION ISOLATION LEVELREPEATABLE READ),之后顯式開(kāi)啟一個(gè)事務(wù)(START TRANSACTION /*!40100 WITH CONSISTENTSNAPSHOT */),這樣就保證了該事務(wù)里讀到的數(shù)據(jù)都是事務(wù)事務(wù)時(shí)候的快照。之后再把表的數(shù)據(jù)讀取出來(lái)。如果加上–master-data=1 的話,在剛開(kāi)始的時(shí)候還會(huì)加一個(gè)數(shù)據(jù)庫(kù)的讀鎖(FLUSH TABLES WITH READ LOCK),等開(kāi)啟事務(wù)后,再記錄下數(shù)據(jù)庫(kù)此時(shí) binlog 的位置(showmaster status),馬上解鎖,再讀取表的數(shù)據(jù)。等所有的數(shù)據(jù)都已經(jīng)導(dǎo)完,就可以結(jié)束事務(wù)
Xtrabackup:
xtrabackup 屬于物理備份,直接拷貝表空間文件,同時(shí)不斷掃描產(chǎn)生的 redo 日志并保存下來(lái)。最后完成 innodb 的備份后,會(huì)做一個(gè) flush engine logs 的操作(老版本在有 bug,在5.6 上不做此操作會(huì)丟數(shù)據(jù)),確保所有的 redo log 都已經(jīng)落盤(pán)(涉及到事務(wù)的兩階段提交
概念,因?yàn)?xtrabackup 并不拷貝 binlog,所以必須保證所有的 redo log 都落盤(pán),否則可能會(huì)丟最后一組提交事務(wù)的數(shù)據(jù))。這個(gè)時(shí)間點(diǎn)就是 innodb 完成備份的時(shí)間點(diǎn),數(shù)據(jù)文件雖然不是一致性的,但是有這段時(shí)間的 redo 就可以讓數(shù)據(jù)文件達(dá)到一致性(恢復(fù)的時(shí)候做的事
情)。然后還需要 flush tables with read lock,把 myisam 等其他引擎的表給備份出來(lái),備份完后解鎖。這樣就做到了完美的熱備。
8. 數(shù)據(jù)表?yè)p壞的修復(fù)方式有哪些?
使用 myisamchk 來(lái)修復(fù),具體步驟:
1)修復(fù)前將mysql服務(wù)停止。
2)打開(kāi)命令行方式,然后進(jìn)入到mysql的/bin目錄。
3)執(zhí)行myisamchk –recover 數(shù)據(jù)庫(kù)所在路徑/*.MYI
使用repair table 或者 OPTIMIZE table命令來(lái)修復(fù),REPAIR TABLE table_name 修復(fù)表 OPTIMIZE TABLE table_name 優(yōu)化表 REPAIR TABLE 用于修復(fù)被破壞的表。OPTIMIZE TABLE 用于回收閑置的數(shù)據(jù)庫(kù)空間,當(dāng)表上的數(shù)據(jù)行被刪除時(shí),所占據(jù)的磁盤(pán)空間并沒(méi)有立即被回收,使用了OPTIMIZE TABLE命令后這些空間將被回收,并且對(duì)磁盤(pán)上的數(shù)據(jù)行進(jìn)行重排(注意:是磁盤(pán)上,而非數(shù)據(jù)庫(kù))。
最后,小編分類整理了許多java進(jìn)階學(xué)習(xí)材料和BAT面試給熱愛(ài)IT行業(yè)的你,如果需要資料的請(qǐng)轉(zhuǎn)發(fā)此文章后再私聊小編回復(fù)【java】就能領(lǐng)取2019年java進(jìn)階學(xué)習(xí)資料和BAT面試題以及《Effective Java》(第3版)電子版書(shū)籍。也可以加群:712263501領(lǐng)取海量學(xué)習(xí)資料進(jìn)行學(xué)習(xí)。