復(fù)制概念
- Mysql內(nèi)建的復(fù)制功能是構(gòu)建大型,高性能應(yīng)用程序的基礎(chǔ)。
- 將Mysql的數(shù)據(jù)分布到多個(gè)系統(tǒng)上去冰抢,這種分布的機(jī)制罩驻,是通過(guò)將Mysql的某一臺(tái)主機(jī)的數(shù)據(jù)復(fù)制到其它主機(jī)(slaves)上,并重新執(zhí)行一遍來(lái)實(shí)現(xiàn)的。
- 復(fù)制過(guò)程中一個(gè)服務(wù)器充當(dāng)主服務(wù)器,而一個(gè)或多個(gè)其它服務(wù)器充當(dāng)從服務(wù)器。主服務(wù)器將更新寫入二進(jìn)制日志文件避归,并維護(hù)文件的一個(gè)索引以跟蹤日志循環(huán)。
- 當(dāng)一個(gè)從服務(wù)器連接主服務(wù)器時(shí)管呵,它通知主服務(wù)器從服務(wù)器在日志中讀取的最后一次成功更新的位置梳毙。從服務(wù)器接收從那時(shí)起發(fā)生的任何更新,然后封鎖并等待主服務(wù)器通知新的更新捐下。
需要注意的是:在進(jìn)行mysql復(fù)制時(shí)账锹,所有對(duì)復(fù)制中的表的更新必須在主服務(wù)器上進(jìn)行。否則必須要小心坷襟,以避免用戶對(duì)主服務(wù)器上的表進(jìn)行的更新與對(duì)從服務(wù)器上的表所進(jìn)行的更新之間的沖突奸柬。
Mysql支持 哪些復(fù)制
- 基于語(yǔ)句的復(fù)制: 在主服務(wù)器上執(zhí)行的SQL語(yǔ)句,在從服務(wù)器上執(zhí)行同樣的語(yǔ)句婴程。MySQL默認(rèn)采用基于語(yǔ)句的復(fù)制廓奕,效率比較高。一旦發(fā)現(xiàn)沒(méi)法精確復(fù)制時(shí),會(huì)自動(dòng)選著基于行的復(fù)制桌粉。
- 基于行的復(fù)制:把改變的內(nèi)容復(fù)制過(guò)去蒸绩,而不是把命令在從服務(wù)器上執(zhí)行一遍. 從mysql5.0開始支持
- 混合類型的復(fù)制: 默認(rèn)采用基于語(yǔ)句的復(fù)制,一旦發(fā)現(xiàn)基于語(yǔ)句的無(wú)法精確的復(fù)制時(shí)铃肯,就會(huì)采用基于行的復(fù)制患亿。
Mysql復(fù)制能解決的問(wèn)題
- 數(shù)據(jù)分布 (Data distribution )
- 負(fù)載平衡(load balancing)
- 數(shù)據(jù)備份(Backups) ,保證數(shù)據(jù)安全
- 高可用性和容錯(cuò)行(High availability and failover)
- 實(shí)現(xiàn)讀寫分離缘薛,緩解數(shù)據(jù)庫(kù)壓力
主從復(fù)制原理
- master節(jié)點(diǎn)將數(shù)據(jù)的改變記錄二進(jìn)制binlog日志窍育,當(dāng)master上的數(shù)據(jù)發(fā)生改變時(shí)卡睦,則將其改變寫入二進(jìn)制binlog日志中宴胧;
- salve節(jié)點(diǎn)會(huì)在一定時(shí)間間隔內(nèi)對(duì)master二進(jìn)制binlog日志進(jìn)行探測(cè)其是否發(fā)生改變
- 如果發(fā)生改變,salve節(jié)點(diǎn)則開啟一個(gè)I/O線程請(qǐng)求讀取master二進(jìn)制binlog日志數(shù)據(jù)
- 同時(shí)master節(jié)點(diǎn)為每個(gè)slave請(qǐng)求啟動(dòng)一個(gè)dump線程表锻,用于向slave發(fā)送日志數(shù)據(jù)
- slave節(jié)點(diǎn)接受并保存至本地的中繼日志relay log中
- slave節(jié)點(diǎn)將啟動(dòng)SQL寫庫(kù)線程從中繼日志中讀取二進(jìn)制日志數(shù)據(jù)恕齐,在本地重放,使得其數(shù)據(jù)和主節(jié)點(diǎn)的保持一致
- 最后I/O線程和SQL線程將進(jìn)入睡眠狀態(tài)瞬逊,等待下一次被喚醒显歧。
注意幾點(diǎn)
- master將操作語(yǔ)句記錄到binlog日志中,然后授予slave遠(yuǎn)程連接的權(quán)限(master一定要開啟binlog二進(jìn)制日志功能确镊;通常為了數(shù)據(jù)安全考慮士骤,slave也開啟binlog功能)。
- slave開啟兩個(gè)線程:IO線程和SQL線程蕾域。其中:IO線程負(fù)責(zé)讀取master的binlog內(nèi)容到中繼日志relay log里拷肌;SQL線程負(fù)責(zé)從relay log日志里讀出binlog內(nèi)容,并更新到slave的數(shù)據(jù)庫(kù)里旨巷,這樣就能保證slave數(shù)據(jù)和master數(shù)據(jù)保持一致了巨缘。
- Mysql復(fù)制至少需要兩個(gè)Mysql的服務(wù),當(dāng)然Mysql服務(wù)可以分布在不同的服務(wù)器上采呐,也可以在一臺(tái)服務(wù)器上啟動(dòng)多個(gè)服務(wù)若锁。
- Mysql復(fù)制最好確保master和slave服務(wù)器上的Mysql版本相同(如果不能滿足版本一致,那么要保證master主節(jié)點(diǎn)的版本低于slave從節(jié)點(diǎn)的版本)
- master和slave兩節(jié)點(diǎn)間時(shí)間需同步
流程圖如下:
如上圖所示:
- Mysql復(fù)制過(guò)程的第一部分就是master記錄二進(jìn)制日志斧吐。
在每個(gè)事務(wù)更新數(shù)據(jù)完成之前又固,master在二日志記錄這些改變。MySQL將事務(wù)串行的寫入二進(jìn)制日志煤率,即使事務(wù)中的語(yǔ)句都是交叉執(zhí)行的口予。在事務(wù)寫入二進(jìn)制日志完成后,master通知存儲(chǔ)引擎提交事務(wù)涕侈。 - 第二部分就是slave將master的binary log拷貝到它自己的中繼日志沪停。首先,slave開始一個(gè)工作線程——I/O線程。I/O線程在master上打開一個(gè)普通的連接木张,然后開始binlog dump process众辨。Binlog dump process從master的二進(jìn)制日志中讀取事件,如果已經(jīng)跟上master舷礼,它會(huì)睡眠并等待master產(chǎn)生新的事件鹃彻。I/O線程將這些事件寫入中繼日志。
- SQL slave thread(SQL從線程)處理該過(guò)程的最后一步妻献。SQL線程從中繼日志讀取事件蛛株,并重放其中的事件而更新slave的數(shù)據(jù),使其與master中的數(shù)據(jù)一致育拨。只要該線程與I/O線程保持一致谨履,中繼日志通常會(huì)位于OS的緩存中,所以中繼日志的開銷很小熬丧。
- 此外笋粟,在master中也有一個(gè)工作線程:和其它MySQL的連接一樣,slave在master中打開一個(gè)連接也會(huì)使得master開始一個(gè)線程析蝴。
復(fù)制過(guò)程有一個(gè)很重要的限制——復(fù)制在slave上是串行化的害捕,也就是說(shuō)master上的并行更新操作不能在slave上并行操作。
Mysql復(fù)制的模式
- 主從復(fù)制:主庫(kù)授權(quán)從庫(kù)遠(yuǎn)程連接闷畸,讀取binlog日志并更新到本地?cái)?shù)據(jù)庫(kù)的過(guò)程尝盼;主庫(kù)寫數(shù)據(jù)后,從庫(kù)會(huì)自動(dòng)同步過(guò)來(lái)(從庫(kù)跟著主庫(kù)變)佑菩;
- 主主復(fù)制:主從相互授權(quán)連接盾沫,讀取對(duì)方binlog日志并更新到本地?cái)?shù)據(jù)庫(kù)的過(guò)程;只要對(duì)方數(shù)據(jù)改變倘待,自己就跟著改變疮跑;(如何解決沖突?)
Mysql主從復(fù)制的優(yōu)點(diǎn)
- 在從服務(wù)器可以執(zhí)行查詢工作(即我們常說(shuō)的讀功能)凸舵,降低主服務(wù)器壓力;(主庫(kù)寫祖娘,從庫(kù)讀,降壓)
- 在從主服務(wù)器進(jìn)行備份啊奄,避免備份期間影響主服務(wù)器服務(wù);(確保數(shù)據(jù)安全)
- 當(dāng)主服務(wù)器出現(xiàn)問(wèn)題時(shí)渐苏,可以切換到從服務(wù)器。(提升性能)
Mysql主從復(fù)制總結(jié)
-
主從復(fù)制條件
- 開啟Binlog功能
- 主庫(kù)要建立賬號(hào)
- 從庫(kù)要配置master.info(CHANGE MASTER to...相當(dāng)于配置密碼文件和Master的相關(guān)信息)
- start slave 開啟復(fù)制功能
需要了解的:
1)3個(gè)線程菇夸,主庫(kù)IO琼富,從庫(kù)IO和SQL及作用
2)master.info(從庫(kù))作用
3)relay-log 作用
4)異步復(fù)制
5)binlog作用(如果需要級(jí)聯(lián)需要開啟Binlog)需要注意:
1)主從復(fù)制是異步的邏輯的SQL語(yǔ)句級(jí)的復(fù)制
2)復(fù)制時(shí),主庫(kù)有一個(gè)I/O線程庄新,從庫(kù)有兩個(gè)線程鞠眉,I/O和SQL線程
3)實(shí)現(xiàn)主從復(fù)制的必要條件是主庫(kù)要開啟記錄binlog功能
4)作為復(fù)制的所有Mysql節(jié)點(diǎn)的server-id都不能相同
5)binlog文件只記錄對(duì)數(shù)據(jù)庫(kù)有更改的SQL語(yǔ)句(來(lái)自主庫(kù)內(nèi)容的變更)薯鼠,不記錄任何查詢(select,show)語(yǔ)句
Mysql主從環(huán)境部署一段時(shí)間后械蹋,發(fā)現(xiàn)主從不同步時(shí)出皇,如何進(jìn)行數(shù)據(jù)同步至一致?(請(qǐng)往下看)
主從同步中可能存在的問(wèn)題
slave運(yùn)行過(guò)慢不能與master同步哗戈,也就是MySQL數(shù)據(jù)庫(kù)主從同步延遲
MySQL數(shù)據(jù)庫(kù)slave服務(wù)器延遲的現(xiàn)象是非常普遍的郊艘,這就導(dǎo)致了有了以下一些潛規(guī)則:“實(shí)時(shí)性要求不高的讀取操作可以放到slave服務(wù)器,實(shí)時(shí)性要求高的讀取操作放到master服務(wù)器”唯咬,“從機(jī)僅能做前一天的統(tǒng)計(jì)類查詢”纱注。
slave同步延遲的原理
MySQL的主從復(fù)制都是單線程的操作,主庫(kù)對(duì)所有DDL和DML產(chǎn)生的日志寫進(jìn)binlog胆胰,由于binlog是順序?qū)懩孕屎芨摺?br> Slave的IO Thread線程從主庫(kù)中bin log中讀取取日志。
Slave的SQL Thread線程將主庫(kù)的DDL和DML操作事件在slave中重放煮剧。DML和DDL的IO操作是隨即的斥滤,不是順序的将鸵,成本高很多勉盅。
由于SQL Thread也是單線程的,如果slave上的其他查詢產(chǎn)生lock爭(zhēng)用顶掉,又或者一個(gè)DML語(yǔ)句(大事務(wù)草娜、大查詢)執(zhí)行了幾分鐘卡住了,那么所有之后的DML會(huì)等待這個(gè)DML執(zhí)行完才會(huì)繼續(xù)執(zhí)行痒筒,這就導(dǎo)致了延時(shí)宰闰。也許有人會(huì)質(zhì)疑:主庫(kù)上那個(gè)相同的DDL也會(huì)執(zhí)行幾分鐘,為什么slave會(huì)延時(shí)簿透?原因是master可以并發(fā)執(zhí)行移袍,而Slave_SQL_Running線程卻不可以。slave同步延遲的可能原因
1--slave的I/O線程推遲讀取日志中的事件信息老充;最常見原因是slave是在單線程中執(zhí)行所有事務(wù)葡盗,而master有很多線程可以并行執(zhí)行事務(wù)。
2--帶來(lái)低效連接的長(zhǎng)查詢啡浊、磁盤讀取的I/O限制觅够、鎖競(jìng)爭(zhēng)和innodb線程同步啟動(dòng)等。
3--Master負(fù)載巷嚣;Slave負(fù)載
4--網(wǎng)絡(luò)延遲
5--機(jī)器配置(cpu喘先、內(nèi)存、硬盤)
(主從同步延遲怎么產(chǎn)生的廷粒?)總之窘拯,當(dāng)主庫(kù)的TPS并發(fā)較高時(shí)红且,產(chǎn)生的DDL數(shù)量超過(guò)slave一個(gè)sql線程所能處理的承受范圍時(shí),主從同步就會(huì)產(chǎn)生延時(shí)涤姊;或者當(dāng)slave中有大型query語(yǔ)句產(chǎn)生了鎖等待也會(huì)產(chǎn)生延時(shí)直焙。
-
如何查看同步延遲
1--可以通過(guò)比對(duì)master、slave上的日志位置
2--通過(guò)"show slave status"查看Seconds_Behind_Master的值砂轻,這個(gè)值代表主從同步延遲的時(shí)間奔誓,值越大說(shuō)明延遲越嚴(yán)重。值為0為正常情況搔涝,正值表示已經(jīng)出現(xiàn)延遲厨喂,數(shù)字越大從庫(kù)落后主庫(kù)越多。
3--使用percona-toolkit的pt-hearbeat工具進(jìn)行查看庄呈。 -
減少同步延遲的操作方案
1--減少鎖競(jìng)爭(zhēng)
如果查詢導(dǎo)致大量的表鎖定蜕煌,需要考慮重構(gòu)查詢語(yǔ)句,盡量避免過(guò)多的鎖诬留。
2--負(fù)載均衡
搭建多少slave斜纪,并且使用lvs或nginx進(jìn)行查詢負(fù)載均衡,可以減少每個(gè)slave執(zhí)行查詢的次數(shù)和時(shí)間文兑,從而將更多的時(shí)間用于去處理主從同步盒刚。
3--salve較高的機(jī)器配置
4--Slave調(diào)整參數(shù)
為了保障較高的數(shù)據(jù)安全性,配置sync_binlog=1绿贞,innodb_flush_log_at_trx_commit=1等設(shè)置因块。而Slave可以關(guān)閉binlog,innodb_flush_log_at_trx_commit也可以設(shè)置為0來(lái)提高sql的執(zhí)行效率(這兩個(gè)參數(shù)很管用)
5--并行復(fù)制
即有單線程的復(fù)制改成多線程復(fù)制籍铁。
從庫(kù)有兩個(gè)線程與復(fù)制相關(guān):io_thread 負(fù)責(zé)從主庫(kù)拿binlog并寫到relaylog涡上, sql_thread 負(fù)責(zé)讀relaylog并執(zhí)行。
多線程的思路就是把sql_thread 變成分發(fā)線程拒名,然后由一組worker_thread來(lái)負(fù)責(zé)執(zhí)行吩愧。
幾乎所有的并行復(fù)制都是這個(gè)思路,有不同的增显,便是sql_thread 的分發(fā)策略雁佳。
MySQL5.7的真正并行復(fù)制enhanced multi-threaded slave(MTS)很好的解決了主從同步復(fù)制的延遲問(wèn)題。
Mysql主從環(huán)境部署一段時(shí)間后甸怕,發(fā)現(xiàn)主從不同步時(shí)甘穿,如何進(jìn)行數(shù)據(jù)同步至一致?
1 使用數(shù)據(jù)庫(kù)監(jiān)測(cè)監(jiān)測(cè)工具percona-toolkit
2 人工對(duì)比日志
Mysql最常用的三種備份工具:
- mysqldump:
通常為小數(shù)據(jù)情況下的備份
innodb: 熱備梢杭,溫備
MyISAM, Aria: 溫備
單線程備份恢復(fù)比較慢 - Xtrabackup(通常用innobackupex工具):
備份mysql大數(shù)據(jù)
InnoDB熱備温兼,增量備份;
MyISAM溫備武契,不支持增量募判,只有完全備份
屬于物理備份荡含,速度快; - lvm-snapshot:
接近于熱備的工具:因?yàn)橐日?qǐng)求全局鎖届垫,而后創(chuàng)建快照释液,并在創(chuàng)建快照完成后釋放全局鎖;
使用cp装处、tar等工具進(jìn)行物理備份误债;
備份和恢復(fù)速度較快;
很難實(shí)現(xiàn)增量備份妄迁,并且請(qǐng)求全局需要等待一段時(shí)間寝蹈,在繁忙的服務(wù)器上尤其如此;