第一篇:MySQL主從復(fù)制的常見拓?fù)?、原理分析以及如何提高主從?fù)制的效率總結(jié)講解
MySQL主從復(fù)制的常見拓?fù)洹⒃矸治鲆约叭绾翁岣咧鲝膹?fù)制的效率總結(jié)
一、主從復(fù)制搭建方法參考
1、MySQL5.6 數(shù)據(jù)庫主從(Master/Slave)同步安裝與配置詳解請參考:
http://blog.csdn.net/xlgen157387/article/details/51331244#comments
2、使用mysqlreplicate命令快速搭建 Mysql 主從復(fù)制:
http://blog.csdn.net/xlgen157387/article/details/52452394
二、Mysql 主從復(fù)制的常用拓?fù)浣Y(jié)構(gòu)
2.1、一主一從
這里寫圖片描述
是最基礎(chǔ)的復(fù)制結(jié)構(gòu),用來分擔(dān)之前單臺數(shù)據(jù)庫服務(wù)器的壓力,可以進(jìn)行讀寫分離。
2.2、一主多從
一臺 Slave 承受不住讀請求壓力時,可以添加多臺,進(jìn)行負(fù)載均衡,分散讀壓力。
還可以對多臺 Slave 進(jìn)行分工,服務(wù)于不同的系統(tǒng),例如一部分 Slave 負(fù)責(zé)網(wǎng)站前臺的讀請求,另一部分 Slave 負(fù)責(zé)后臺統(tǒng)計系統(tǒng)的請求。
因為不同系統(tǒng)的查詢需求不同,對 Slave 分工后,可以創(chuàng)建不同的索引,使其更好的服務(wù)于目標(biāo)系統(tǒng)。
2.3、雙主復(fù)制
Master 存在下線的可能,例如故障或者維護(hù),需要把 Slave 切換為 Master。
在原來的 Master 恢復(fù)可用后,由于其數(shù)據(jù)已經(jīng)不是最新的了,不能再做主,需要做為 Slave 添加進(jìn)來。
那么就需要對其重新搭建復(fù)制環(huán)境,需要耗費一定的工作量。
雙主結(jié)構(gòu)就是用來解決這個問題的,互相將對方作為自己的 Master,自己作為對方的 Slave 來進(jìn)行復(fù)制,但對外來講,還是一個主和一個從。
當(dāng) 主Master 下線時,備Master 切換為 主Master,當(dāng)原來的 主Master 上線后,因為他記錄了自己當(dāng)前復(fù)制到對方的什么位置了,就會自動從之前的位置開始重新復(fù)制,不需要人為地干預(yù),大大提升了效率。
2.4、級聯(lián)復(fù)制
當(dāng)直接從屬于 Master 的 Slave 過多時,連到 Master 的 Slave IO 線程就比較多,對 Master 的壓力是很大的。
級聯(lián)結(jié)構(gòu)就是通過減少直接從屬于 Master 的 Slave 數(shù)量,減輕 Master 的壓力,分散復(fù)制請求,從而提高整體的復(fù)制效率。
2.5、雙主級聯(lián)
級聯(lián)復(fù)制結(jié)構(gòu)解決了 Slave 過多導(dǎo)致的瓶頸問題,但還是有單主結(jié)構(gòu)中切換主時的維護(hù)問題。
那么為了解決這個問題,就可以加入上面的雙主結(jié)構(gòu)。
在必要時,可以再對 Slaves 進(jìn)行分級。
Mysql 的復(fù)制結(jié)構(gòu)有很多種方式,復(fù)制的最大問題是數(shù)據(jù)延時,選擇復(fù)制結(jié)構(gòu)時需要根據(jù)自己的具體情況,并評估好目標(biāo)結(jié)構(gòu)的延時對系統(tǒng)的影響。
三、Mysql 主從復(fù)制過程及原理
3.1、Binary Log 簡單介紹
因為Binlog dump 線程操作的文件是bin-log 日志文件,并且實現(xiàn)主從復(fù)制在主服務(wù)器上主要依靠bin-log日志文件,所以我們簡單介紹一下bin-log日志文件。
3.2、原理
MySQL的Replication(英文為復(fù)制)是一個多MySQL數(shù)據(jù)庫做主從同步的方案,特點是異步復(fù)制,廣泛用在各種對MySQL有更高性能、更高可靠性要求的場合。與之對應(yīng)的是另一個同步技術(shù)是MySQL Cluster,但因為MySQL Cluster配置比較復(fù)雜,所以使用者較少。
MySQL Replication 就是從服務(wù)器拉取主服務(wù)器上的 二進(jìn)制日志文件,然后再將日志文件解析成相應(yīng)的SQL語句在從服務(wù)器上重新執(zhí)行一遍主服務(wù)器的操作,通過這種方式來保證數(shù)據(jù)的一致性。
MySQL的Replication是一個異步復(fù)制的過程(mysql5.1.7以上版本分為異步復(fù)制和半同步兩種模式),它是從一個Mysql instance(instance英文為實例)(我們稱之為Master)復(fù)制到另一個Mysql instance(我們稱之slave)。
3.3、三個線程
在master與slave之間實現(xiàn)整個復(fù)制過程主要由三個線程來完成:
1、Slave SQL thread線程,在slave端
2、Slave I/O thread線程,在slave端
3、Binlog dump thread線程(也可稱為IO線程),在master端 1 2 3 注意:如果一臺主服務(wù)器配兩臺從服務(wù)器那主服務(wù)器上就會有兩個Binlog dump 線程,而每個從服務(wù)器上各自有兩個線程。
要實現(xiàn)MySQL的Replication,首先必須打開master端的binlog(mysql-bin.xxxxxx)日志功能,否則無法實現(xiàn)mysql的主從復(fù)制。因為mysql的整個主從復(fù)制過程實際上就是:slave端從master端獲取binlog日志,然后再在自己身上完全順序的執(zhí)行該日志中所記錄的各種SQL操作。有關(guān)具體如何開啟mysql的binlog日志功能,請大家自己在網(wǎng)上搜。
3.4、主從復(fù)制流程
MySQL主從復(fù)制的基本交互過程,如下:
1、slave端的IO線程連接上master端,并請求從指定binlog日志文件的指定pos節(jié)點位置(或者從最開始的日志)開始復(fù)制之后的日志內(nèi)容。
2、master端在接收到來自slave端的IO線程請求后,通知負(fù)責(zé)復(fù)制進(jìn)程的IO線程,根據(jù)slave端IO線程的請求信息,讀取指定binlog日志指定pos節(jié)點位置之后的日志信息,然后返回給slave端的IO線程。該返回信息中除了binlog日志所包含的信息之外,還包括本次返回的信息在master端的binlog文件名以及在該binlog日志中的pos節(jié)點位置。
3、slave端的IO線程在接收到master端IO返回的信息后,將接收到的binlog日志內(nèi)容依次寫入到slave端的relaylog文件(mysql-relay-bin.xxxxxx)的最末端,并將讀取到的master端的binlog文件名和pos節(jié)點位置記錄到master-info(該文件存slave端)文件中,以便在下一次讀取的時候能夠清楚的告訴master“我需要從哪個binlog文件的哪個pos節(jié)點位置開始,請把此節(jié)點以后的日志內(nèi)容發(fā)給我”。
4、slave端的SQL線程在檢測到relaylog文件中新增內(nèi)容后,會馬上解析該log文件中的內(nèi)容。然后還原成在master端真實執(zhí)行的那些SQL語句,并在自身按順豐依次執(zhí)行這些SQL語句。這樣,實際上就是在master端和slave端執(zhí)行了同樣的SQL語句,所以master端和slave端的數(shù)據(jù)完全一樣的。
以上mysql主從復(fù)制交互過程比較拗口,理解起來也比較麻煩,我簡化了該交互過程。如下:
1、master在執(zhí)行sql之后,記錄二進(jìn)制log文件(bin-log)。
2、slave連接master,并從master獲取binlog,存于本地relay-log中,然后從上次記住的位置起執(zhí)行SQL語句,一旦遇到錯誤則停止同步。
從以上mysql的Replication原理可以看出:
主從間的數(shù)據(jù)庫不是實時同步,就算網(wǎng)絡(luò)連接正常,也存在瞬間主從數(shù)據(jù)不一致的情況。
如果主從的網(wǎng)絡(luò)斷開,則從庫會在網(wǎng)絡(luò)恢復(fù)正常后,批量進(jìn)行同步。
如果對從庫進(jìn)行修改數(shù)據(jù),那么如果此時從庫正在在執(zhí)行主庫的bin-log時,則會出現(xiàn)錯誤而停止同步,這個是很危險的操作。所以一般情況下,我們要非常小心的修改從庫上的數(shù)據(jù)。
一個衍生的配置是雙主、互為主從配置,只要雙方的修改不沖突,則可以工作良好。
如果需要多主庫的話,可以用環(huán)形配置,這樣任意一個節(jié)點的修改都可以同步到所有節(jié)點。
3.5、整體過程就是:
MySQL 復(fù)制基于主服務(wù)器在二進(jìn)制日志中跟蹤所有對數(shù)據(jù)庫的更改(更新、刪除等等)。每個從服務(wù)器從主服務(wù)器接收主服務(wù)器已經(jīng)記錄到其二進(jìn)制日志的保存的更新,以便從服務(wù)器可以對其數(shù)據(jù)拷貝執(zhí)行相同的更新。將主服務(wù)器的數(shù)據(jù)拷貝到從服務(wù)器的一個途徑是使用LOAD DATA FROM MASTER語句。請注意LOAD DATA FROM MASTER目前只在所有表使用MyISAM存儲引擎的主服務(wù)器上工作。并且,該語句將獲得全局讀鎖定。
MySQL 使用3個線程來執(zhí)行復(fù)制功能,其中1個在主服務(wù)器上,另兩個在從服務(wù)器上。當(dāng)發(fā)出START SLAVE時,從服務(wù)器創(chuàng)建一個I/O線程,以連接主服務(wù)器并讓它發(fā)送記錄在其二進(jìn)制日志中的語句。
主服務(wù)器創(chuàng)建一個線程,即I/O線程,將二進(jìn)制日志中的內(nèi)容發(fā)送到從服務(wù)器。該線程可以識別為主服務(wù)器上SHOW PROCESSLIST的輸出中的Binlog Dump線程。
從服務(wù)器I/O線程讀取主服務(wù)器Binlog Dump線程發(fā)送的內(nèi)容并將該數(shù)據(jù)拷貝到從服務(wù)器數(shù)據(jù)目錄中的本地文件中,即中繼日志。
第3個線程是SQL線程,是從服務(wù)器創(chuàng)建用于讀取中繼日志并執(zhí)行日志中包含的更新。
有多個從服務(wù)器的主服務(wù)器創(chuàng)建為每個當(dāng)前連接的從服務(wù)器創(chuàng)建一個線程;每個從服務(wù)器有自己的I/O和SQL線程。
四、MySQL支持的復(fù)制類型及其優(yōu)缺點
bin-log 日志文件有兩種格式,一種是Statement-Based,另一種是Row-Based。
(1):基于語句的復(fù)制(Statement-Based): 在主服務(wù)器上執(zhí)行的SQL語句,在從服務(wù)器上執(zhí)行同樣的語句。MySQL默認(rèn)采用基于語句的復(fù)制,效率比較高。一旦發(fā)現(xiàn)沒法精確復(fù)制時,會自動選著基于行的復(fù)制。
(2):基于行的復(fù)制(Row-Based):把改變的內(nèi)容復(fù)制過去,而不是把命令在從服務(wù)器上執(zhí)行一遍.從mysql5.0開始支持
(3):混合類型的復(fù)制: 默認(rèn)采用基于語句的復(fù)制,一旦發(fā)現(xiàn)基于語句的無法精確的復(fù)制時,就會采用基于行的復(fù)制。
4.1、Statement-Based優(yōu)點和缺點分析
優(yōu)點
bin-log日志包含了描述數(shù)據(jù)庫操作的事件,但是這些事件包含的情況只是對數(shù)據(jù)庫進(jìn)行改變的操作,例如 insert、update、create、delete等操作。相反對于select、desc等類似的操作并不會去記錄,并且它記錄的是語句,所以相對于Row-Based來說這樣會占用更少的存儲空間。
因為bin-log日志文件記錄了所有的改變數(shù)據(jù)庫的語句,所以此文件可以作為以后的數(shù)據(jù)庫的審核依據(jù)
缺點
不安全,并不是所有的改變數(shù)據(jù)的語句都會被記錄復(fù)制。任何的非確定性的行為都是很難被記錄復(fù)制的。
例如:對于delete 或者update語句,如果使用了limit但是并沒有 order by,這就屬于非確定性的語句,就不會被記錄
對于沒有索引條件的update語句,必須鎖定更多的數(shù)據(jù),降低了數(shù)據(jù)庫的性能。
insert……select 語句同樣也需要鎖定大量的數(shù)據(jù),對數(shù)據(jù)庫的性能有所損耗。
獲取更詳細(xì)的信息可以參考官方文檔——Statement-Based的優(yōu)點和缺點
4.2、Row-Based優(yōu)點和缺點分析
優(yōu)點
所有的改變都會被復(fù)制,這是最安全的復(fù)制方式
對于 update、insert……select等語句鎖定更少的行
此種方式和大多數(shù)的數(shù)據(jù)庫系統(tǒng)一樣,所以了解其他的系統(tǒng)的人員可以很容易的轉(zhuǎn)到mysql 缺點
使用不方便,我們不能通過bin-log日志文件查看什么語句執(zhí)行了,也無從知道在從服務(wù)器上接收到什么語句,我們只能看到什么數(shù)據(jù)改變了
因為記錄的是數(shù)據(jù),所以說bin-log日志文件占用的存儲空間要比Statement-based大。
對于數(shù)據(jù)量大的操作其花費的時間有更長
獲取更詳細(xì)的信息可以參考官方文檔——Row-Based的優(yōu)點和缺點
bin-log日志文件默認(rèn)的格式為Statement-Based,如果想改變其格式在開啟服務(wù)的時候使用—binlog-format選項,其具體命令如下
mysqld_safe –user=msyql –binlog-format=格式 & 1
四、主服務(wù)器流程分析
4.1、主服務(wù)器線程 Binlog dump thread
Binlog dump 線程是當(dāng)有從服務(wù)器連接的時候由主服務(wù)器創(chuàng)建,其大致工作過程經(jīng)歷如下幾個階段:
首先bin-log日志文件加鎖,然后讀取更新的操作,讀取完畢以后將鎖釋放掉,最后將讀取的記錄發(fā)送給從服務(wù)器。
我們可以使用如下的命令來查看該線程的信息
mysql> SHOW PROCESSLISTG 1 以我的系統(tǒng)為例,因為我這系統(tǒng)中是一臺主服務(wù)器和兩臺從服務(wù)器,所以會列出兩條Binlog dump線程的信息
*************************** 1.row ***************************
Id: 2
User: repuser
Host: 192.168.144.131:41544
db: NULL Command: Binlog Dump
Time: 54
State: Master has sent all binlog to slave;waiting for binlog to be updated
Info: NULL *************************** 2.row ***************************
Id: 3
User: repuser
Host: 192.168.144.132:40888
db: NULL Command: Binlog Dump
Time: 31
State: Master has sent all binlog to slave;waiting for binlog to be updated
Info: NULL
上述字段中的state字段會有以下幾種狀態(tài):
1.Sending binlog event to slave 表示Binlog dump 線程已經(jīng)讀取完binlog日志中更新的event,現(xiàn)在正在發(fā)送給從服務(wù)器
2.Finished reading one binlog;switching to next binlog 表示Binlog dump 線程已經(jīng)讀取完一個binlog日志,現(xiàn)在正在打開下一個binlog日志讀取來發(fā)送給從服務(wù)器
3.Master has sent all binlog to slave;waiting for binlog to be updated 這就是上面我們看到的state的值,表示Binlog dump 線程已經(jīng)讀取完所有的binlog日志文件,并且將其發(fā)送給了從服務(wù)器。現(xiàn)在處于空閑狀態(tài),正在等待讀取有新的操作的binlog日志文件
4.Waiting to finalize termination 這個狀態(tài)持續(xù)的很短暫,我們幾乎看不到。當(dāng)線程停止的時候顯示此狀態(tài)
上述幾個狀態(tài)就是一次主從復(fù)制過程中Binlog dump 線程所經(jīng)歷的狀態(tài),如果我們是在測試的環(huán)境中,上述1、2、4狀態(tài)我們幾乎是看不到的,因為它執(zhí)行的很快。
在主從系統(tǒng)中主服務(wù)器上的一個主要的文件就是bin-log日志,該線程操作的文件也是此日志文件,因此這是我們需要在配置文件my.cnf 中打開bin-log日志的原因,使用此文件來記錄我們的更新操作。
[mysqld] log-bin = mysql-bin server-id = 1 1 2 3 還有一點需要注意,在上面已經(jīng)說過,但是在這里覺得有必要再重復(fù)一遍,就是有多少個從服務(wù)器連接主服務(wù)器上就有多少個Binlog dump 線程。
bin-log日志文件管理
對于bin-log日志文件,其默認(rèn)的名稱為 mysql-bin.xxxxxx。而且還有一個索引文件mysql-bin.index,其中記錄了當(dāng)前所有的bin-log日志文件。
對于新的主服務(wù)器只有一個bin-log日志文件 mysql-bin.000001。此時所有的操作都有這個文件來記錄,如果我們想更換bin-log日志文件,可以使用如下命令
Mysql>flush logs;1 2 此時會創(chuàng)建一個mysql-bin.000002文件來記錄以后的操作。除了使用上述命令以外,當(dāng)bin-log日志文件達(dá)到其最大值的時候也會產(chǎn)生新的bin-log日志文件
其文件最大值和文件名包括索引文件的名稱可以使用 –max_binlog_size、–log-bin和—log-bin-index 選項來改變,具體命令如下
mysqld_safe –user=msyql –max_binlog_size=文件長度 –log-bin=新的日志文件名稱 –log-bin-index=新索引文件名 & 1 對于主服務(wù)器來說,總起來一句話:主服務(wù)器針對于每一個從服務(wù)器都創(chuàng)建一個Binlog dump線程,用來讀取bin-log日志中更新的操作將其發(fā)送給從服務(wù)器,發(fā)送完畢以后繼續(xù)等待bin-log日志是否有更新。
五、從服務(wù)器流程分析
在主服務(wù)器探究這篇文章中我們提到過,在一次主從復(fù)制過程中需要用到三個線程:Binlog dump 線程、Slave I/O 線程和Slave SQL線程,其中Binlog dump 線程在主服務(wù)器上面,剩下的兩個線程是在從服務(wù)器上面工作的。
這兩個線程在從服務(wù)器上面的工作流程如下圖所示:
對于這兩個線程隨著從服務(wù)器開啟slave而產(chǎn)生
mysql> START SLVAE;
然后使用
Mysql> SHOW SLAVE STATUSG 1 查看這兩個線程情況 ……
Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 1264 Relay_Log_File: localhost-relay-bin.000002 Relay_Log_Pos: 878 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes ……
上面結(jié)果中的 Slave_IO_Running:Yes和Slave_SQL_Running:Yes表示這兩個線程正在運行。
然后我們在從服務(wù)器上面使用命令
mysql> SHOW PROCESSLIATG 1 顯示如下結(jié)果(記為 結(jié)果一)
*************************** 1.row ***************************
Id: 22
User: system user
Host:
db: NULL Command: Connect
Time: 4
State: Waiting for master to send event
Info: NULL *************************** 2.row ***************************
Id: 23
User: system user
Host:
db: NULL Command: Connect
Time: 4
State: Slave has read all relay log;waiting for the slave I/O thread to update it
Info: NULL
從State信息可以看出Id 22是I/O線程,正在等待主服務(wù)器發(fā)送更新的內(nèi)容;Id 23是Slave SQL線程,已經(jīng)讀取了relay log 文件中所有更新的內(nèi)容,正在等待I/O線程更新該文件。
使用命令停止slave機制
mysql> STOP SLVAE;1 然后我們再次查看會發(fā)現(xiàn)結(jié)果如下
……
Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 1264 Relay_Log_File: localhost-relay-bin.000002 Relay_Log_Pos: 878 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: No Slave_SQL_Running: No ……
說明這兩個線程已經(jīng)停止了運行。此時再次使用 SHOW PROCESSLISTG命令,則沒有結(jié)果顯示
5.1、Slave I/O線程
Slave I/O 線程去連接主服務(wù)器的Binlog dump 線程并要求其發(fā)送binlog日志中記錄的更新的操作,然后它將Binlog dump 線程發(fā)送的數(shù)據(jù)拷貝到從服務(wù)器上(也就是本地)的文件relay log中。
當(dāng)然要查看此線程是否運行,除了上面介紹的方法,還可以使用
mysql> SHOW SLAVE LIKE ‘Slave_running’;1 這時如果出現(xiàn)下面的結(jié)果說明該線程正在運行
+-----------------+-------------------+ | Variable_name
| Value
| +-----------------+-------------------+ | Slave_running
| ON
| +-----------------+-------------------+
在上述結(jié)果一中我們可以看到1.row即是Slave I/O線程的信息,其State: Waiting for master to send event 表示正在等待主服務(wù)器發(fā)送內(nèi)容。當(dāng)然State不止這一個值,它還有其它的值,下面列出了State的所有的值
1.Waiting for master update 在連接到主服務(wù)器之前的初始狀態(tài)
2.Connecting to master 該線程正在連接主服務(wù)器,當(dāng)然如果我們的網(wǎng)絡(luò)環(huán)境優(yōu)異的話,此狀態(tài)我們幾乎是看不到的 3.Checking master version 這個狀態(tài)發(fā)生的時間也非常短暫,該狀態(tài)在該線程和主服務(wù)器建立連接之后發(fā)生。
4.Registering slave on master 在主服務(wù)器上面注冊從服務(wù)器,每當(dāng)有新的從服務(wù)器連接進(jìn)來以后都要在主服務(wù)器上面進(jìn)行注冊
5.Requesting binlog dump 向主服務(wù)器請求binlog日志的拷貝
6.Waiting to reco004km.cnnnect after a failed binlog dump request 如果5中失敗,則該線程進(jìn)入睡眠狀態(tài),此時State就是這個值,等待著去定期重新連接主服務(wù)器,那這個周期的大小可以通過CHANGE MASTER TO 來指定
7.Reconnecting after a failed binlog dump request 去重新連接主服務(wù)器
8.Waiting for master to send event 此值就是我們上述結(jié)果所顯示的,正常情況下我們查看的時候一般都是這個值。其具體表示是這個線程已經(jīng)和主服務(wù)器建立了連接,正在等待主服務(wù)器上的binlog 有更新,如果主服務(wù)器的Binlog dump線程一直是空閑的狀態(tài)的話,那此線程會等待很長一段時間。當(dāng)然也不是一直等待下去,如果時間達(dá)到了slave_net_timeout規(guī)定的時間,會發(fā)生等待超時的情況,在這種情況下I/O線程會重新去連接主服務(wù)器
9.Queueing master event to the relay log 該線程已經(jīng)讀取了Binlog dump線程發(fā)送的一個更新事件并且正在將其拷貝到relay log文件中
10.Waiting to reconnect after a failed master event read 當(dāng)該線程讀取Binlog dump 線程發(fā)送的更新事件失敗時,該線程進(jìn)入睡眠狀態(tài)等待去重新連接主服務(wù)器,這個等待的時間默認(rèn)是60秒,當(dāng)然這個值也可以通過CHANGE MASTER TO來設(shè)置
11.Reconnecting after a failed master event read 該線程去重新連接主服務(wù)器,當(dāng)連接成功以后,那這個State的值會改變?yōu)?Waiting for master to send event
12.Waiting for the Slave SQL thread to free enough relay log space relay log space的大小是通過relay_log_space_limit來設(shè)定的,隨著relay logs變得越來越大所有的大小合起來會超過這個設(shè)定值。這時該線程會等待SQL線程釋放足夠的空間刪除一些relay log文件
13.Waiting for slave mutex on exit 當(dāng)線程停止的時候會短暫的出現(xiàn)該情況
以上就是State可能會出現(xiàn)的值,以及都是在什么情況下出現(xiàn)。
5.2、Slave SQL線程
Slave SQL線程是在從服務(wù)器上面創(chuàng)建的,主要負(fù)責(zé)讀取由Slave I/O寫的relay log文件并執(zhí)行其中的事件。
在上述結(jié)果一中2.row即是Slave SQL線程的信息,同樣有一個State表示該線程的當(dāng)前狀態(tài)。
下面也列出了State所有可能出現(xiàn)的情況。
1.Waiting for the next event in relay log 該狀態(tài)是讀取relay log之前的初始狀態(tài) 2.Reading event from the relay log 該狀態(tài)表示此線程已經(jīng)在relay log中讀取了一個事件準(zhǔn)備執(zhí)行 3.Making temp file 該狀態(tài)表示此線程正在執(zhí)行LOAD_DATA_INFILE并且正在創(chuàng)建一個臨時文件來保存從服務(wù)器將要讀取的數(shù)據(jù)
4.Slave has read all relay log;waiting for the slave I/O thread to update it 該線程已經(jīng)處理完了relay log中的所有事件,現(xiàn)在正在等待slave I/O線程更新relay log文件
5.Waiting for slave mutex on exit 當(dāng)線程停止的時候會短暫的出現(xiàn)該情況
上面是對從服務(wù)器上的兩個線程的簡單的介紹,在運行過程中我們會發(fā)現(xiàn)這兩個線程都離不開的文件就是relay log文件,下面我們簡單介紹一下relay log文件。
5.3、relay log文件
relay log 和 主服務(wù)器上的bin log很相似,都是一系列的文件,這些文件包括那些包含描述數(shù)據(jù)庫改變的操作事件的文件和索引文件,這個索引文件是relay logs文件的名稱集合。
relay log 文件和 bin log文件一樣,也是二進(jìn)制文件,不能直接查看,需要使用mysql自帶工具mysqlbinlog查看。
] # mysqlbinlog mysql安裝路徑/data/relay-log文件
當(dāng)然其索引文件的內(nèi)容我們是可以直接使用 vim查看的。
對于relay logs 文件的名稱的命名規(guī)則默認(rèn)使用的是 host_name-relay-bin.nnnnnn,以我的系統(tǒng)來說,其文件名默認(rèn)為localhost-relay-bin.000001。對于索引文件的命名規(guī)則為host_name-relay-bin.index,同樣在我的系統(tǒng)中的名稱為localhost-relay-bin.index。這兩個名稱是可以通過—relay-log 和 –relay-log-index來改變的,其使用方式如下:
mysqld_safe –user=mysql –relay-log=文件名 –relay-log-index=新索引文件名 & 1 在這里如果改變這兩個名稱的話,可能會引起‘不能打開relay log’文件和‘在初始化relay log 過程中不能發(fā)現(xiàn)目標(biāo)log’等錯誤。這也算是mysql設(shè)計的一個bug,沒有什么好的解決辦法,如果我們不想使用默認(rèn)的文件名稱的話,唯一的辦法就是我們可以預(yù)料到從服務(wù)器的主機名稱可能在將來會發(fā)生改變,在開始初始化從服務(wù)器的時候就使用以上兩個選項指定文件名,這樣就可以使文件名不再依賴于服務(wù)器的主機名。
對于這些relay log文件并不是一直在增加的,當(dāng)Slave SQL線程執(zhí)行完一個relay log文件中所有的事件并且不再需要它的時候會把改relay log文件刪除。由于是Slave SQL線程來做這些事情,所以也沒有什么明確的規(guī)則來指定如何刪除relay log文件
以上的所有內(nèi)容大概描述了主從復(fù)制系統(tǒng)中從服務(wù)器的主要工作流程。
六、如何提高M(jìn)ysql主從復(fù)制的效率?
MySQL的主從復(fù)制,實際上就是Master記錄自己的執(zhí)行日志binlog,然后發(fā)送給Slave,Slave解析日志并執(zhí)行,來實現(xiàn)數(shù)據(jù)復(fù)制。對于復(fù)制效率,binlog的大小是非常重要的因素,因為它涉及了I/O和網(wǎng)絡(luò)傳輸
主從復(fù)制涉及到了兩端:master/slave,看下這兩端可以如何優(yōu)化
(1)master 端
master端有2個參數(shù)可以控制
Binlog_Do_DB : 設(shè)定哪些數(shù)據(jù)庫需要記錄Binlog
Binlog_Ignore_DB : 設(shè)定哪些數(shù)據(jù)庫不要記錄Binlog
這兩項很重要,指定必要數(shù)據(jù)庫,忽略不需要復(fù)制的數(shù)據(jù)庫,可以減少binlog的大小,提高了I/O效率,加快網(wǎng)絡(luò)傳輸。
但這兩項也同樣比較危險,需要謹(jǐn)慎使用,因為可能會有主從數(shù)據(jù)不一致和復(fù)制出錯的風(fēng)險。
因為MySQL判斷是否須要復(fù)制某個Event,不是根據(jù)產(chǎn)生該Event的語句所在的數(shù)據(jù)庫,而是根據(jù)執(zhí)行時所在的默認(rèn)數(shù)據(jù)庫,也就是登錄時指定的數(shù)據(jù)庫,或運行“USE DATABASE”中所指定的數(shù)據(jù)庫。
如果執(zhí)行語句中明確指定了數(shù)據(jù)庫名稱,而這個數(shù)據(jù)庫是被指定不記錄Binlog的,那么這個語句在slave中執(zhí)行時就會出錯。例如
garbage 庫是被指定不記錄日志的
product 庫是指定要記錄日志的 1 2 3 執(zhí)行下面的語句
use product;delete from garbage.junk;1 2 delete語句會被發(fā)送給slave,但slave中沒有g(shù)arbage庫,所以執(zhí)行時報錯,復(fù)制失敗
(2)slave 端
slave端有6個參數(shù)可以控制
Replicate_Do_DB : 設(shè)定須要復(fù)制的數(shù)據(jù)庫,多個DB用逗號分隔
Replicate_Ignore_DB : 設(shè)定可以忽略的數(shù)據(jù)庫
Replicate_Do_Table : 設(shè)定須要復(fù)制的Table
Replicate_Ignore_Table : 設(shè)定可以忽略的Table
Replicate_Wild_Do_Table : 功能同Replicate_Do_Table,但可以帶通配符來進(jìn)行設(shè)置
Replicate_Wild_Ignore_Table : 功能同Replicate_Ig-nore_Table,可帶通配符設(shè)置
slave端的配置優(yōu)化效果要明顯小于master端的,因為master端日志都寫完了,日志也傳過來了
但這幾個參數(shù)可以幫助我們減少日志的應(yīng)用量,因為設(shè)置了過濾,實際寫入的sql數(shù)量變少了,slave端的復(fù)制也就加快了