MySQL復(fù)制:
- 擴(kuò)展方式:
- Scale up,向上擴(kuò)展;使用更好更高級(jí)性能的硬件;
- Scale Out,向外擴(kuò)展;增加更多的主機(jī)
- MySQL的擴(kuò)展:
- 復(fù)制:復(fù)制是mysql向外擴(kuò)展的解決方案,每個(gè)節(jié)點(diǎn)都有相同的數(shù)據(jù)集;結(jié)構(gòu)通常是主從復(fù)制結(jié)構(gòu);工作方式就是讓從節(jié)點(diǎn)通過(guò)向主節(jié)點(diǎn)請(qǐng)求二進(jìn)制日志中的事件于本地,并執(zhí)行replay完成;復(fù)制默認(rèn)是單向進(jìn)行的;
- 主從復(fù)制:mysql的從節(jié)點(diǎn)不接收任何修改操作的請(qǐng)求,而僅僅把自己扮演成客戶端,向主服務(wù)器請(qǐng)求主服務(wù)器上所有的數(shù)據(jù)修改,并在本地replay一遍,從而實(shí)現(xiàn)跟主服務(wù)器一模一樣的數(shù)據(jù)集;在這個(gè)數(shù)據(jù)集上可以接受其他用戶的讀請(qǐng)求;但不接收寫請(qǐng)求,這就叫做mysql的主從復(fù)制;
- 為什么要做mysql復(fù)制?完成數(shù)據(jù)分布的目的;例如,更多用戶查詢;
- 冗余:既然能完成冗余就能提升高可用性能,可寫腳本檢測(cè)主從節(jié)點(diǎn)當(dāng)中,主節(jié)點(diǎn)的可靠性,一旦發(fā)現(xiàn)主節(jié)點(diǎn)故障,將主節(jié)點(diǎn)下線,自動(dòng)提升從節(jié)點(diǎn)為主節(jié)點(diǎn),所以就完成了故障切換,從而實(shí)現(xiàn)高可用功能;
市面有很多實(shí)現(xiàn)高可用解決方案,就是通過(guò)這種方式實(shí)現(xiàn)的; - 負(fù)載均衡:主節(jié)點(diǎn)接受所有的寫操作,并且把寫操作又同步給從節(jié)點(diǎn)一份,所以,從節(jié)點(diǎn)也必須要完成同樣多的寫操作;因此,只能負(fù)載均衡讀請(qǐng)求;
- 支援安全的備份操作:當(dāng)主節(jié)點(diǎn)掛了,從節(jié)點(diǎn)迅速提升為主節(jié)點(diǎn);這是一種冗余功能;復(fù)制還能幫助完成備份;數(shù)據(jù)做冷備是最可靠的,冷備不可能在線上做但是最可靠的;而有了復(fù)制結(jié)構(gòu)以后,可以給主服務(wù)器配置一個(gè)從節(jié)點(diǎn),當(dāng)需要做備份時(shí),只需將從節(jié)點(diǎn)從主復(fù)制上給它下線,停止服務(wù),然后直接復(fù)制數(shù)據(jù)副本就ok了;輔助完成備份的;
- 測(cè)試:通過(guò)備份的方式,把數(shù)據(jù)放到新版的msyql服務(wù)器上測(cè)試;
- 冗余:既然能完成冗余就能提升高可用性能,可寫腳本檢測(cè)主從節(jié)點(diǎn)當(dāng)中,主節(jié)點(diǎn)的可靠性,一旦發(fā)現(xiàn)主節(jié)點(diǎn)故障,將主節(jié)點(diǎn)下線,自動(dòng)提升從節(jié)點(diǎn)為主節(jié)點(diǎn),所以就完成了故障切換,從而實(shí)現(xiàn)高可用功能;
MySQL主從復(fù)制

工作模式:
主節(jié)點(diǎn)(master)必須啟用二進(jìn)制日志,所有的寫操作除了保存在數(shù)據(jù)中一份之外,還會(huì)在本地的二進(jìn)制日志中將能夠修改數(shù)據(jù)或潛在有可能修改數(shù)據(jù)的語(yǔ)句記錄在二進(jìn)制日志文件中一份;
從節(jié)點(diǎn)(slave)啟動(dòng)一個(gè)專門的線程,把自己扮演成mysql客戶端,通過(guò)mysql協(xié)議向mysql服務(wù)器請(qǐng)求讀取對(duì)方二進(jìn)制日志中的事件,服務(wù)器端會(huì)檢查自己二進(jìn)制日志中的事件跟對(duì)方請(qǐng)求的位置(對(duì)方會(huì)指明請(qǐng)求二進(jìn)制日志中的事件),于是服務(wù)器會(huì)從自己的二進(jìn)制日志中根據(jù)請(qǐng)求者指定的位置,如果請(qǐng)求者不能指定就從第一個(gè)文件的最開始處開始,把一個(gè)個(gè)事件發(fā)送給從節(jié)點(diǎn)。
從節(jié)點(diǎn)收到后,每讀到一個(gè)事件,先保存在中繼日志中,保存完成后還會(huì)用一個(gè)文件記錄已經(jīng)讀到了主節(jié)點(diǎn)哪個(gè)二進(jìn)制日志的哪個(gè)位置,索引下次請(qǐng)求時(shí),就會(huì)告訴主節(jié)點(diǎn)自己讀到哪個(gè)位置了,從該位置之后是否產(chǎn)生新事件,如果有,主節(jié)點(diǎn)又會(huì)繼續(xù)發(fā)送事件給從節(jié)點(diǎn)。
從節(jié)點(diǎn)不斷的向主節(jié)點(diǎn)發(fā)送這種請(qǐng)求,讓主節(jié)點(diǎn)檢索有沒(méi)有新事件,如果有的話,主節(jié)點(diǎn)需要啟動(dòng)一個(gè)叫做mysqldump線程,dump它能夠從二進(jìn)制日志文件中,把事件讀出來(lái),并響應(yīng)給從節(jié)點(diǎn);
從節(jié)點(diǎn)得到事件后保存在中繼日志中,目的是在本地replay一遍,因此,在本地還要啟動(dòng)一個(gè)叫sql thread 的線程,負(fù)責(zé)從中級(jí)日志中讀一個(gè)事件然后在本地執(zhí)行一遍,最終數(shù)據(jù)就保存在數(shù)據(jù)文件中;而負(fù)責(zé)從節(jié)點(diǎn)向主節(jié)點(diǎn)請(qǐng)求數(shù)據(jù)的線程叫做IO thread。
主從架構(gòu)類型:
- 異步復(fù)制:主節(jié)點(diǎn)收到寫操作后,只需要保證本地寫入完成,那么就立即返回給客戶端寫入操作完成,不用等待從服務(wù)器反饋寫入完成并在本地重放完成。
- 半同步復(fù)制:一個(gè)主節(jié)點(diǎn)有多個(gè)從節(jié)點(diǎn),主節(jié)點(diǎn)接收到請(qǐng)求以后,要至少等待一個(gè)從節(jié)點(diǎn)同步完成并告訴主節(jié)點(diǎn)數(shù)據(jù)存儲(chǔ)完成,主節(jié)點(diǎn)才返回客戶端結(jié)果,但從節(jié)點(diǎn)可有n個(gè),給余的從節(jié)點(diǎn)異步;一旦主節(jié)點(diǎn)掉線,至少能夠有一個(gè)從節(jié)點(diǎn)數(shù)據(jù)是完整的
- 一主多從
- 一主一從
- 級(jí)聯(lián)復(fù)制:一個(gè)節(jié)點(diǎn)首先是主節(jié)點(diǎn)的從,同時(shí)又是其它節(jié)點(diǎn)的主:
- 循環(huán)復(fù)制:每一個(gè)服務(wù)器都是下家的主服務(wù)器同時(shí)又是上家的從服務(wù)器;
- 雙柱復(fù)制
- 一從多主: 每個(gè)主服務(wù)器提供不同的數(shù)據(jù)庫(kù)
主從復(fù)制的落后原因:
事實(shí)上落后也有很大的好處,有時(shí)甚至需要專門落后一些時(shí)間;例如,一不小心刪除了數(shù)據(jù)庫(kù),這樣,從服務(wù)器落后主服務(wù)器就不用擔(dān)心,趕緊斷開從服務(wù)器,所有數(shù)據(jù)仍然不受影響,把從服務(wù)器切換為線上的主節(jié)點(diǎn)就OK了;
所以在有些場(chǎng)景中有意讓專門一臺(tái)從服務(wù)器落后與主服務(wù)器一段時(shí)間;
對(duì)非常繁忙的主節(jié)點(diǎn),由于主節(jié)點(diǎn)事務(wù)是可以并行的,就意味著很多事務(wù)是并行提交的,對(duì)數(shù)據(jù)庫(kù)本身沒(méi)什么問(wèn)題,因?yàn)楸镜赜袃?nèi)存,本地?cái)?shù)據(jù)文件有可能是分散的,因?yàn)楸镜剡€有可能有多個(gè)數(shù)據(jù)庫(kù),所以IO可以分散出去;但是,無(wú)論有多少本地事務(wù)提交的操作,有多少個(gè)寫語(yǔ)句,這些寫語(yǔ)句只能一個(gè)一個(gè)寫進(jìn)二進(jìn)制日志中;從這個(gè)角度認(rèn)為,一個(gè)非常繁忙的主節(jié)點(diǎn)必然的其本地的執(zhí)行速度要快于往二進(jìn)制日志中寫入的速度;這樣就可認(rèn)為從節(jié)點(diǎn)在復(fù)制的過(guò)程就更慢了,因此,這種落后也是必然的;有時(shí)從節(jié)點(diǎn)落后于主節(jié)點(diǎn)一兩個(gè)小時(shí)都很常見(jiàn);
主從配置過(guò)程:
(1) 時(shí)間同步;
(2)復(fù)制的開始位置;
從0開始;
從備份中恢復(fù)從節(jié)點(diǎn)后啟動(dòng)的復(fù)制,復(fù)制的起始點(diǎn)是備份操作時(shí)主節(jié)點(diǎn)所處的日志文件及其事件位置
(3) 中從服務(wù)器mysqld程序版本
從服務(wù)器版本號(hào)可以高于主的版本號(hào)
(4) 主節(jié)點(diǎn)配置
在mysql配置文件中添加:
[mysqld]
log_bin=mysql-bin #開啟二進(jìn)制日志
server_id=# #為當(dāng)前節(jié)點(diǎn)設(shè)置一個(gè)全局唯一的ID號(hào)
啟動(dòng)服務(wù)并創(chuàng)建有復(fù)雜權(quán)限的用戶賬號(hào):
需要有`REPLICATION SLAVE, REPLICATION CLIENT `兩種權(quán)限
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'USERNAME'@'HOST' IDENTIFIED BY 'PASSWORD';
mysql> FLUSH PRIVILEGES;
(5) 從節(jié)點(diǎn)配置
配置文件my.cnf
[mysqld]
server_id=#
relay_log=relay_log
read_only=ON
啟動(dòng)服務(wù):
mysql> CHANGE MASTER TO MASTER_HOST='HOST',MASTER_USER='USERNAME',MASTER_PASSWORD='PASSWORD',MASTER_LOG_FILE='BINLOG',MASTER_LOG_POS=#;
mysql> START SLAVE [IO_THREAD|SQL_THREAD];
mysql> SHOW SLAVE STATUS;
練習(xí):基于SSL復(fù)制的實(shí)現(xiàn)示例:
啟用ssl功能可以參考:http://www.itdecent.cn/p/eb9d4ab3991e 最后一個(gè)練習(xí)
此處創(chuàng)建CA server端ssl不在贅述,直接創(chuàng)建client的ssl開始
CA服務(wù)和mysql的主節(jié)點(diǎn)安裝在192.168.43.13
從節(jié)點(diǎn)為192.168.43.14
在主節(jié)點(diǎn)創(chuàng)建從節(jié)點(diǎn)ssl認(rèn)證所需的key:
[root@node3 ~]# cd /var/lib/mysql/.ssl
[root@node3 .ssl]# (umask 077;openssl genrsa -out client.key 2048)
[root@node3 .ssl]# openssl req -new -key client.key -out client.crt -days 365
[root@node3 .ssl]# openssl ca -in client.crt -out client.pem -days 365
[root@node3 .ssl]# openssl rsa -in client.key -out client-key.pem
[root@node3 .ssl]# scp client* root@192.168.43.14:/var/lib/mysql/.ssl/
[root@node3 .ssl]# mysql
登錄mysql并創(chuàng)建基于ssl的具有復(fù)制權(quán)限的用戶和密碼
MariaDB [(none)]> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'inspur'@'192.168.43.%' IDENTIFIED BY 'inspur' REQUIRE SSL;
MariaDB [(none)]> FLUSH PRIVILEGES;
在從節(jié)點(diǎn)登錄測(cè)試:
[root@node4 .ssl]# mysql --ssl-cert=/var/lib/mysql/.ssl/client.pem --ssl-key=/var/lib/mysql/.ssl/client-key.pem -uinspur -h192.168.43.13 -pinspur
配置從節(jié)點(diǎn)配置文件
[root@node4 .ssl]# vim /etc/my.cnf
ssl
ssl_cert=/var/lib/mysql/.ssl/client.pem
ssl_key=/var/lib/mysql/.ssl/client-key.pem
[root@node4 .ssl]# systemctl start mariadb.service
[root@node4 .ssl]# mysql
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.43.13',MASTER_USER='inspur',MASTER_PASSWORD='inspur',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=245,MASTER_SSL=1,MASTER_SSL_CERT='/var/lib/mysql/.ssl/client.pem',MASTER_SSL_KEY='/var/lib/mysql/.ssl/client-key.pem';
MariaDB [(none)]> START SLAVE;
MariaDB [(none)]> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.43.13
Master_User: inspur
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 409
Relay_Log_File: relay-log.000004
Relay_Log_Pos: 693
Relay_Master_Log_File: mysql-bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 409
Relay_Log_Space: 1873
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: Yes
Master_SSL_CA_File: /etc/pki/CA/cacert.pem
Master_SSL_CA_Path:
Master_SSL_Cert: /var/lib/mysql/.ssl/client.pem
Master_SSL_Cipher:
Master_SSL_Key: /var/lib/mysql/.ssl/client-key.pem
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row in set (0.00 sec)
ERROR: No query specified
主主復(fù)制:
-
互為主從:兩個(gè)節(jié)點(diǎn)各自都要開啟binlog和relay log;
(1) 數(shù)據(jù)不一致;因此,慎用;無(wú)論主從還是主主,只能選擇一個(gè)并備份出來(lái),刪除另一個(gè);
(2) 自動(dòng)增長(zhǎng)id;- 定義一個(gè)節(jié)點(diǎn)使用奇數(shù)id
auto_increment_offset=1
auto_increment_increment=2 - 另一個(gè)節(jié)點(diǎn)使用偶數(shù)id:
auto_increment_offset=2
auto_increment_increment=2
- 定義一個(gè)節(jié)點(diǎn)使用奇數(shù)id
-
配置步驟:
- (1) 各節(jié)點(diǎn)使用唯一的server_id;
- (2) 都啟動(dòng)binary log和relay log;
- (3) 創(chuàng)建擁有復(fù)制權(quán)限的用戶賬號(hào);
- (4) 定義自動(dòng)增長(zhǎng)id字段的數(shù)值范圍為奇偶;
- (5) 均把對(duì)方指定為主節(jié)點(diǎn),并啟動(dòng)復(fù)制線程;
-
復(fù)制時(shí)應(yīng)該注意的問(wèn)題:
1、從服務(wù)設(shè)定為“只讀”; 在從服務(wù)器啟動(dòng)read_only,但僅對(duì)非SUPER權(quán)限的用戶有效; 阻止所有用戶: `mysql> FLUSH TABLES WITH READ LOCK; `2、盡量確保復(fù)制時(shí)的事務(wù)安全 在master節(jié)點(diǎn)啟用參數(shù): `sync_binlog = ON `:當(dāng)遇到事務(wù)提交時(shí),必須將binlog緩沖區(qū)中(內(nèi)存中)記錄的事件立即刷新到磁盤上的二進(jìn)制日志文件中區(qū); 如果用到的是InnoDB存儲(chǔ)引擎: `innodb_flush_logs_at_trx_commit=ON`:事務(wù)提交時(shí),立即將事務(wù)緩沖區(qū)中與事務(wù)相關(guān)的數(shù)據(jù)刷寫到磁盤上的事務(wù)日志中區(qū) `innodb_support_xa=ON `:xa為分布式事務(wù),是否讓innodb支持分布式事務(wù);3、從服務(wù)器意外中止時(shí)盡量避免自動(dòng)啟動(dòng)復(fù)制線程 `skip_slave_start=ON`: 是否自動(dòng)啟動(dòng)復(fù)制線程;默認(rèn)是自動(dòng)啟動(dòng)的,建議關(guān)閉,手動(dòng)啟動(dòng)復(fù)制功能;-
4、從節(jié)點(diǎn):設(shè)置參數(shù) `sync_master_info=ON`:每一次當(dāng)給從節(jié)點(diǎn)dump一些event之后,本地對(duì)應(yīng)的master_info信息是否會(huì)立即同步到磁盤上讓從節(jié)點(diǎn)能夠獲取到或讓本地立即記錄下來(lái);啟動(dòng)為ON,但會(huì)增加磁盤IO壓力;sync_relay_log_info=ON
演示示例:
節(jié)點(diǎn)1:192.168.43.13
節(jié)點(diǎn)2:192168.43.14
停止msyql服務(wù),清除此前實(shí)驗(yàn);
[root@node3 ~]# systemctl stop mariadb
[root@node3 ~]# rm -rf /var/lib/mysql/*
修改節(jié)點(diǎn)1的配置文件:
[root@node3 ~]# vim /etc/my.cnf
[mysqld]
...
log_bin=mysql-bin
server_id=1
relay_log=relay-bin
auto_increment_offset=1
auto_increment_increment=2
修改節(jié)點(diǎn)2的配置文件:
[root@node4 ~]# vim /etc/my.cnf
[mysqld]
...
log_bin=mysql-bin
server_id=2
relay_log=relay-bin
auto_increment_offset=2
auto_increment_increment=2
分別啟動(dòng)mysql服務(wù):
[root@node3 ~]# systemctl start mariadb
Job for mariadb.service failed because the control process exited with error code. See "systemctl status mariadb.service" and "journalctl -xe" for details. #此處因?yàn)榍懊嬷苯觬m刪除了數(shù)據(jù)庫(kù)文件,因此需要使用`mysql_install_db --datadir=/var/lib/mysql` 重新初始化,并修改`/var/lib/mysql的屬主屬組為mysql
然后重新啟動(dòng):
[root@node3 ~]# systemctl start mariadb
連接到mysql服務(wù)器上查看二進(jìn)制日志和中繼日志是否都啟動(dòng)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'relay_log';
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| relay_log | relay-bin |
+---------------+-----------+
在兩節(jié)點(diǎn)上:設(shè)置復(fù)制權(quán)限的賬號(hào):
MariaDB [(none)]> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'slave'@'192.168.43.14' IDENTIFIED BY 'slave';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
在節(jié)點(diǎn)1上:
MariaDB [(none)]> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 503 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.43.14',MASTER_USER='slave',MASTER_PASSWO
RD='slave',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=501;
Query OK, 0 rows affected (0.02 sec)
MariaDB [(none)]> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
在節(jié)點(diǎn)2上:
MariaDB [(none)]> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 501 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.43.13',MASTER_USER='slave',MASTER_PASSWORD='slave',MASTER_LOG_FILE='mysql-bin.000003',MASTER_LOG_POS=503;
Query OK, 0 rows affected (0.03 sec)
MariaDB [(none)]> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.43.14
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 501
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 529
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 501
Relay_Log_Space: 817
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 3
1 row in set (0.00 sec)
測(cè)試:
在節(jié)點(diǎn)1上創(chuàng)建一個(gè)數(shù)據(jù)庫(kù):
MariaDB [(none)]> CREATE DATABASE mydb;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| #mysql50#.ssl |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
在節(jié)點(diǎn)2上查看:
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| #mysql50#.ssl |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
至此雙主模式配置完成
半同步復(fù)制:
一個(gè)個(gè)主節(jié)點(diǎn)有多個(gè)從節(jié)點(diǎn),主節(jié)點(diǎn)接收到請(qǐng)求以后,要至少等待一個(gè)從節(jié)點(diǎn)同步完成并告訴主節(jié)點(diǎn)數(shù)據(jù)存儲(chǔ)完成,主節(jié)點(diǎn)才返回客戶端結(jié)果,但從節(jié)點(diǎn)可有n個(gè),給余的從節(jié)點(diǎn)異步;一旦主節(jié)點(diǎn)掉線,至少能夠有一個(gè)從節(jié)點(diǎn)數(shù)據(jù)是完整的,把這種模型叫半同步復(fù)制模型;
這個(gè)半同步的服務(wù)器應(yīng)該與主節(jié)點(diǎn)在同一機(jī)架或同一機(jī)房?jī)?nèi)的有著充分帶寬的節(jié)點(diǎn);其它節(jié)點(diǎn)可以是跨機(jī)房或跨互聯(lián)網(wǎng)的;
支持多種插件:插件路徑為/usr/lib64/mysql/plugins/
需要安裝方可使用,安裝方法:`mysql> INSTALL PLUGIN plugin_name SONAME 'shared_library_name';
- 半同步復(fù)制所需插件:
semisync_master.so
semisync_slave.so
半同步復(fù)制示例:
清除此前主主模型的實(shí)驗(yàn):
~]# systemctl stop mariadb.service
~]# rm -rf /var/lib/mysql/*
重啟配置為主從復(fù)制模型后再主節(jié)點(diǎn)安裝相應(yīng)插件并配置:
[root@node3 ~]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.60-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> SHOW PLUGINS;
+--------------------------------+----------+--------------------+--------------------+---------+
| Name | Status | Type | Library | License |
+--------------------------------+----------+--------------------+--------------------+---------+
| binlog | ACTIVE | STORAGE ENGINE | NULL | GPL |
| mysql_native_password | ACTIVE | AUTHENTICATION | NULL | GPL |
| mysql_old_password | ACTIVE | AUTHENTICATION | NULL | GPL |
| MEMORY | ACTIVE | STORAGE ENGINE | NULL | GPL |
| CSV | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MyISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL | GPL |
| Aria | ACTIVE | STORAGE ENGINE | NULL | GPL |
| BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| FEDERATED | ACTIVE | STORAGE ENGINE | NULL | GPL |
| ARCHIVE | ACTIVE | STORAGE ENGINE | NULL | GPL |
| InnoDB | ACTIVE | STORAGE ENGINE | NULL | GPL |
| INNODB_RSEG | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_UNDO_LOGS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_TRX | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_LOCKS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_LOCK_WAITS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMP_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMPMEM | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CMPMEM_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_TABLES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_TABLESTATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_INDEXES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_COLUMNS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FIELDS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FOREIGN | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_FOREIGN_COLS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_SYS_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_TABLE_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_INDEX_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_POOL_PAGES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_POOL_PAGES_INDEX | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_POOL_PAGES_BLOB | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| XTRADB_ADMIN_COMMAND | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_CHANGED_PAGES | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_PAGE | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_PAGE_LRU | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| INNODB_BUFFER_POOL_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL |
| PERFORMANCE_SCHEMA | ACTIVE | STORAGE ENGINE | NULL | GPL |
| FEEDBACK | DISABLED | INFORMATION SCHEMA | NULL | GPL |
| partition | ACTIVE | STORAGE ENGINE | NULL | GPL |
| rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL |
+--------------------------------+----------+--------------------+--------------------+---------+
43 rows in set (0.00 sec)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%semi%';
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
+------------------------------------+-------+
4 rows in set (0.00 sec)
MariaDB [(none)]> SET @@GLOBAL.rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%semi%';
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
+------------------------------------+-------+
從節(jié)點(diǎn)安裝插件并配置:
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.02 sec)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows in set (0.00 sec)
MariaDB [(none)]> SET @@GLOBAL.rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows in set (0.00 sec)
MariaDB [(none)]> START SLAVE;
Query OK, 0 rows affected (0.03 sec)
主節(jié)點(diǎn)查看:
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
注意:使用INSTALL PLUGIN plugin_name SONAME 'shared_library_name時(shí),可以在配置文件中[mysqld]段中添加:
plugin_dir=/path/to/plugin/directory;不指明則默認(rèn)在/usr/lib64/mysql/pligin/目錄下;
plugin_name:為插件的名字;
shared_library_name:為插件文件的名字;
插件安裝后會(huì)生成很多服務(wù)器變量:
rpl_semi_sync_master_enabled:是否啟用自己為半同步節(jié)點(diǎn)
rpl_semi_sync_master_timeout:等待從節(jié)點(diǎn)超時(shí)時(shí)間;單位毫秒,默認(rèn)10秒;
rpl_semi_sync_master_trace_level:跟蹤級(jí)別;使用默認(rèn)值即可
rpl_semi_sync_master_wait_no_slave:沒(méi)有從節(jié)點(diǎn)是否等待;
rpl_semi_sync_master_clients:對(duì)于當(dāng)前主節(jié)點(diǎn),有多少個(gè)半同步節(jié)點(diǎn);
Rpl_semi_sync_master_net_avg_wait_time:網(wǎng)絡(luò)平均等待時(shí)間;
rpl_semi_sync_master_net_wait_time:網(wǎng)絡(luò)等待時(shí)間;
rpl_semi_sync_master_net_waits:網(wǎng)絡(luò)等待次數(shù);
rpl_semi_sync_master_tx_avg_wait_time:事務(wù)的平均等待時(shí)間;
rpl_semi_sync_master_tx_wait_time:事務(wù)的等待時(shí)間;
rpl_semi_sync_master_tx_waits:事務(wù)的等待次數(shù);
rpl_semi_sync_slave_enabled:是否啟用為半同步節(jié)點(diǎn)
rpl_semi_sync_slave_trace_level:跟蹤級(jí)別
復(fù)制過(guò)濾器:
僅復(fù)制有限一個(gè)或幾個(gè)數(shù)據(jù)庫(kù)相關(guān)的數(shù)據(jù),而非所有;由復(fù)制過(guò)濾器進(jìn)行;
- 有兩種實(shí)現(xiàn)方式:
- (1) 主服務(wù)器僅向二進(jìn)制日志中記錄與特定數(shù)據(jù)庫(kù)(特定表)相關(guān)的事件
使用方法:- binlog_do_db=:數(shù)據(jù)庫(kù)白名單列表,使用逗號(hào)分隔;只記錄哪些數(shù)據(jù)看相關(guān)的寫入操作到二進(jìn)制文件中;
- binlog_ingore_db=:數(shù)據(jù)庫(kù)黑名單列表,使用逗號(hào)分隔;僅忽略哪些數(shù)據(jù)庫(kù)相關(guān)的寫入操作到而鍵值文件中
- 注意:二者不能同時(shí)使用;還有此方法時(shí)間點(diǎn)還原無(wú)法實(shí)現(xiàn),不建議使用;
- (2) 從服務(wù)器SQL_THREDA在replay中繼日志中的事件時(shí),僅讀取特定數(shù)據(jù)庫(kù)(特定表)相關(guān)的事件并應(yīng)用于本地;
使用方法:-
reolicate_do_db=:僅復(fù)制指定的數(shù)據(jù)庫(kù),要復(fù)制數(shù)據(jù)庫(kù)的白名單; -
replicate_ingore_db=:忽略復(fù)制指定的數(shù)據(jù)庫(kù),黑名單; -
replicate_do_table=:表的白名單 -
replicate_ingore_table=:表的黑名單 -
replicate_wild_do_table=:使用通配符的表的白名單 -
replicate_wild_ingore_table=:使用通配符的表的黑名單
-
- (1) 主服務(wù)器僅向二進(jìn)制日志中記錄與特定數(shù)據(jù)庫(kù)(特定表)相關(guān)的事件
復(fù)制的監(jiān)控和維護(hù):
- (1) 清理日志:PURGE
PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }; - (2) 復(fù)制監(jiān)控
- MASTER:
SHOW MASTER STATUS;
SHOW BINLOG EVENTS;
SHOW BINARY LOGS;
-SLAVE:
SHOW SLAVE STATUS;
判斷從服務(wù)器是否落后于主服務(wù)器的變量:Seconds_Behind_Master:0
- MASTER:
- (3) 如何確定主從節(jié)點(diǎn)數(shù)據(jù)是否一致?
通過(guò)表的CHECKSUM檢查;
使用percona-tools中pt-table-checksum; - (4) 主從數(shù)據(jù)不一致時(shí)的修復(fù)方法?
重新復(fù)制;選擇一個(gè)認(rèn)為比較完整的數(shù)據(jù)庫(kù),重新備份導(dǎo)入到從節(jié)點(diǎn)上;