一、半同步復制原理介紹
1. 優點
當事務返回客戶端成功后,則日志一定在至少兩台主機上存在。
MySQL在加載並開啟Semi-sync插件后,每一個事務需等待備庫接收日志后才返回給客戶端。如果做的是小事務,兩台主機的延遲又較小,則Semi-sync可以實現在性能很小損失的情況下的零數據丟失。
2. 缺點
完成單條事務增加了額外的等待延遲,延遲的大小取決於網絡的好壞。
Semi-sync不是分布式事務,主庫會在自己完成事務后,等待備庫接收事務日志。
3. 主機Crash時的處理
備庫Crash時,主庫會在某次等待超時后,關閉Semi-sync的特性,降級為普通的異步復制,這種情況比較簡單。
主庫Crash后,那么可能存在一些事務已經在主庫Commit,但是還沒有傳給任何備庫,我們姑且稱這類事務為"牆頭事務"。"牆頭事務"都是沒有返回給客戶端的,所以發起事務的客戶端並不知道這個事務是否已經完成。
這時,如果客戶端不做切換,只是等Crash的主庫恢復后,繼續在主庫進行操作,客戶端會發現前面的"牆頭事務"都已經完成,可以繼續進行后續的業務處理;另一種情況,如果客戶端Failover到備庫上,客戶端會發現前面的“牆頭事務”都沒有成功,則需要重新做這些事務,然后繼續進行后續的業務處理。
4. 其他
可以做多個備庫,任何一個備庫接收完成日志后,主庫就可以返回給客戶端了。
網絡傳輸在並發線程較多時,一次可能傳輸很多日志,事務的平均延遲會降低。
"牆頭事務"在牆頭上的時候,是可以被讀取的,但是這些事務在上面Failover的場景下,是被認為沒有完成的。
5. 半同步復制插件安裝
1. 安裝
-------------------------------------
在master上安裝master插件:
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
在slave上安裝slave插件;
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
2. 必須同時兩端激活
-------------------------------------
在運行時:
在master上執行:
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1; mysql> SET GLOBAL rpl_semi_sync_master_timeout = 3000;
在slave上執行:
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1; mysql> STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;
3. 監視
-------------------------------------
看配置
SHOW VARIABLES LIKE 'rpl_semi_sync%';
看狀態:
SHOW STATUS LIKE 'rpl_semi_sync%';
二、主從復制原理介紹
一、MySQL復制概述
MySQL支持單向、異步復制,復制過程中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。MySQL復制基於主服務器在二進制日志中跟蹤所有對數據庫的更改(更新、刪除等等)。因此,要進行復制,必須在主服務器上啟用二進制日志。每個從服務器從主服務器接收主服務器上已經記錄到其二進制日志的保存的更新。當一個從服務器連接主服務器時,它通知主服務器定位到從服務器在日志中讀取的最后一次成功更新的位置。從服務器接收從那時起發生的任何更新,並在本機上執行相同的更新。然后封鎖並等待主服務器通知新的更新。從服務器執行備份不會干擾主服務器,在備份過程中主服務器可以繼續處理更新。
二、復制實現細節
MySQL使用3個線程來執行復制功能,其中兩個線程(Sql線程和IO線程)在從服務器,另外一個線程(IO線程)在主服務器。當發出START SLAVE時,從服務器創建一個I/O線程,以連接主服務器並讓它發送記錄在其二進制日志中的語句。主服務器創建一個線程將二進制日志中的內容發送到從服務器。該線程可以即為主服務器上SHOW PROCESSLIST的輸出中的Binlog Dump線程。從服務器I/O線程讀取主服務器Binlog Dump線程發送的內容並將該數據拷貝到從服務器數據目錄中的本地文件中,即中繼日志。第3個線程是SQL線程,由從服務器創建,用於讀取中繼日志並執行日志中包含的更新。在從服務器上,讀取和執行更新語句被分成兩個獨立的任務。當從服務器啟動時,其I/O線程可以很快地從主服務器索取所有二進制日志內容,即使SQL線程執行更新的遠遠滯后。
1、復制線程狀態
通過show slave status\G和show master status可以查看復制線程狀態。常見的線程狀態有:
(1)主服務器Binlog Dump線程
Has sent all binlog to slave; waiting for binlog to be updated
線程已經從二進制日志讀取所有主要的更新並已經發送到了從服務器。線程現在正空閑,等待由主服務器上新的更新導致的出現在二進制日志中的新事件。
(2)從服務器I/O線程狀態
Waiting for master to send event
線程已經連接上主服務器,正等待二進制日志事件到達。如果主服務器正空閑,會持續較長的時間。如果等待持續slave_read_timeout秒,則發生超時。此時,線程認為連接被中斷並企圖重新連接。
(3)從服務器SQL線程狀態
Reading event from the relay log
線程已經從中繼日志讀取一個事件,可以對事件進行處理了。
Has read all relay log; waiting for the slave I/O thread to update it
線程已經處理了中繼日志文件中的所有事件,現在正等待I/O線程將新事件寫入中繼日志。
2、復制過程中使用的傳遞和狀態文件
默認情況,中繼日志使用host_name-relay-bin.nnnnnn形式的文件名,其中host_name是從服務器主機名,nnnnnn是序列號。中繼日志與二進制日志的格式相同,並且可以用mysqlbinlog讀取。
從服務器在data目錄中另外創建兩個小文件。這些狀態文件默認名為主master.info和relay-log.info。狀態文件保存在硬盤上,從服務器關閉時不會丟失。下次從服務器啟動時,讀取這些文件以確定它已經從主服務器讀取了多少二進制日志,以及處理自己的中繼日志的程度。
如果要備份從服務器的數據,還應備份這兩個小文件以及中繼日志文件。它們用來在恢復從服務器的數據后繼續進行復制。如果丟失了中繼日志但仍然有relay-log.info文件,可以通過檢查該文件來確定SQL線程已經執行的主服務器中二進制日志的程度。然后可以用Master_Log_File和Master_LOG_POS選項執行CHANGE MASTER TO來告訴從服務器重新從該點讀取二進制日志。
三、主從復制的配置方法
1. 在master創建復制用戶
grant replication slave on *.* to 'replication'@'192.168.1.%' identified by '000000'; flush privileges;
2. 修改master的配置文件,開啟binlog日志和設置需要復制的數據庫
[mysqld] server-id = 1 log-bin=/opt/mysql/binlog/mysql-bin binlog_do_db=db1 binlog_ignore_db=mysql binlog_format=mixed
3. 修改slave 配置,指定需要復制的數據庫和relaylog的路徑
[mysqld] server-id = 2 replicate-do-db=db1 replicate-ignore-db = mysql,information_schema relay-log=/opt/mysql/data/mysqlb-relay-bin relay-log-index=/opt/mysql/data/mysqlb-relay-bin.index
4. 重啟master和slave數據庫服務器
5. 在master上執行
mysql>flush tables with read lock;
mysql>show master status\G
*************************** 1. row ***************************
File: binlog.000006
Position: 107
Binlog_Do_DB: test
Binlog_Ignore_DB: mysql
1 row in set (0.00 sec)
mysql>unlock tables;
注:這里鎖表的目的是為了生產環境中不讓進新的數據,好讓從服務器定位同步位置。初次同步完成后,記得解鎖。
6. 在slave上,使用change master指向同步位置
mysql>change master to master_host='192.168.1.106',master_port=3307, master_user='replication', master_password='000000', master_log_file='binlog.000006', master_log_pos=107;
注:master_log_file,master_log_pos由上面主服務器查出的狀態值中確定。master_log_file對應File,master_log_pos對應Position。mysql 5.x以上版本已經不支持在配置文件中指定主服務器相關選項。
7. 啟動從服務器復制線程
mysql>start slave;
原文鏈接 http://haiker.iteye.com/blog/1632697
