1. 程式人生 > >Mysql 主從復制之半同步復制(基於gtid)

Mysql 主從復制之半同步復制(基於gtid)

半同步復制 server-id作用

Mysql主從復制
mysql主從復制原理:
從庫有兩個線程IO線程和SQL線程
1.從庫的IO線程向主庫的主進程發送請求,主庫驗證從庫,交給主庫IO線程負責數據傳輸;
2.主庫IO線程對比從庫發送過來的master.info裏的信息,將binlog文件信息,偏移量和binlog文件名等發送給從庫
3.從庫接收到信息後,將binlog信息保存到relay-bin中,同時更新master.info的偏移量和binlog文件名
4.從庫的SQL線程不斷的讀取relay-bin的信息,同時將讀到的偏移量和文件名寫道relay-log.info文件,binlog信息寫進自己的數據庫,一次同步操作完成。
5.完成上次同步後,從庫IO線程不斷的向主庫IO線程要binlog信息
6.從庫如果也要做主庫,也要打開log_bin 和log-slave-update參數
配置讀寫mysql主從復制的步驟:
1.在主庫與從庫都安裝mysql數據庫
2.在主庫的配置文件(/etc/my.cnf)中配置server-id 和log-bin
3.在登陸主庫後創建認證用戶並做授權。
4.在從庫的配置文件(/etc/my.cnf)中配置server-id
5.登陸從庫後,指定master並開啟同步開關。
需要註意的是server-id主從庫的配置是不一樣的。
Server-id存在作用:
mysql同步的數據中是包含server-id的,而server-id用於標識該語句最初是從哪個server寫入的。因此server-id一定要有的
Server-id不能相同的原因:每一個同步中的slave在master上都對應一個master線程,該線程就是通過slave的server-id來標識的;每個slave在master端最多有一個master線程,如果兩個slave的server-id 相同,則後一個連接成功時,slave主動連接master之後,如果slave上面執行了slave stop;則連接斷開,但是master上對應的線程並沒有退出;當slave start之後,master不能再創建一個線程而保留原來的線程,那樣同步就可能有問題;
在mysql做主主同步時,多個主需要構成一個環狀,但是同步的時候有要保證一條數據不會陷入死循環,這裏就是靠server-id來實現的;
Mysql的主從復制(gtid)實驗配置:

配置環境:rhel6.5 iptables selinx down
172.25.40.1 server1.example.com master
172.25.40.2 server2.example.com slave
安裝包:mysql-5.7.17-1.el6.x86_64.rpm-bundle.tar
在master和slave上解壓後安裝mysql數據庫:

tar xf mysql-5.7.17-1.el6.x86_64.rpm-bundle.tar
yum install -y mysql-community-client-5.7.17-1.el6.x86_64.rpm mysql-community-common-5.7.17-1.el6.x86_64.rpm mysql-community-libs-5.7.17-1.el6.x86_64.rpm mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm mysql-community-server-5.7.17-1.el6.x86_64.rpm
 /etc/init.d/mysqld start
 grep ‘password‘ /var/log/mysqld.log       
```      #篩選初始化是數據庫登陸密碼
登陸數據庫後修改密碼:
`alter user root@localhost identified by ‘xxxxxxx‘;` ##修改本地用戶密碼
1.Master端的操作:

vim /etc/my.cnf
[mysqld]
server-id=1
log-bin=mysql-bin
gtid_mode=ON #使用gtid模式
enforce-gtid-consistency=true #強制使用gtid

Slave端的操作:

[mysqld]
server-id=2
gtid_mode=ON
enforce-gtid-consistency=true

註意:在修改兩臺服務器的mysql配置文件時,一定要保證server-id必須是不同的,server-id的取值範圍是:2^32-1
2.重新啟動兩臺服務器上的mysql
` /etc/init.d/mysqld restart`
3.進入主庫創建認證用戶並授權
`grant replication slave on *.* to redhat@‘172.25.40.%‘ identified by ‘xxxxxxxxxx‘;`
4.進入slave端指定master

stop slave;
change master to master_host=‘172.25.40.1‘,master_user=‘redhat‘,master_password=‘xxxxxxxxxx‘,master_auto_position=1;
start slave;


5.在設置半同步復制master端的操作

mysql> install plugin rpl_semi_sync_master soname ‘semisync_master.so‘;
Query OK, 0 rows affected (0.50 sec)

mysql> set global rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like ‘%rpl_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_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.01 sec)

6.5.在設置半同步復制slave端的操作

mysql> install plugin rpl_semi_sync_slave soname ‘semisync_slave.so‘;
Query OK, 0 rows affected (0.14 sec)

mysql> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like ‘%rpl_semi%‘;
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows in set (0.00 sec)

如果在slave端開啟io線程後,會自動調轉為半同步模式進行數據傳輸
![](http://i2.51cto.com/images/blog/201805/02/7687411e99cbec08048536a5589ece39.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

關閉io線程 在master上再進行事務時會等待10s後從半同步狀態轉為異步。
![](http://i2.51cto.com/images/blog/201805/02/3f2914d044166abddd25f04bacc788e1.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

當第二次進行數據插入時會變成異步同步

![](http://i2.51cto.com/images/blog/201805/02/21df15b4774e91b721b9856d9355ea15.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

Mysql 並行復制
多線程工作
Slave端修改配置文件:

[mysqld]
slave-parallel-type=LOGICAL_CLOCK
slave-parallel-workers=16 #開啟16個線程工作
master_info_repository=TABLE #以表的形式存放master_info的信息
relay_log_info_repository=TABLE #以表的形式存放relay_log_info的信息
relay_log_recovery=ON #


重啟服務
`/etc/init.d/mysqld restart`
當進入數據庫的mysql庫中,可以執行sql語句:
`select * from slave_master_info;`
可以看到原本在/var/lib/mysql下的relay-log.info的文件已經轉為數據庫中的表。

Mysql 主從復制之半同步復制(基於gtid)