天天看點

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

官網下載下傳 mysql

https://www.mysql.com/

現在企業中用的最多的也是5.6 5.7,我們下載下傳5.7版本的就可。

實驗環境:

server1 172.25.254.1 前三種複制方式中充當master結點

server2 172.25.254.2 前三中複制方式中充當slave結點

server3 172.25.254.3 再做全同步複制時開啟

在做實驗的時候每台主機之間必須有解析,因為後面的實驗會用到解析。

安裝mysql

下載下傳的 rpm-bundle 包裡面有:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

将他們用rpm的方式進行安裝。

它的配置檔案為 /etc/my.cnf

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

并且會自動生成 /var/log/mysqld.log 的日志檔案,并且會生成一個初始密碼:

[[email protected] ~]# cat /var/log/mysqld.log | grep password
2020-05-09T13:56:35.301030Z 1 [Note] A temporary password is generated for [email protected]: Khq*fpetp1S<
           

初次登陸它會警告我們更改密碼:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

進行安全初始化:

mysql_secure_installation 
           

這裡的密碼設定要求較高,需要設定的複雜一點 ,我的密碼為Cc990718-+

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

進行相關的設定就可以了。

登陸資料庫:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

就可以登陸了。

mysql中的鎖

對資料的操作其實隻有兩種,也就是讀和寫,而資料庫在實作鎖時,也會對這兩種操作使用不同的鎖,

  • 共享鎖(讀鎖),允許多個事務讀一行資料。Share Lock
  • 排他鎖(寫鎖),允許一個事務删除或更新一行資料,其他事物不可以在上鎖(讀或寫)。Exclusive Lock

mysql中的事務

事務: event ,具有四個個特性,原子性,隔離性,一緻性,持久性

是無就是一組原子性的SQL查詢,或者說一個獨立的工作單元。

如果資料庫引擎能夠成功地對資料庫進行該組查詢的全部語句,那麼就執行改組查詢,如果其中有任何一條語句因為崩潰或者其它原因而無法執行,那麼所有的語句都不會執行,也就是說,事務内的語句,要莫全部執行成功,要麼全部執行失敗。

mysql的主從複制(基于二進制日志)

主節點 server1 :172.25.254.1

從結點 server2 :172.25.254.2

原理:複制操作,不是複制資料,更穩定。

主節點先進行寫操作,然後會把操作記錄進二進制的日志檔案中,此時主節點的dump的線程會通知從結點的IO線程複制資料,IO線程就和master結點進行通信,然後把擷取到的二進制日志資料寫入到終繼日志(relay log)中,此時SQL線程會讀取中繼日志中的内容,在本機重新執行一次(replay)
mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

master 主節點中配置檔案:

vim /etc/my.cnf

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

然後打開資料庫,執行指令,為複制建立一個使用者:

# 建立repl使用者,%代表整個網段,Cc9為密碼
mysql> CREATE USER 'repl'@'172.25.254.%' IDENTIFIED BY 'Cc990718-+';
Query OK, 0 rows affected (0.00 sec)

#授權所有庫的所有表的複制權限給剛建立的使用者
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.25.254.%';
Query OK, 0 rows affected (0.00 sec)

SHOW MASTER STATUS;          擷取,目前二進制日志的檔案名稱和位置
           
mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

然後層測試使用repl使用者登入;

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

slave 從結點進行配置

配置檔案:vim /etc/my.cnf

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

登陸mysql執行指令:

mysql> CHANGE MASTER TO
    ->      MASTER_HOST='172.25.254.1',       主機名
    ->      MASTER_USER='repl',				使用者
    ->      MASTER_PASSWORD='Cc990718-+',	密碼
    ->      MASTER_LOG_FILE='mysql-bin.000001',		主節點擷取到的檔案名	
    ->      MASTER_LOG_POS=154;					主節點擷取到的檔案位置 
#CHANGE MASTER TO MASTER_HOST='172.25.254.1',MASTER_USER='repl',MASTER_PASSWORD='Cc990718-+',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;	
           
mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制
start slave;          開啟複制
show slave status\G    檢視slave結點狀态,可以看見SQL線程和IO線程都是yes ,則正常開啟複制
           
mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

IO 線程負責和master結點進行通信,SQL程序負責把通信得來的資料寫入到本機的資料庫。

檢視複制:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制
mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

在主節點建立的資料庫就可以在從結點看到了。

我們再在主節點建立一張表:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

在從結點檢視:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

這就說明主從複制是ok的,這就是基于二進制日志的主從複制.

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

這裡面是mysql的一些日志資訊,我們可以用 mysqlbinlog 讀取這些日志

基于全局事務辨別的複制GTID

避免了即與二進制檔案日志的複制的缺點:中途出現錯誤時事務就不能完整進行了,就成為了廢資料。

GTID的優點就就是把一個事物看成一個單元,要麼整體成功,要麼整體失敗。

在兩台主機上的配置檔案都加上GTID:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

然後再slave結點去配置基于gtid的自動位置識别:

先停掉上面的基于二進制檔案的slave:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

再修改複制的方式,開啟複制;

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制
mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

IO和SQL線程開啟。

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

跟蹤gtid 和執行gtid。

我們再次插入資料進行嘗試:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

插入user2,

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

這時slave結點也能看到了,

并且此時檢視狀态 ,

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

gtid捕捉到了一個事務:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

半同步複制 Semi-synchronous replication

傳統的複制原理:

master的新事務 t1 -> binlog buffer(緩沖區) -> dumper -> slave

binlog buffer(check) -> slave(IO) -> relay log -> SQL -> mysql

  • 傳統的幾種複制方式存在一個普遍的問題,就是如果master主節點執行一個比較大的任務時,slave主機的複制會消耗系統資源,會有一些延遲,這個時候如果slave還沒有複制完成時master結點就挂掉了,這時還沒有完成複制的slave就被迫成為新的master主機,這樣的方式就會丢失資料。
  • 這樣是有很大的缺陷的,是以mysql在5.5本本後就退出了這個半同步複制,相比于異步複制(GTID,二進制日志)提高了資料的完整性。
  • 也就是說master的dumper線程在通知slave之後會接收slave的ack的确認消息,ack 就是是否成功收到 t1 的标志,slave結點再把所有的 binlog 的資料記錄到relay log 中後才會傳回ack給dumper線程。
  • 如果沒有收到ack信号就進入到等待,直到接至少接收到一個ack信号為止(slave結點可能由有多個),如果等待逾時,就降級為普通的異步複制,接收到了ack就說明slave結點接收到了完整的 t1 ,就繼續進行新的事務。

在主節點安裝插件:

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.16 sec)
           

在每個子結點安裝插件:

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.03 sec)
           
mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制
mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

插件安裝完成。

激活插件:

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

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

slave 結點重新開機IO線程:

mysql> stop slave IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> start slave IO_THREAD;
Query OK, 0 rows affected (0.00 sec)
           

在master結點檢視狀态:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

功能打開,且又一個用戶端在半同步複制。

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

功能打開,逾時時間為10s。

slave結點檢視:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

現在在主節點插入資料測試:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制
mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

複制正常,但我們怎樣測試接收的ack信号哪?,我們關閉slave結點的IO線程。

mysql> stop slave io_thread;
Query OK, 0 rows affected (0.04 sec)
           

然後再次在追結點插入資料。

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

可見此時等待了10s才結束的,這時就已經切換到了異步複制了。

再次插入:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

就又非常快了,因為已經到了異步複制了。

但這時我們在slave主機看不到剛才插入的兩條資料:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

我們再開啟slave結點上的IO線程:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

可見資料就又回來了。

全同步複制,組複制

group replication。銀行機構一般會使用全同步。

組複制不同與半同步複制的地方在于,master結點會接收到所有的slave結點的ack信号時才會開始下一步。而半同步隻要求接收到 >= 一個的信号就可以了。由于每台結點的内容都一樣,是以每台結點主機都可以作為master結點。

我們開啟第三台虛拟機: server3 172.25.254.3 作為第二個slave結點。

在三個結點中進行配置:

關閉資料庫,并清空之前的資料。

systemctl stop mysqld
rm -fr /var/lib/mysql/*
           

配置檔案:

删除前面的配置,并添加下面的配置:

vim /etc/my.cnf

server1 :

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

plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="1d630e12-92a0-11ea-943f-525400685c65"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "172.25.254.1:33061"
loose-group_replication_group_seeds= "172.25.254.1:33061,172.25.254.2:33061,172.25.254.3:33061"     # 主機組
loose-group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist='127.0.0.1,172.25.254.0/24'
loose-group_replication_enforce_update_everywhere_check=ON
loose-group_replication_single_primary_mode=OFF         關閉單主機模式,
           

server2:

server_id=2            這裡的id不能和上面相同
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

plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="1d630e12-92a0-11ea-943f-525400685c65"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "172.25.254.2:33061"       本地ip
loose-group_replication_group_seeds= "172.25.254.1:33061,172.25.254.2:33061,172.25.254.3:33061"
loose-group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist='127.0.0.1,172.25.254.0/24'
loose-group_replication_enforce_update_everywhere_check=ON
loose-group_replication_single_primary_mode=OFF
           

做完後我們啟動mysqld ,并重新進行初始化,因為我們剛才删除了全部的檔案,是以會重新生成初始密碼,我們進行更改(三台主機都做):

mysql> alter user [email protected] identified by 'Cc990718-+';
Query OK, 0 rows affected (0.10 sec)
           

在mysql中進行配置:

server1:

#關閉二進制日志,防止中間三步産生的日志資料傳輸混亂
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

#建立使用者
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Cc990718-+';
Query OK, 0 rows affected (0.00 sec)

#授權所有庫所有表
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
Query OK, 0 rows affected (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)

#更改master使用者,并指定組複制的插件。
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Cc990718-+' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.25 sec)

#安裝組複制的插件
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

#發起組複制,生成組名,隻能再一個結點開啟, 這裡我們選擇server1
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)

#啟動組複制
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (2.56 sec)

#關閉這個是因為這個參數會再每次開啟組複制時生成一個組名,這樣就混亂了,是以我們開啟一次就關閉。
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)

#擷取組資訊,目前隻有一台
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 26ff60fd-92a1-11ea-9713-525400e49b44 | server1     |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.00 sec)

           

然後我們把server2 和server3 加進組去,和上面相同的操作:

server2和server3:

mysql> SET SQL_LOG_BIN=0;

mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Cc990718-+';

mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';

mysql> FLUSH PRIVILEGES;

mysql> SET SQL_LOG_BIN=1;

mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Cc990718-+' FOR CHANNEL 'group_replication_recovery';

INSTALL PLUGIN group_replication SONAME 'group_replication.so';

mysql> START GROUP_REPLICATION;

## 如果報錯,先關閉組複制,再執行這條指令,這是由于資料沖突産生的
set global group_replication_allow_local_disjoint_gtids_join=on;
           

這時我們再server1檢視組:

server2和server3就加進去了。

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

這時我們就可以輸入資料進行測試了:

再server1中插入資料:

再server3中插入資料:

在server2中檢視:

mysql的多種主從複制詳解安裝mysqlmysql中的鎖mysql中的事務mysql的主從複制(基于二進制日志)基于全局事務辨別的複制GTID半同步複制 Semi-synchronous replication全同步複制,組複制

發現所有的組内的主機的資料都是一樣的。

這樣的方式是因為我們在哪一台主機上插入資料,那一台主機就是master主機。這就是組複制的原理。