MySQL/MariaDB數據庫主從複製

MySQL數據庫複製概述

MySQL的主從複製是指從服務器向主服務器獲取二進制日誌文件,然後在從服務器上對這些日誌重新執行,從而使從服務器和主服務器保持同步。但由於是異步的複製,從服務器在一定程度上落後於主服務器,剛寫入到主服務器上的數據可能服務在從服務器上查詢得到。


MySQL的複製原理:

(1)從服務器創建I/O線程連接主數據庫,向主數據庫請求二進制日誌文件。

(2)主庫上啓動Binlog Dump,將二進制日誌文件發送給I/O線程,I/O線程獲取數據後將數據寫在從庫的中繼日誌中(relay log)。

(3)SQL線程讀取中繼日誌並執行。


在主服務器上,記錄二進制日誌的方式有3種:

statement:基於語句級別的binlog,記錄的是修改數據的sql語句。

row:基於行級別的binlog逐行記錄數據的變更。

mixed:由MySQL數據庫自動選擇哪種方式記錄binlog。

statement格式僅僅是記錄操作的SQL語句,row格式會將每行數據的變化都記錄到binlog中,相對於statement要詳細的多,更能夠保證主從數據庫的一致性。但是row格式下的二進制日誌文件會顯得非常龐大,會影響磁盤I/O,在傳輸過程中也會影響帶寬,所以需要根據具體情況來設定。


在一個非常繁忙的數據庫上,主庫上往往有多個線程併發執行寫操作,而這些事件記錄到二進制日誌中一定是線性的。從庫上只有一個SQL線程執行寫操作,長此以往,從庫與主庫的差距會越來越大。這種情況下在從庫上可以啓動多個SQL線程用於執行寫操作,每個線程負責執行主庫上某個數據庫的所有相關事務。還有在主庫上一個事務提交之後,相關的記錄不會立刻同步到磁盤上,而是記錄在緩衝上,每隔一段時間同步一次。這樣也可能會導致主從不一致,可以在主服務器上設置參數sync_binlog=1,一但事務提交,就將二進制日誌文件從內存緩衝同步至磁盤上。


數據庫複製搭建過程

一主多從架構

實驗環境:主服務器(192.168.1.106),從服務器(192.168.1.127)


1)首先確保各服務器時間同步

2)安裝MariaDB數據庫,這裏使用的是mariadb-10,二進制安裝方式,mariadb-10中GTID機制已成爲標配,不需要再手動啓動。

[root@www ansible]# ansible mysql -m shell -a 'tar xf /root/mariadb-10.0.10-linux-x86_64.tar.gz -C /usr/local/'
[root@www ansible]# ansible mysql -m shell -a 'groupadd -g 300 -r mysql'
[root@www ansible]# ansible mysql -m shell -a 'useradd -u 300 -g mysql -r  mysql'
[root@www ansible]# ansible mysql -m shell -a 'ln -sv /usr/local/mariadb-10.0.10-linux-x86_64/ /usr/local/mysql'
[root@www ansible]# ansible mysql -m shell -a 'chown -R root.mysql /usr/local/mysql/*'
[root@www ansible]# ansible mysql -m shell -a 'chown -R mysql.mysql /data'
[root@www ansible]# ansible mysql -m shell -a 'mkdir /etc/mysql'
[root@www ansible]# ansible mysql -m shell -a 'cp /usr/local/mysql/support-files/my-large.cnf /etc/mysql/my.cnf'
[root@www ansible]# ansible mysql -m shell -a 'cp /usr/local/mysql/support-files/mysql.server /etc/rc.d/init.d/mysqld'
[root@www ansible]# ansible mysql -m shell -a 'chkconfig --add mysqld'

在各個節點上/usr/local/mysql目錄下執行初始化操作:

./scripts/mysql_install_db --user=mysql --datadir=/MySQL_DATA/data/

3)修改配置文件

主服務器上:

/etc/mysql/my.cnf:

datadir=/data/mydata                     #數據存放目錄
log-bin=/data/binlogs/master-bin         #二進制日誌存放位置
binlog_format=mixed                      #記錄二進制日誌格式
sync_binlog = 1                          #事務一提交,就將二進制日誌同步至磁盤上
autocommit = off                         #關閉自動提交
server-id       = 1                      #服務器ID號
 
innodb_support_xa       = 1              #支持分佈式事務

從服務器上:

/etc/mysql/my.cnf:

server-id       = 2
datadir = /data/mydata
relay-log = /data/relaylog/relay-log   #中繼日誌存放目錄
read_only       = 1                #從服務器爲只讀狀態(確保數據的一致性)
slave_parallel_threads = 3         #啓動的SQL線程數
sync_master_info = 1               #從服務器按需要同步master.info文件
sync_relay_log = 1                 #按需要同步中繼日誌
sync_relay_log_info = 1            #按需要同步relay.info文件

4)啓動服務

[root@www ~]# ansible mysql -m shell -a 'service mysqld start'

5)在主服務器上登錄mariadb,創建授權賬號

MariaDB [(none)]> grant replication slave,replication client on *.* to repuser@'192.168.1.%' identified by 'repuser';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;

6)從服務器上,登錄數據庫使用有複製權限的賬號連接master

首先查看主服務器二進制日誌所處的位置(show master status;),如果服務器已經運行了一段時間,可以先對主服務器進行備份(備份至某個位置),在從服務器上恢復,再從該位置進行同步。

wKiom1XayirSvoL8AAFI-IIbzQA037.jpg

MariaDB [(none)]> change master to master_host='192.168.1.106',master_user='repuser',master_password='repuser',master_log_file='master-bin.000007',master_log_pos=343;

從服務器上啓動IO線程和sql線程

MariaDB [(none)]> start slave;

或者

MariaDB [(none)]> start slave IO_THREAD
MariaDB [(none)]> start slave SQL_THREAD


從服務器上查看運行狀況:

wKioL1Xaymfhq7hSAAJQD3wNaSU768.jpg

wKiom1XayJXxbfhsAACIVuomwfY796.jpg

相關線程已經啓動,其中Seconds_Behind_Master顯示了從服務器落後主服務器的時間,這個變量是通過當前服務器時間戳和二進制日誌中事件的時間戳對比得到的(null爲從庫沒有處於運行狀態,0也有可能是複製中斷了,這個參數經供參考)

在主服務器上可同過show slave hosts查看與自己同步的從服務器:

wKioL1Xay7mQSXSiAADohKsds_M636.jpg


實現半同步複製

半同步就是主服務器上數據發生了更改,需要等待至少一個從節點把數據完整地複製過去,才能繼續後續的操作。半同步功能是以插件的方式提供能,要啓用此功能需要先安裝插件。該插件位於mariadb安裝目錄下的lib/plugin目錄中,登入數據庫後直接安裝即可。


主節點上安裝插件

MariaDB [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so';

在配置文件中添加如下幾項:

rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 1000

重啓服務後查看相關變量:

MariaDB [(none)]> show global variables like '%semi%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | ON    |
| rpl_semi_sync_master_timeout       | 1000  |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
+------------------------------------+-------+


從節點上安裝插件

MariaDB [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

在配置文件中添加:

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    |
+---------------------------------+-------+

該功能已啓用.................^_^


雙主複製架構

實驗環境:node1(192.168.1.106),node2(192.168.1.126)

配置雙主模型是需要注意幾點:

    (1) 雙方節點都得創建具有複製權限用戶;

    (2) 雙節點都得啓用中繼日誌和二進制日誌;

    (3) 爲保證具有自動增長功能的字段能正確生成ID,需要配置兩個節點分別使用偶數或奇數ID號;

    (4) 都要把對方配置爲自己的主節點;


node1上配置文件:

[root@node1 ~]# vim /etc/mysql/my.cnf 
log-bin = /data/binlog/master-bin
binlog_format = row
datadir = /data/mydata
sync_binlog = 1
autocommit = off
relay-log = /data/relaylog/relay-log    #中繼日誌存放位置
innodb_support_xa = 1
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
auto-increment-increment = 2            #自增長的間隔
auto-increment-offset = 1               #自增長起始值
slave_parallel_threads = 3
log_slave_updates = 1                   #開啓從庫更新操作寫入二進制日誌功能
server-id       = 1

node2上配置文件(除了下面3項其餘的與node1上的配置一致):

[root@node1 ~]# vim /etc/mysql/my.cnf 
.......
.......
auto-increment-increment = 2
auto-increment-offset = 2
server-id       = 2


在node1和node2上都創建具有複製權限的用戶:

MariaDB [(none)]> grant replication slave,replication client on *.* to repuser@'192.168.1.%' identified by 'repuser';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;

查看node1和node2上當前數據庫二進制日誌文件所處的位置:

MariaDB [(none)]> show master status;

在node1上主服務器指向node2:

MariaDB [(none)]> change master to master_host='192.168.1.126',master_user='repuser',master_password='repuser',master_log_file='master-bin.000004',master_log_pos=657;

在node2上主服務器指向node1:

MariaDB [(none)]> change master to master_host='192.168.1.106',master_user='repuser',master_password='repuser',master_log_file='master-bin.000004',master_log_pos=657;

最後啓動I/O線程和SQL線程:

MariaDB [(none)]> start slave;


node1(192.168.1.106)上查看從節點狀態:

wKiom1Xa1-agJB-5AAI9z0LeZ40421.jpg

node2(192.168.1.126)上查看從節點狀態:

wKioL1Xa2h7C***yAAI_UhSroyE199.jpg

在雙主模型中應用半同步功能,需要在兩個節點上都安裝插件,並配置主從相關的參數。

配置完成.................^_^


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