Mysql主從、主主、半同步複製

系統環境

主機名   IP

node1    192.168.231.130

node2    192.168.231.131


MariaDB版本

# mysql --version
mysql  Ver 15.1 Distrib 5.5.60-MariaDB, for Linux (x86_64) using readline 5.1

Mariadb主從複製

主只可寫,從只可讀

主從複製:
    從節點:
        I/O    Thread:從Master請求二進制日誌事件,並保存於中繼日誌中
        SQL    Thread:從中繼日誌中讀取日誌文件,在本地完成重放
   主節點:
       dump    Thread:爲每個Slave的I/O    Thread啓動一個dump線程,用於向其發送binary    log    events

特點:
    1.異步複製
    2.主從數據不一致比較常見

配置過程:

主節點:
(1)啓動二進制日誌
(2)爲當前節點設置一個全局唯一的ID號
(3)創建有複製權限的用戶賬號
從節點:
(1)啓動中繼日誌
(2)爲當前節點設置一個全局唯一的ID號
(3)使用有複製權限的用戶賬號連接至主服務器,並啓動複製線程

實例

#編輯node1配置文件
[root@node1 ~]# vim /etc/my.cnf
log_bin=mysql-bin   #開啓二進制日誌,以mysql-bin命名文件
innodb_file_per_table=ON   #每個新創建的表都會有一個表空間,將每個新創建的表的數據及索引存儲在一個獨立的.ibd文件裏
server_id=1  #id號
skip_name_resolve=ON  #禁止域名解析的

#修改配置文件後重啓mariadb
[root@node1 ~]# systemctl restart mariadb

#創建repluser用戶,並賦予REPLICATION SLAVE,REPLICATION CLIENT權限
MariaDB [(none)]> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repluser'@'192.168.231.131' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.01 sec)
  • REPLICATION SLAVE :常用於建立複製時所需要用到的用戶權限,也就是slave server必須被master server授權具有該權限的用戶,才能通過該用戶複製。
  • REPLICATION CLIENT :不可用於建立複製,有該權限時,只是多了可以使用如"SHOW SLAVE STATUS"、"SHOW MASTER STATUS"等命令。
#刷新權限
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
 
#編輯node2的mariadb配置文件
[root@node2 ~]# vim /etc/my.cnf
relay_log=relay-log  #中繼日誌
server_id=6
innodb_file_per_table=ON
skip_name_resolve=ON
[root@node2 ~]# systemctl start mariadb
[root@node1 mysql]# mysql
MariaDB [(none)]> help CHANGE MASTER TO

#查看主節點二進制日誌
MariaDB [(none)]> show master logs;
+-------------------+-----------+
| Log_name          | File_size |
+-------------------+-----------+
| master-bin.000001 |     30331 |
| master-bin.000002 |   1038814 |
| master-bin.000003 |       245 |
+-------------------+-----------+
3 rows in set (0.00 sec)
[root@node2 mysql]# mysql

#查看CHANGE MASTER TO 詳細解釋
MariaDB [(none)]> help CHANGE MASTER TO

#確定需要同步的主機IP,用戶名,密碼,binlog文件,binlog位置等信息
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.231.130',MASTER_USER='repluser',MASTER_PASSWORD='123456',MASTER_LOG_FILE='master-bin.000003',MASTER_LOG_POS=245;

#查看slave的狀態
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State:  
                  Master_Host: 192.168.231.130
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000003    #當前二進制日誌
          Read_Master_Log_Pos: 245                     #二進制記錄位置
               Relay_Log_File: relay-log.000001        #中繼日誌
                Relay_Log_Pos: 4
        Relay_Master_Log_File: master-bin.000003
             Slave_IO_Running: No                            #IO線程沒有開啓
            Slave_SQL_Running: No                          #SQL線程沒有開啓
 
#啓動SLAVE,相應的IO和SQL線程就會開啓
MariaDB [(none)]> START SLAVE;

測試:

#創建數據庫後,二進制日誌進行記錄,位置變爲578
[root@node1 ~]# mysql
MariaDB [(none)]> create database mydb;
MariaDB [(none)]> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000003 |      578 |              |                  |
+-------------------+----------+--------------+------------------+

[root@node2 ~]# mysql
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.231.130
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000003
          Read_Master_Log_Pos: 578        #讀取node1二進制日誌到578,說明覆製成功
               Relay_Log_File: relay-log.000002
                Relay_Log_Pos: 863
        Relay_Master_Log_File: master-bin.000003
             Slave_IO_Running: Yes    #IO線程開啓
            Slave_SQL_Running: Yes    #SQL線程開啓

#node2也可查看到mydb數據庫
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| performance_schema |
| test               |
+--------------------+

注意:進行下邊實驗時,數據可能會影響,可刪除/etc/my.cnf中datadir目錄中數據,並重啓mariadb

MariaDB主主複製

都可進行讀寫

互爲主從:
    1、數據不一致:因此,慎用
    2、自動增長id

        需要用到輔助工具(這裏不再使用奇偶id,使用自增id即可)
        否則會出現:
        | 12 | landongyang  |
        | 14 | ruifeng      |
        | 16 | xiaohe       |
        | 17 | lisiye       |
        | 19 | changshun    |
        | 21 | lidaniang    |
        | 23 | wenxiansheng |
        | 24 | landongyang1 |
        | 26 | ruifeng1     |
        | 28 | xiaohe1      |

        配置一個節點使用奇數id
            auto_increment_offset=1
            auto_increment_increment=2
        另一個節點使用偶數id
            auto_increment_offset=2
            auto_increment_increment=2

配置步驟:
(1)各節點使用一個唯一server_id
(2)都啓動binary log和relay log;
(3)創建擁有複製權限的用戶賬號
(4)定義自動增長id字段的數值範圍爲奇偶
(5)均把對方指定爲主節點,並啓動複製線程

實例


#編輯node1配置文件
[root@node1 ~]# vim /etc/my.cnf
log_bin=master-bin
relay_log=relay-log
innodb_file_per_table=ON
server_id=1
skip_name_resolve=ON

#重啓mariadb
[root@node1 ~]# systemctl restart mariadb
[root@node1 ~]# mysql
#下邊命令不再註釋,可看前文
MariaDB [(none)]> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repluser'@'192.168.231.131' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000003 |      499 |              |                  |
+-------------------+----------+--------------+------------------+

#編輯node2配置文件
[root@node2 ~]# vim /etc/my.cnf
log_bin=master-bin
relay_log=relay-log
innodb_file_per_table=ON
server_id=1
skip_name_resolve=ON

#重啓mariadb
[root@node2 ~]# systemctl start mariadb
[root@node2 ~]# mysql
MariaDB [(none)]> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repluser'@'192.168.231.130' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000003 |      509 |              |                  |
+-------------------+----------+--------------+------------------+
[root@node1 ~]# mysql
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.231.131',MASTER_USER='repluser',MASTER_PASSWORD='123456',MASTER_LOG_FILE='master-bin.000003',MASTER_LOG_POS=509;
MariaDB [(none)]> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000003 |      499 |              |                  |
+-------------------+----------+--------------+------------------+
[root@node2 ~]# mysql
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.231.130',MASTER_USER='repluser',MASTER_PASSWORD='123456',MASTER_LOG_FILE='master-bin.000003',MASTER_LOG_POS=499;
Query OK, 0 rows affected (0.02 sec)
MariaDB [(none)]> start slave;

[root@node1 ~]# mysql
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.231.131
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000003
          Read_Master_Log_Pos: 509
               Relay_Log_File: relay-log.000002
                Relay_Log_Pos: 530
        Relay_Master_Log_File: master-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: 509
              Relay_Log_Space: 818
              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: 6
1 row in set (0.00 sec)

[root@node2 ~]# mysql
MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.231.130
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000003
          Read_Master_Log_Pos: 509
               Relay_Log_File: relay-log.000002
                Relay_Log_Pos: 530
        Relay_Master_Log_File: master-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: 509
              Relay_Log_Space: 818
              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: 1
1 row in set (0.00 sec)

測試

node1和node2都可進行讀寫

#進入數據庫創建數據庫
[root@node1 ~]# mysql
MariaDB [(none)]> create database mydb;
MariaDB [(none)]> use mydb
MariaDB [mydb]> create table student(id int NOT NULL AUTO_INCREMENT PRIMARY KEY,name char(20));
MariaDB [mydb]> insert into student(name) values('changshun'),('lidaniang'),('wenxiansheng');
MariaDB [mydb]> select * from student;
+----+--------------+
| id | name         |
+----+--------------+
|  1 | changshun    |
|  2 | lidaniang    |
|  3 | wenxiansheng |
+----+--------------+

[root@node2 ~]# mysql
MariaDB [(none)]> use mydb;
MariaDB [mydb]> select * from student;
+----+--------------+
| id | name         |
+----+--------------+
|  1 | changshun    |
|  2 | lidaniang    |
|  3 | wenxiansheng |
+----+--------------+
MariaDB [mydb]> insert into student(name) values('tianyou'),('ruixuan'),('xiaoshun');
MariaDB [mydb]> select * from student;
+----+--------------+
| id | name         |
+----+--------------+
|  1 | changshun    |
|  2 | lidaniang    |
|  3 | wenxiansheng |
|  4 | tianyou      |
|  5 | ruixuan      |
|  6 | xiaoshun     |
+----+--------------+

MariaDB半同步複製

主只可讀,從只可讀

首先了解一下半同步複製

  • 異步複製(Asynchronous replication)

MySQL默認的複製即是異步的,主庫在執行完客戶端提交的事務後會立即將結果返給給客戶端,並不關心從數據庫是否已經接收並處理,這樣就會有一個問題,主服務如果crash掉了,此時主服務上已經提交的事務可能並沒有傳到從上,如果此時,強行將從提升爲主,可能導致新主上的數據不完整。

  • 全同步複製(Fully synchronous replication)

指當主庫執行完一個事務,所有的從庫都執行了該事務才返回給客戶端。因爲需要等待所有從庫執行完該事務才能返回,所以全同步複製的性能必然會收到嚴重的影響。

  • 半同步複製(Semisynchronous replication)

介於異步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於異步複製,半同步複製提高了數據的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步複製最好在低延時的網絡中使用。

master:
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql> SET GLOBAL VARIABLES rpl_semi_sync_master_enabled=l;
mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';
mysq1> SHOW GLOBAL STATUS LIKE '%semi%';
slave:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> SET GLOBAL VARIABLES rpl_semi_sync_slave_enabled=1;


#編輯node1配置文件
[root@node1 ~]# vim /etc/my.cnf
log_bin=master-bin
innodb_file_per_table=ON
server_id=1
skip_name_resolve=ON

#重啓mariadb
[root@node1 ~]# systemctl restart mariadb
[root@node1 ~]# mysql
MariaDB [(none)]> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repluser'@'192.168.231.131' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
#查看當前二進制日誌
MariaDB [(none)]> SHOW MASTER STATUS;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000003 |      499 |              |                  |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

#在node1安裝semisync_master,主半同步插件
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

#查看插件列表中是否已安裝
MariaDB [(none)]> SHOW PLUGINS;
| rpl_semi_sync_master           | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |

#查看半同步複製相關變量
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    |
+------------------------------------+-------+

#開啓半同步複製功能
MariaDB [(none)]> set global rpl_semi_sync_master_enabled=1;
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    |
+------------------------------------+-------+


#編輯node2配置文件
[root@node2 ~]# vim /etc/my.cnf
relay_log=relay-log
server_id=6
innodb_file_per_table=ON
skip_name_resolve=ON
[root@node2 ~]# systemctl restart mariadb
[root@node2 ~]# mysql
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
| rpl_semi_sync_slave            | ACTIVE   | REPLICATION        | semisync_slave.so | GPL     |
MariaDB [(none)]> show global variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | OFF   |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

MariaDB [(none)]>   set global rpl_semi_sync_slave_enabled=1;
MariaDB [(none)]> show global variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

[root@node2 ~]# mysql
 MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.231.130',MASTER_USER='repluser',MASTER_PASSWORD='123456',MASTER_LOG_FILE='master-bin.000003',MASTER_LOG_POS=499;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> start slave;

測試

[root@node1 ~]# mysql
MariaDB [(none)]> create database mydb;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> use mydb;
Database changed
MariaDB [mydb]> create table mytb(id int,name char(30));
Query OK, 0 rows affected (0.01 sec)

MariaDB [mydb]> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 1074  |#平均等待時間
| Rpl_semi_sync_master_net_wait_time         | 2149  |#半同步複製等待時間
| Rpl_semi_sync_master_net_waits             | 2     |
| 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      | 1031  |
| Rpl_semi_sync_master_tx_wait_time          | 2063  |
| Rpl_semi_sync_master_tx_waits              | 2     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 2     |
+--------------------------------------------+-------+

複製過濾

複製過濾器:
    讓從節點僅複製指定的數據庫,或指定數據庫的指定表
有兩種實現方式:
(1)主服務器僅向二進制日誌中記錄與特定數據庫(特定表)相關的事件
    問題:時間還原無法實現;不建議使用
    參數:
    binlog_do_db=    #數據庫白名單列表
    binlog_ignore_db=    #數據庫黑名單列表
(2)從服務器SQL_THREAD在replay中繼日誌中的事件時,僅讀取與特定數據庫(特定表)相關的事件並應用於本地
    問題:會造成網絡及IO浪費
    參數:
    replicate_do_db
    replicate_ignore_db
    replicate_do_table
    replicate_ignore_db
    replicate_ignore_table
    replicate_wild_do_table
    replicate_wild_ignore_table
在這裏演示第二種方案:

可以基於半同步複製進行實驗,只是設置參數進行過濾

[root@node2 ~]# mysql

#先把slave停掉,再設置變量,否則會報錯
MariaDB [(none)]> stop slave;
MariaDB [(none)]> show global variables like 'replicate%';
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| replicate_annotate_row_events    | OFF       |
| replicate_do_db                  |           |
| replicate_do_table               |           |
| replicate_events_marked_for_skip | replicate |
| replicate_ignore_db              |           |
| replicate_ignore_table           |           |
| replicate_wild_do_table          |           |
| replicate_wild_ignore_table      |           |
+----------------------------------+-----------+

#設置複製的數據庫白名單
MariaDB [(none)]> set global replicate_do_db=mydb;
MariaDB [(none)]> start slave;

測試

node1:
MariaDB [mydb]> create database yourdb;
MariaDB [mydb]> insert into mytb values(1,'ruixuan'),(2,'ruifeng'),(3,'ruiquan');
MariaDB [mydb]> select * from mytb;
+------+---------+
| id   | name    |
+------+---------+
|    1 | ruixuan |
|    2 | ruifeng |
|    3 | ruiquan |
+------+---------+

node2:
#沒有複製yourdb
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| performance_schema |
| test               |
+--------------------+
#數據複製到mydb中的表mytb
MariaDB [mydb]> select * from mytb;
+------+---------+
| id   | name    |
+------+---------+
|    1 | ruixuan |
|    2 | ruifeng |
|    3 | ruiquan |
+------+---------+

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章