mysql主從復(fù)制架構(gòu)及實(shí)現(xiàn)

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è)試;

MySQL主從復(fù)制

mysql主從復(fù)制.png
工作模式:

主節(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
  • 配置步驟:

    • (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=:使用通配符的表的黑名單

復(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
  • (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)上;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容