mysql5.6半同步主從複制配置
在談這個特性之前,我們先來看看MySQL的複制架構衍生史。
在2000年,MySQL 3.23.15版本引入了Replication。Replication作為一種準實時同步方式,得到廣泛應用。這個時候的Replicaton的實作涉及到兩個線程,一個在Master,一個在Slave。Slave的I/O和SQL功能是作為一個線程,從Master擷取到event後直接apply,沒有relay log。這種方式使得讀取event的速度會被Slave replay速度拖慢,當主備存在較大延遲時候,會導緻大量binary log沒有備份到Slave端。
在2002年,MySQL 4.0.2版本将Slave端event讀取和執行獨立成兩個線程(IO線程和SQL線程),同時引入了relay log。IO線程讀取event後寫入relay log,SQL線程從relay log中讀取event然後執行。這樣即使SQL線程執行慢,Master的binary log也會盡可能的同步到Slave。當Master當機,切換到Slave,不會出現大量資料丢失。
在2010年MySQL 5.5版本之前,一直采用的是這種異步複制的方式。主庫的事務執行不會管備庫的同步進度,如果備庫落後,主庫不幸crash,那麼就會導緻資料丢失。于是在MySQL在5.5中就順其自然地引入了半同步複制,主庫在應答用戶端送出的事務前需要保證至少一個從庫接收并寫到relay log中。那麼半同步複制是否可以做到不丢失資料呢?下面分析。
在2016年,MySQL在5.7.17中引入了一個全新的技術,稱之為InnoDB Group Replication。目前官方MySQL 5.7.17基于Group replication的全同步技術已經問世,全同步技術帶來了更多的資料一緻性保障。相信是未來同步技術一個重要方向,值得期待。MySQL 5.7 Group Replication
半同步機制:
1. 當Master上開啟半同步複制的功能時,至少應該有一個Slave開啟其功能。此時,一個線程在Master上送出事務将受到阻塞,直到得知一個已開啟半同步複制功能的Slave已收到此事務的所有事件,或等待逾時。
2. 當Slave主機連接配接到Master時,能夠檢視其是否處于半同步複制的機制。
3. 當一個事務的事件都已寫入其relay-log中且已重新整理到磁盤上,Slave才會告知已收到。
4. 如果等待逾時,也就是Master沒被告知已收到,此時Master會自動轉換為異步複制的機制。當至少一個半同步的Slave趕上了,Master與其Slave自動轉換為半同步複制的機制。
5. 半同步複制的功能要在Master,Slave都開啟,半同步複制才會起作用;否則,隻開啟一邊,它依然為異步複制。
由于5.7之後的版本引入的全同步,測試半同步必須用5.6的版本進行。
1.配置半同步的主從複制必須先配置好異步的主從複制,先檢查一下異步的主從是否完好。
master:
[html] view plain copy- mysql> mysql> show master status;
- +------------------+----------+--------------+------------------+-------------------+
- | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
- | mysql_bin.000013 | 601 | | | |
- 1 row in set (0.00 sec)
slave:
- mysql> show slave status\G
- *************************** 1. row ***************************
- Slave_IO_State: Waiting for master to send event
- Master_Host: 172.17.61.131
- Master_User: repl
- Master_Port: 3306
- Connect_Retry: 60
- Master_Log_File: mysql_bin.000013
- Read_Master_Log_Pos: 601
- Relay_Log_File: mysqld-relay-bin.000002
- Relay_Log_Pos: 374
- Relay_Master_Log_File: mysql_bin.000013
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
- ...
- Exec_Master_Log_Pos: 601
- Relay_Log_Space: 548
- Until_Condition: None
- ...
- Master_Server_Id: 10000
- Master_UUID: 82acea94-3e6f-11e8-b4a7-000c29d02daa
- Master_Info_File: /u01/mysql/master.info
- SQL_Delay: 0
- SQL_Remaining_Delay: NULL
- Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
- Master_Retry_Count: 86400
2.master安裝半同步子產品并啟動(此子產品就在/usr/local/mysql/lib/plugin/semisync_master.so)
PS:如果想解除安裝異步子產品就使用uninstall即可。
- mysql> show global variables like '%semi%';
- Empty set (0.00 sec)
- mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
- Query OK, 0 rows affected (0.06 sec)
- mysql> 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)
rpl_semi_sync_master_enabled參數是指是否已啟動半同步
rpl_semi_sync_master_timeout參數連接配接salve逾時的時間,機關為毫秒,預設為10秒
在配置檔案中修改這兩個參數并重新開機資料庫
- [root@qht131 ~]# cat /etc/my.cnf
- 。。。
- [mysqld]
- rpl_semi_sync_master_enabled = 1
- rpl_semi_sync_master_timeout = 2000
- [root@qht131 ~]# service mysql restart
- Shutting down MySQL.... [ OK ]
- Starting MySQL.. [ OK ]
- | rpl_semi_sync_master_enabled | ON |
- | rpl_semi_sync_master_timeout | 2000 |
3.slave安裝半同步子產品
- mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
- Query OK, 0 rows affected (0.03 sec)
- +---------------------------------+-------+
- | Variable_name | Value |
- | rpl_semi_sync_slave_enabled | OFF |
- | rpl_semi_sync_slave_trace_level | 32 |
- 2 rows in set (0.00 sec)
修改配置檔案打開半同步
- [root@qht132 backup]# cat /etc/my.cnf
- 。。。。
- rpl_semi_sync_slave_enabled=1
- [root@qht132 backup]# service mysql restart
- Shutting down MySQL.. [ OK ]
- | rpl_semi_sync_slave_enabled | ON |
需要重新連接配接master伺服器,半同步才會生效:
- mysql> stop slave io_thread;
- Query OK, 0 rows affected (0.00 sec)
- mysql> start slave io_thread;
3.檢查一下半同步是否完成
- mysql> show global status like 'rpl%';
- +--------------------------------------------+-------+
- | 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.03 sec)
現在半同步已經正常工作了,主要看Rpl_semi_sync_master_clients是否不為0,Rpl_semi_sync_master_status是否為ON。如果Rpl_semi_sync_master_status為OFF,說明出現了網絡延遲或Slave IO線程延遲。
4.那麼可以驗證一下半同步逾時,是否會自動降為異步工作。可以在Slave上停掉半同步協定,然後在Master上建立資料庫看一下能不能複制到Slave上。
slave上先關閉半同步:
- mysql> set global rpl_semi_sync_slave_enabled = 0 ;
master:
- mysql> create database dbtest;
- Query OK, 1 row affected (2.01 sec)
- mysql> create database dbtest2;
- Query OK, 1 row affected (0.00 sec)
建立第一個資料庫花了2.01秒,而我們前面設定的逾時時間是2秒,而建立第二個資料庫花了0.01秒,由此得出結論是逾時轉換為異步傳送。可以在Master上檢視半同步相關的參數值Rpl_semi_sync_master_clients和Rpl_semi_sync_master_status是否正常。
- mysql> show global status like '%semi%';
- | Rpl_semi_sync_master_clients | 0 |
- | Rpl_semi_sync_master_no_times | 1 |
- | Rpl_semi_sync_master_no_tx | 2 |
- | Rpl_semi_sync_master_status | OFF |
Rpl_semi_sync_master_clients已為0,Rpl_semi_sync_master_status已為OFF,現在主從複制已是異步狀态。
5.還有一個問題,slave開啟半同步後,master能自動開啟半同步嗎?
- mysql> set global rpl_semi_sync_slave_enabled = 1;
- Query OK, 0 rows affected (0.01 sec)
- 14 rows in set (0.00 sec)
當Slave開啟半同步後,或者當主從之間網絡延遲恢複正常的時候,半同步複制會自動從異步複制又轉為半同步複制,還是相當智能的。
原文位址
http://www.bieryun.com/3145.html