17.1.1 Replication技術mysql
17.1.2 Group Replication使用場景數據庫
17.1.3 Group Replication細節bootstrap
17.2.1 Group Replication部署單主模式
17.2.1.1 部署Group Replication實例
17.2.1.2 爲一個實例配置Group Replication
17.3.1 Replication_group_member_stats
17.3.2 Replication_group_members
17.3.3 Replication_connection_status
17.3.4 Replication_applier_status
17.3.5 Group Replication Server States
17.4.3.2 Unblocking a Partition
17.9.3 Data Manipulation Statements
17.9.4 Data Definition Statements
17.5.9.2 Recovering From a Point-in-time
最經常使用建立容錯系統是使用手段來冗餘組件,也就是說組件能夠被刪除,可是系統仍是正常運行。複製的數據庫必須面臨的一個問題,他們須要維護和管理多個實例,還有服務組合在一塊兒建立,把一切其餘傳統分佈式系統組合的問題也必須解決。
最主要的問題是抱着數據庫和數據的複製在幾個服務合做下,邏輯是一致的而且是簡單的。也就是說,多個服務贊成系統和數據的狀態,而且贊成系統前進時的每一個修改。就是服務在每一個數據庫的傳輸的狀態都必須贊成,全部的處理就好像在一個數據庫或者以後會覆蓋的其餘數據庫到相同的狀態。
MySQL Group Replication提供了分佈式複製,使用server之間的強鏈接,若是服務在相同的group,那麼久會自動鏈接上。Group能夠是單主,也能夠是多主的。
有一個編譯好的服務,在任意時間點,能夠看group的一致性和可用性。服務能夠加入,離開group,而且view會有相應的更新。有時候服務會異常離開group,那麼錯誤診斷機制會發現而且通知組而且修改view,這些都是自動的。
對於事務提交,須要大多數贊成。事務提交和回滾完成是由單獨服務肯定的,不是全部的服務決定。若是有一個network partition,那麼就會致使分裂,成員不能相互通訊,所以系統不能處理,知道問題被解決。固然也有內置的,自動的主分裂保護的機制。
MySQL傳統的主從複製。有一個主,多個從。主執行事務,提交而後發送到從,從新執行。是shared-nothing系統,全部的服務默認是full copy的。
Group Replication能夠用於容錯系統,是一組互相交互的服務。交互層提供了機制確保消息的原子性和消息的交互。
Group Replication實現了多主的複製。複製組由多個服務組成,每一個服務均可以運行事務。讀寫的時候以後group承認以後才能提交。只讀事務由於不須要和group交互,所以提交很快。也就是說關於寫入事務,group須要決定事務是否提交,而不是原始的服務單獨肯定的。當原始服務準備提交,服務會自動廣播。而後事務的全局順序被創建。這個很重要,也就是說全部的服務在相同的事務順序下,收到了相同的事務。這樣也就保證了group的數據一致性。
固然不一樣的服務併發的執行事務也會有衝突。這種衝突出如今檢查不一樣寫入集合的併發事務。這個過程叫作certification 。若是2個併發事務在不一樣的服務上運行,更新了相同的行,那麼就是發生衝突了。解決方法是提交順序在前面的,另一個就回滾。
略,具體看:
https://dev.mysql.com/doc/refman/5.7/en/group-replication-use-cases.html
有一個錯誤發現機制,用來找出報告那個服務是靜默的,而後假定爲已經掛了。錯誤發現其實分佈式服務用來提供服務的活動信息。以後group決定服務確實出錯,那麼剩下的group成員就會排除這個成員。
當服務靜默,錯誤發現機制就會被觸發。當服務A沒有收到來自服務B的,並且超時就會觸發。
若是服務被全部的成員隔離,並懷疑全部的node都是錯誤的。就不能被group保護,懷疑是無效的。當服務被懷疑,那麼就不能再執行任何本地事務。
MySQL Group Replication管理到Group成員服務,這個服務是內置的插件,定義了那個服務是在線的,能夠投票的。在線的服務被稱爲view。所以每一個group內的服務都有一個同樣的view,表示那個服務是活動的。
全部服務須要統一的不僅僅是事務提交,還有當前的view。所以若是全部贊成一個新的服務的加入,而後Group從新配置,加入這個服務,而且出發view的修改。當服務離開group的時候也會發生,而後group重排配置,而且出發view的修改。
當一個成員自覺的離開group,會先初始化Group的從新配置。而後出發一個過程,除了一開的服務以外,其餘服務都要贊成,若是成員是由於故障一開的,錯誤發現機制發現問題,而且發出從新配置的提議。須要全部的服務贊成,若是不能贊成那麼group的配置就沒法修改。也就是說管理員須要手工來修復。
Group Replication實現了Paxos分佈式算法來提供服務的分佈式服務。要求大多數的服務活動以達到大多數,來作個決定。直接影響了系統能夠容忍的錯誤容錯公司以下,服務器n,容錯f:n = 2 x f + 1
也就是說,容忍一個錯誤那麼group必需要有3個成員。由於就算有一個錯了,還有2個,任然能夠造成大多數來處理一些事情。若是另一個也掛, 那麼就剩下一個,不發造成大多數(大於半數)。
Group Size |
Majority |
Instant Failures Tolerated |
1 |
1 |
0 |
2 |
2 |
0 |
3 |
2 |
1 |
4 |
3 |
1 |
5 |
3 |
2 |
6 |
4 |
2 |
7 |
4 |
3 |
每一個實例能夠運行在單個機器上,能夠在同一個機器上。
第一步不是三個實例。Group Replication是MySQL內部的插件,MySQL 5.7.17以後版本都開始有。
mkdir data
mysql-5.7/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-5.7 --datadir=$PWD/data/s1
mysql-5.7/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-5.7 --datadir=$PWD/data/s2
mysql-5.7/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-5.7 --datadir=$PWD/data/s3
配置服務的基本配置:
[mysqld]
# server configuration
datadir=<full_path_to_data>/data/s1
basedir=<full_path_to_bin>/mysql-5.7/
port=24801
socket=<full_path_to_sock_dir>/s1.sock
配置複製相關,並啓動GTID
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
Group Replication配置
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "127.0.0.1:24901"
loose-group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"
loose-group_replication_bootstrap_group= off
第一行:全部的寫入的事務的write set使用XXHASH64進行編碼。
第二行:要加入的group的名字
第三行:服務啓動後,不自動啓動
第四行:使用127.0.0.1,端口爲24901,來接入group成員的鏈接。
第五行:當加入一個group時,須要鏈接的host,只須要鏈接一個,而後該階段會要求group從新配置,容許服務器加入到group。當多個服務同時要求加入group,保證用的seed已經在group 中。
第六行:插件是否關聯到group,這個參數很重要,必須只有一個服務使用,否則會出現主分裂的狀況,就是不一樣的group有相同的Group名字。第一個服務實例online以後就禁用這個選項。
Group Replication使用異步複製的協議,處理分佈的恢復,來同步將要加入group的成員。分佈的恢復處理依賴於複製通道,group_replication_recovery 用來在group成員之間作傳輸。所以須要一個複製用戶和足夠的權限,用戶成員之間的恢復複製通道。
建立一個擁有REPLICATION_SLAVE權限的用戶,可是這個過程不能被binlog捕獲。
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0,00 sec)
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'rpl_pass';
Query OK, 0 rows affected (0,00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
Query OK, 0 rows affected, 1 warning (0,00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0,00 sec)
mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0,00 sec)
配置好以後,使用change master to語句配置服務
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' \\
FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0,01 sec)
分佈式恢復的第一步就是把服務加入到Group中,若是帳號和權限設置的不對那麼沒法運行恢復進程,最重要的是沒法加入到group。相似的,若是成員不能正確的經過host識別其餘成員那麼恢復進程也會錯誤。能夠經過performance_schema. replication_group_members查看host。可使用report_host區別開來。
弄完上面的配置,而且啓動後,鏈接到服務,執行一下命令:
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
安裝好以後能夠經過show plugins查看,若是安裝成功就會在返回中。
啓動group,讓s1關聯group而且啓動Group Replication。這個關聯要單個服務器完成,而且只能啓動一次。因此這個配置不能保存在配置文件中,若是保存了,下次啓動會自動關聯到第二個Group,而且名字是同樣的。若是開關plugin,可是參數是ON的也會有這個問題。
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
一旦start完成,就能夠查到成員了:
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| group_replication_applier | ce9be252-2b71-11e6-b8f4-00212844f856 | myhost | 24801 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
1 row in set (0,00 sec)
增長一些數據:
mysql> CREATE DATABASE test;
Query OK, 1 row affected (0,00 sec)
mysql> use test
Database changed
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
Query OK, 0 rows affected (0,00 sec)
mysql> INSERT INTO t1 VALUES (1, 'Luis');
Query OK, 1 row affected (0,01 sec)
這個時候已經有一個成員了s1,已經有了一些數據,如今加入其它節點到Group
增長s2 到group,設置配置文件,基本和s1的一直,修改server_id,由於文檔中是本地多實例,須要修改datadir等信息。
設置用於複製的用戶:
SET SQL_LOG_BIN=0;
CREATE USER rpl_user@'%';
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%' IDENTIFIED BY 'rpl_pass';
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' \\
FOR CHANNEL 'group_replication_recovery';
而後啓動
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0,01 sec)
這裏和s1不同的地方。
START GROUP_REPLICATION;
經過 performance_schema.replication_group_members 檢查成員是否是正常。
查看以前s1插入的數據時候已經徹底同步過來。
使用performance schema 上的表來監控Group Replication,若是有performance_ schema那麼就會在上面建立來個表:
· performance_schema.replication_group_member_stats
· performance_schema.replication_group_members
· performance_schema.replication_connection_status
· performance_schema.replication_applier_status
· group_replication_recovery
· group_replication_applier
Field |
Description |
Channel_name |
Group Replication通道名 |
Member_id |
成員的uuid |
Count_transactions_in_queue |
未通過沖突檢查的事務數量 |
Count_transactions_checked |
經過沖突檢查的事務數量 |
Count_conflicts_detected |
沒有經過沖突檢查的事務數量 |
Count_transactions_rows_validating |
衝突檢查數據庫的大小 |
Transactions_committed_all_members |
成功提交到成員的事務數量 |
Last_conflict_free_transaction |
最後一次衝突,被釋放的事務 |
Field |
Description |
Channel_name |
通道名 |
Member_id |
成員uuid |
Member_host |
成員host |
Member_port |
成員端口 |
Member_state |
成員狀態 (which can be ONLINE, ERROR, RECOVERING, OFFLINE or UNREACHABLE). |
Field |
Description |
Channel_name |
通道名 |
Group_name |
Group名 |
Source_UUID |
Group的標識 |
Service_state |
查看服務是不是group成員{ON, OFF and CONNECTING}; |
Received_transaction_set |
已經被該成員接受的gtid集 |
Field |
Description |
Channel_name |
通道名 |
Service_state |
服務狀態 |
Remaining_delay |
是否配置了延遲 |
Count_transactions_retries |
重試執行的事務個數 |
Received_transaction_set |
已經被接收的gtid集 |
表replication_group_members在view發生變化的時候就會修改,好比group的配置動態變化。若是出現網絡分離,或者服務離開group,信息就會被報告,根據不通的服務得到的信息不通。注意若是服務離開了group,那麼就沒法得到其餘服務的信息。若是發生分離,好比quorum丟失,服務就不能相互進行協同。也就是說會報告unreachable而不會一個假設狀態。
Field |
Description |
Group Synchronized |
ONLINE |
服務online能夠提供所有服務 |
Yes |
RECOVERING |
成員正在恢復,以後會變成online黃臺 |
No |
OFFLINE |
插件已經安裝,可是成員不屬於任何group |
No |
ERROR |
在recovery階段或者應用修改的時候,出現錯誤 |
No |
UNREACHABLE |
錯誤排查懷疑服務沒法鏈接。 |
No |
Group Replication有2個不一樣的模式:
1. 單主模式
2. 多主模式
默認是單主模式的,不能的模式不能出如今一個group中,好比一個成員是單主,一個成員是多主。切換模式須要從新配置,而後重啓。無論什麼模式,Group Replication都不支持failover。這個必須由程序本身來處理,或者用其餘中間件。
當不是了多主,語句是能夠兼容的,當在多主模式,如下狀況是會被檢查語句的:
1. 若是一個事務執行在serializable隔離級別,可是提交失敗
2. 若是事務執行的表有外鍵,可是提交失敗
固然檢查能夠經過group_replication_enforce_update_everywhere_checks來關閉。
在單主模式下,只有主是能夠讀寫的,其餘都只能讀取。這個設置是自動的。主一般是關聯到group的,其餘的成員join,自動學習主,而且設置爲只讀。
在單主模式下,多主的檢查被取消,由於系統只有一個服務是可寫的。當主成員失敗,自動主選舉機制會選取新的主。而後新竹根據成員的uuid進行排序而後選擇第一個。
當主離開Group,也會選舉新主,一旦新主被選出來以後,就會設置可讀寫,其餘任然是從。
在多主模式下,和單主不通,不須要選舉產生多主,服務沒有特定的角色。全部的服務都是可讀寫的。
Primary 能夠經過show status 或者select查找:
mysql> SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member';
+--------------------------------------+
| VARIABLE_VALUE |
+--------------------------------------+
| 69e1a3b8-8397-11e6-8e67-bf68cbc061a4 |
+--------------------------------------+
1 row in set (0,00 sec)
當一個新的成員要加入到group,會鏈接到一個合適的donor而且獲取數據,成員會一直獲取直到狀態變爲online。
Donor選擇
Donor選擇是隨機的在group中選一個成員。同一個成員不會被選擇屢次。若是鏈接到donor失敗,那麼會自動或去鏈接新的donor,一旦超過鏈接重試限制就會報錯。
強制自動Donor切換
出現如下問題的時候會自動切換到一個新的donor,並嘗試鏈接:
1. 清理數據場景,若是被選擇的donor包含數據清理,可是是recovery須要的,那麼會產生錯誤而且,獲取一個新的donor。
2. 重複數據,若是一個joiner已經包含了一些數據,和selected的有衝突,那麼也會報告錯誤,而且選擇一個新的donor。
3. 其餘錯誤,任何recovery線程的錯誤都會觸發,鏈接一個新的donor。
Donor鏈接重試
Recovery數據的傳輸是依賴binlog和現存的MySQL複製框架,所以可能會有一些傳輸問題致使receiver或者applier有問題。這個時候會有donor切換。
重試次數
默認從donor pool裏面能夠嘗試10次鏈接,也能夠經過參數修改,一下腳本設置成了10次:
SET GLOBAL group_replication_recovery_retry_count= 10;
Sleep Routines
經過參數設置:
SET GLOBAL group_replication_recovery_reconnect_interval= 120;
設置爲120秒,只有當joiner嘗試鏈接了全部的donor,可是沒有合適的,而且沒有剩餘的,那麼按照參數來sleep。
Replication_group_members包含了當前view裏面的全部服務的和服務的狀態。大多數狀況下服務運行是正常的,因此這個表對全部服務來講是一致的。若是出現網絡隔離,那麼quorum就會丟失,而後表上回顯示UNREACHABLE。
好比有個場景有5個服務,而後由於事故,其中3個丟失:
· Server s1 with member identifier 199b2df7-4aaf-11e6-bb16-28b2bd168d07
· Server s2 with member identifier 199bb88e-4aaf-11e6-babe-28b2bd168d07
· Server s3 with member identifier 1999b9fb-4aaf-11e6-bb54-28b2bd168d07
· Server s4 with member identifier 19ab72fc-4aaf-11e6-bb51-28b2bd168d07
· Server s5 with member identifier 19b33846-4aaf-11e6-ba81-28b2bd168d07
丟失以前的狀態:
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | 127.0.0.1 | 13002 | ONLINE |
| group_replication_applier | 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | 127.0.0.1 | 13001 | ONLINE |
| group_replication_applier | 199bb88e-4aaf-11e6-babe-28b2bd168d07 | 127.0.0.1 | 13000 | ONLINE |
| group_replication_applier | 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | 127.0.0.1 | 13003 | ONLINE |
| group_replication_applier | 19b33846-4aaf-11e6-ba81-28b2bd168d07 | 127.0.0.1 | 13004 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
5 rows in set (0,00 sec)
而後由於事故quorum丟失:
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | 127.0.0.1 | 13002 | UNREACHABLE |
| group_replication_applier | 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | 127.0.0.1 | 13001 | ONLINE |
| group_replication_applier | 199bb88e-4aaf-11e6-babe-28b2bd168d07 | 127.0.0.1 | 13000 | ONLINE |
| group_replication_applier | 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | 127.0.0.1 | 13003 | UNREACHABLE |
| group_replication_applier | 19b33846-4aaf-11e6-ba81-28b2bd168d07 | 127.0.0.1 | 13004 | UNREACHABLE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
5 rows in set (0,00 sec)
由於大多數已經丟失,因此Group就沒法繼續運行。爲了讓Group恢復運行須要重置group成員列表。或者關閉s1,s2的group replication,而後解決s3,s4,s5出現的問題,而後重啓group replication。
Group Replication能夠強制成員配置來重置。一下場景只有S1,S2,就能夠強制成員列表,經過設置變量group_replication_force_members變量。
假設S1,S2存活,其餘都非預期退出group,想要強制成員只有S1,S2。
首先查看S1上的成員列表:
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | 127.0.0.1 | 13002 | UNREACHABLE |
| group_replication_applier | 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | 127.0.0.1 | 13001 | ONLINE |
| group_replication_applier | 199bb88e-4aaf-11e6-babe-28b2bd168d07 | 127.0.0.1 | 13000 | ONLINE |
| group_replication_applier | 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | 127.0.0.1 | 13003 | UNREACHABLE |
| group_replication_applier | 19b33846-4aaf-11e6-ba81-28b2bd168d07 | 127.0.0.1 | 13004 | UNREACHABLE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
5 rows in set (0,00 sec)
而後從S1,S2中獲取@@group_replication_local_address,而後設置到變量中
mysql> SELECT @@group_replication_local_address;
+-----------------------------------+
| @@group_replication_local_address |
+-----------------------------------+
| 127.0.0.1:10000 |
+-----------------------------------+
1 row in set (0,00 sec)
mysql> SELECT @@group_replication_local_address;
+-----------------------------------+
| @@group_replication_local_address |
+-----------------------------------+
| 127.0.0.1:10001 |
+-----------------------------------+
1 row in set (0,00 sec)
mysql> SET GLOBAL group_replication_force_members="127.0.0.1:10000,127.0.0.1:10001";
Query OK, 0 rows affected (7,13 sec)
檢查members
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | 127.0.0.1 | 13000 | ONLINE |
| group_replication_applier | b60907e7-4ab6-11e6-afb7-28b2bd168d07 | 127.0.0.1 | 13001 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
2 rows in set (0,00 sec)
當強制一個新的成員配置,要保證其餘服務是中止了。在場景中S3,S4,S5若是不是真的unreachable實際上是online的,那麼他們本身就會已造成一個功能分區。這樣強制成員可能會形成主分隔的狀況。所以保證其餘服務是關閉的很重要,若是沒有,那麼就手工關閉他們。
IP白名單,是容許其餘程序或者服務鏈接group Replication的設置。默認是內網,show的時候顯示AUTOMATIC,參數是grou_replication_ip_whitelist。若s1設置了,s2鏈接的時候,會先去查看白名單,而後再考慮是否接受s2的鏈接。
默認配置顯示AUTOMATIC,能夠經過錯誤日誌查看:
2016-07-07T06:40:49.320686Z 4 [Note] Plugin group_replication reported: 'Added automatically \\
IP ranges 10.120.40.237/18,10.178.59.44/22,127.0.0.1/8 to the whitelist'
爲了更加安全能夠手動設置這個白名單
mysql> STOP GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_ip_whitelist="10.120.40.237/18,10.178.59.44/22,127.0.0.1/8";
mysql> START GROUP_REPLICATION;
MySQL Group Replication支持openssl和yassl。Group鏈接和recovery鏈接均可以使用ssl。
Recovery配置SSL
Recovery是經過傳統的異步複製鏈接執行的。一旦選擇好了donor,就會建立一個異步複製鏈接。那麼須要給用戶配置ssl。
donor> SET SQL_LOG_BIN=0;
donor> CREATE USER 'rec_ssl_user'@'%' REQUIRE SSL;
donor> GRANT replication slave ON *.* TO 'rec_ssl_user'@'%';
donor> SET SQL_LOG_BIN=1;
而後配置一些相關參數。
new_member> SET GLOBAL group_replication_recovery_use_ssl=1;
new_member> SET GLOBAL group_replication_recovery_ssl_ca= '.../cacert.pem';
new_member> SET GLOBAL group_replication_recovery_ssl_cert= '.../client-cert.pem';
new_member> SET GLOBAL group_replication_recovery_ssl_key= '.../client-key.pem';
而後在change master to 鏈接過去。
new_member> CHANGE MASTER TO MASTER_USER="rec_ssl_user" FOR CHANNEL "group_replication_recovery";
new_member> START GROUP_REPLICATION;
Group鏈接配置SSL
Group 鏈接配置ssl和服務有關,若是服務支持,那麼group也就支持,那麼配置服務的SSL須要配置這些參數:
[mysqld]
ssl_ca = "cacert.pem"
ssl_capath = "/.../ca_directory"
ssl_cert = "server-cert.pem"
ssl_cipher = "DHE-RSA-AEs256-SHA"
ssl_crl = "crl-server-revoked.crl"
ssl_crlpath = "/.../crl_directory"
ssl_key = "server-key.pem"
group_replication_ssl_mode= REQUIRED
略,本身看:
https://dev.mysql.com/doc/refman/5.7/en/group-replication-options.html
基礎要求:
1. innodb存儲引擎:由於若是出現衝突須要回滾,那麼存儲引擎要支持事務。
2. 主鍵,由於判斷是否衝突須要用到主鍵
3. IPv4,目前只支持ipv4
4. 網絡性能,由於group Replication是一個集羣因此對網絡帶寬要求可能比較高。
服務參數設置:
1. 啓動binlog,由於group Replication仍是依賴binlog進行數據同步的。
2. Slave update logs,由於新加入的服務須要recovery,須要用到binlog,若是選中了donor是slave,那麼就有用了
3. 啓動GTID,group Replication的event應用都是依賴GTID的。
4. 複製信息存儲方式,複製信息都要求保存在表上。
5. Transaction write set extraction,寫事務提取,這裏都用XXHASH64.
6. 多線程,group成員能夠開多線程 applier。須要設置3個參數
slave-parallel-workers=N:線程數量
slave-preserve-commit-order=1:由於group Replication要保證成員事務提交順序要和primary同樣,所以須要設置。
slave-parallel-type=logical_clock表示能夠併發的事務
Group Replication有這麼一些限制:
1. replication event checksum,由於涉及的問題,group replication不能使用event checksum
2. gap lock,檢驗進程不使用gap lock,由於才能更好的檢查衝突問題。
3. 表鎖和命名鎖,檢驗進程不使用表鎖和命名鎖。
4. SERIALIZABLE隔離級別,在多主group replication默認是不支持的,若是設置了就會不讓提交。
5. 併發DDL和DML,多主DDL和DML在不一樣服務器併發是不支持的。這樣不一樣服務執行相同object的DDL和DML會引發衝突。
6. 外鍵和級聯,多主模式下不支持多級別的外鍵依賴,特別是定義了級聯的外鍵。由於外鍵約束,多主狀況下,外鍵的級聯操做會形成沒法診斷的衝突問題,因此建議使用group_replication_enforce_update_everywhere_checks=ON來解決不可發現的衝突問題。
7. 大事務,由於事務太大,會致使沒法在成員間5秒鐘內複製完,那麼就會發生錯誤。
https://dev.mysql.com/doc/refman/5.7/en/group-replication-frequently-asked-questions.html
Group Replication是MySQL的一個插件,基於binary log,行模式,GTID。集成了當前的MySQL平臺,好比performance schema,Group Replication結構如圖:
從圖的上面開始,
Capture組件:用來跟着事務執行的上下文
Applier組件:負責執行遠程事務
Recovery組件:當服務join到group的時候,用來恢復數據,而且捕獲錯誤。
下面是複製協議邏輯,處理衝突診斷,接受和傳播事務到group。
下面綠色是爲上面高級別的API提供底層服務。
MySQL Group Replication,是一批服務組成。有一個uuid的group名。Group是動態的服務能夠離開或者加入。Group會服務加入或者離開的時候調整本身。
若是一個服務加入group,會自動從已經存在的服務上獲取數據,追上來。這個同步狀態是異步的。若是服務離開group,剩下的服務會發現而且從新配置group。
在多主下,任何服務均可以插入數據,任何服務在沒有協調下均可以運行事務,可是事務提交須要服務協調並決定事務去留。
協調的目的:
1. 檢查事務是否應該被提交
2. 傳播事務到其餘服務而且應用
事務傳播是原子性的,要不所有接受,要不所有不接受。若接受就會以相同的順序接受事務。衝突發現是經過比較和檢查事務的寫入集實現。若是出現衝突解決方式是保留第一個提交的事務。
DDL語句,目前不支持原子性或者事務性,所以一旦執行,若是不要了不能回滾。所以DDL的語句執行,包含了這個object的數據的修改要在同一個服務上。單主的group Replication是不會有問題的。
MySQL DDL是不支持事務的。服務執行提交沒有group的贊成的,所以必須把DDL和包含這個object的DML放在一個服務上運行。
Group Replication分佈式recovery過程,用來同步joiner和donor之間的數據。大概分爲2個步驟:
階段1
這個階段joiner選擇一個group中的成員做爲donor,而後donor把joiner沒有的數據同步給joiner,這個同步是異步的。主要是經過binary log進行同步數據。
在binary log同步的時候,joiner會緩存group交換的事務。當從donor的binary log運行完以後,進入第二階段
階段2
這個階段joiner,應用以前緩存起來的事務,應用完成以後,定義爲online
Resilience
在階段1,Recovery過程碰到donor出現錯誤的時候,會切換到另一個新的donor。
使用donor把 joiner同步到指定的點,donor和joiner使用GTID機制。可是單單GTID是不夠的,由於GTID只能提供joiner丟失哪一個事務。不能用來標記,要更新到哪一個點,也不能用來傳輸認證信息。
View 和 View Change
View:當前可用服務的列表
View change:表示發生修改的發生,好比join或者leave
View標識符:是view的惟一標識,在view修改的時候生成。
在group交互層,view修改會有各自的view id來區別修改view的修改前和修改後。
View標識符由2個部分組成:1.隨機數,由group生成,2.自增。Group生成的隨機數,會一直保留知道group消亡,第二部分在view每次修改的時候都會自增。
使用2個部分來表示view標識符,主要是爲了表示清楚group修改,實際上,只使用自增會致使view標識符和以前的group重複,破壞了binary log數據的惟一性。
開始:穩定的Group
開始是一組穩定的online的group,每一個服務都是online的。
View Change:成員加入
當有一個新的成員加入,view change 開始執行,每一個online服務隊會隊列一個view change log event。爲啥要隊列,由於有其餘事物可能也在隊列上,而且是屬於老的view的。
不僅僅如此,joiner會選擇一個group 裏面的online成員做爲donor,來同步數據.
開始傳輸:Catching Up
一旦joiner選擇了一個donor,就會創建一個異步的複製鏈接,用來同步binlog數據。直到線程處理到view change log event。
View id會在同時傳輸到全部的成員,joiner知道到那個view id複製要他中止。View id能夠明確,哪些數據屬於哪一個view。當joiner同步donor的數據的時候也會緩存,過來的事務。同步中止後,會應用這些事務。
最後:Caught Up
當joiner發現view change log event是預期的view id,鏈接到donor會被中斷,並開始應用緩存的事務。儘管在binlog中只是一個標記,表示view修改。也能用來確認新成員加入到group。若是沒有,joiner就沒有足夠的信息來肯定,加入以後的事務。
Catch up的時間,由事務生成的速度決定。在應用到時候是不會影響其餘成員的事務。
分佈式Recovery有一些限制,就是由於是基於異步複製的,所以若是當使用較老的備份或者鏡像來作新的成員,就會致使階段1的時間會很長。所以建議使用較新的備份和鏡像,減小階段1的時間。
https://dev.mysql.com/doc/refman/5.7/en/group-replication-observability.html
Group交互線程GCT,是循環運行的。FCT接受來自group和插件的消息,控制quorum和錯誤發現,發送一些keep alive消息,而且處理進出的事務。GCT等待incoming消息隊列。當沒有消失的時候,GCT會等待,讓GCT在進入sleep,多自旋一下子可能在某些case會更好些。由於sleep會切出cpu。能夠經過參數來設置自旋的時間:
mysql> SET GLOBAL group_replication_poll_spin_loops= 10000;
當出現網絡帶寬的瓶頸,消息壓縮在group交互層能夠提供30-40%的吞吐量提高。
TCP是點對點的,當有N個鏈接,那麼就要發N次信息。由於binary log量大,壓縮率也很高,所以對大事務來講是一個強制的特性。
壓縮發生在group交互引擎層,在數據被GCT處理前,因此他的上下文是mysql用戶會話線程。壓縮根據閥值來配置,默認都是壓縮的。也沒有要求group中全部的成員都必須啓動壓縮才能使用。當收到一個消息的時候,成員檢查消息頭,看看是否是壓縮的,若是是那麼進行解壓。
壓縮算法使用LZ4。默認壓縮閥值是1000000字節。壓縮閥值能夠經過參數設置,一旦失誤超過這個閥值就會被壓縮。
STOP GROUP_REPLICATION;
SET GLOBAL group_replication_compression_threshold= 2097152;
START GROUP_REPLICATION;
這裏壓縮閥值是2MB,若是事務複製的消息大於2MB,就會壓縮。把參數設置爲0來取消壓縮。
https://dev.mysql.com/doc/refman/5.7/en/group-replication-flow-control.html