1. 程式人生 > 其它 >023、半同步複製+GTID複製

023、半同步複製+GTID複製

半同步複製

半同步複製 mysql 5.5之後,非同步複製的基礎之上,(已搭好主從的基礎上)搭建半同步複製。
1、主庫安裝外掛
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.12 sec)
--若解除安裝:uninstall plugin rpl_semi_sync_master.
2、從庫安裝外掛
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.09 sec)
3、開啟半同步複製開關主庫執行:
mysql> show 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.08 sec)

mysql> set global rpl_semi_sync_master_enabled=on;
Query OK, 0 rows affected (0.02 sec)
從庫執行:
mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | OFF   |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)

mysql> set global rpl_semi_sync_slave_enabled=on;
4、檢視引數狀態主庫檢視狀態:
mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| 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.09 sec)
從庫檢視狀態:
mysql> show global status like '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF   |
+----------------------------+-------+
1 row in set (0.05 sec)
狀態是off,原因是:未啟用,需要重啟主從。從庫重啟主從之後再檢視:
mysql> stop slave;
Query OK, 0 rows affected (0.02 sec)

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

mysql> show global status like '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)
主庫檢視:
mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| 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.00 sec)
--連線數為1
5、驗證從庫執行:
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 192.168.100.111
                  Master_User: uslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000008
          Read_Master_Log_Pos: 949
               Relay_Log_File: localhost-relay-bin.000003
                Relay_Log_Pos: 283
        Relay_Master_Log_File: mysql-bin.000008
             Slave_IO_Running: No
            Slave_SQL_Running: Yes
該操作會導致binlog內容無法傳遞。主庫執行插入操作:
mysql> insert into t select 2;
Query OK, 1 row affected (10.21 sec)
Records: 1  Duplicates: 0  Warnings: 0
可以看到,簡單的插入操作,等待了10秒。半同步複製關閉:
mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| Rpl_semi_sync_master_net_avg_wait_time     | 655   |
| Rpl_semi_sync_master_net_wait_time         | 655   |
| Rpl_semi_sync_master_net_waits             | 1     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 1     |
| Rpl_semi_sync_master_status                | OFF   |
| 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.00 sec)
從庫開啟io thread之後,恢復正常:
mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)
mysql> show global status like '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)
這也是半同步複製的缺點,網路不好時,與非同步複製互相切換,影響業務。

檢視主從延遲

1、從庫檢視主從同步狀態
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.100.111
                  Master_User: uslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000006
          Read_Master_Log_Pos: 120
               Relay_Log_File: localhost-relay-bin.000012
                Relay_Log_Pos: 283
        Relay_Master_Log_File: mysql-bin.000006
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 120
              Relay_Log_Space: 623
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 3
                  Master_UUID: d11d7e9d-a69e-11eb-ac06-080027d46e3d
             Master_Info_File: /u01/data/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
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (0.00 sec)
主要看兩個引數:Read_Master_Log_Pos,Exec_Master_Log_Pos,若前者比較大,則有延遲。若兩個引數值相同,則沒有延遲。次要看引數:Seconds_Behind_Master,該引數供參考,不太準確。若該引數值很大,則證明有延遲的存在。2、使用percona工具的命令工具下載地址:https://www.percona.com/downloads/percona-toolkit/LATEST/安裝該工具:
[root@localhost soft]# yum install percona-toolkit-3.3.1-1.el7.x86_64.rpm
3、使用工具監控延遲主庫執行
[root@localhost ~]# pt-heartbeat --database=test --update --create-table --daemonize -uroot -proot
意思是:在test庫下建立心跳錶,並實時更新。
mysql> select * from heartbeat;
+----------------------------+-----------+------------------+----------+-----------------------+---------------------+
| ts                         | server_id | file             | position | relay_master_log_file | exec_master_log_pos |
+----------------------------+-----------+------------------+----------+-----------------------+---------------------+
| 2021-05-11T17:05:00.001120 |         3 | mysql-bin.000010 |    37435 | NULL                  |                NULL |
+----------------------------+-----------+------------------+----------+-----------------------+---------------------+
1 row in set (0.00 sec)
從庫執行
[root@localhost ~]# pt-heartbeat --master-server-id=3 --monitor --database=test -uroot -proot --defaults-file=/etc/my.cnf
需要指定主庫的server id,指定行為為監控。
:每秒鐘重新整理一次,結果顯示了延時的時間。

GTID複製

GTID(Global Transaction ID)是對於一個已提交事務的編號,並且是一個全域性唯一的編號。GTID實際上是由UUID+TID組成的。其中UUID是一個MySQL例項的唯一標識,儲存在mysql資料目錄下的auto.cnf檔案裡。TID代表了該例項上已經提交的事務數量,並且隨著事務提交單調遞增。MySQL 5.6.10之後,出現了GTID複製,區別於傳統複製(binlog+posititon),使用全域性事務號進行標識。藉助GTID,在發生主備切換的情況下,MySQL的其它Slave可以自動在新主上找到正確的複製位置,這大大簡化了複雜複製拓撲下叢集的維護,也減少了人為設定複製位置發生誤操作的風險。另外,基於GTID的複製可以忽略已經執行過的事務,減少了資料發生不一致的風險。搭建GTID複製,建議不要在現有的主從基礎上搭建,建議在新環境搭建。初始化從庫前,主庫的備份就不需要加--master-data引數了,因為GTID不支援binlog+position號。GTID的相關引數,需要修改配置檔案,並重啟資料庫才生效(5.7之後可以動態修改)。GTID的工作原理:
  • master更新資料時,會在事務前產生GTID,一同記錄到binlog日誌中。
  • slave端的i/o執行緒將變更的binlog,寫入到本地的relay log中。
  • sql執行緒從relay log中獲取GTID,然後對比slave端的binlog是否有記錄。
  • 如果有記錄,說明該GTID的事務已經執行,slave會忽略。
  • 如果沒有記錄,slave就會從relay log中執行該GTID的事務,並記錄到binlog。
  • 在解析過程中會判斷是否有主鍵,如果沒有就用二級索引,如果沒有就用全部掃描。
1、清理環境,從庫執行
[root@localhost ~]# pkill mysql
[root@localhost ~]# rm -rf /u01/data/mysql/
2、初始化資料庫
[root@localhost ~]# mkdir -p /u01/data/mysql
[root@localhost ~]# chown -R mysql:mysql /u01/data/mysql/
[root@localhost ~]# /usr/local/mysql/scripts/mysql_install_db --defaults-file=/etc/my.cnf --user=mysql --basedir=/usr/local/mysql --datadir=/u01/data/mysql
[root@localhost ~]# mysqld_safe --defaults-file=/etc/my.cnf &
3、主庫備份,從庫恢復
[root@localhost ~]# mysqldump --single-transaction -uroot -proot -A > /u01/bakdata/mysqldump/all_for_slave.sql 
Warning: Using a password on the command line interface can be insecure.
--不需要加--master-data,因為GTID不支援binlog+position號
[root@localhost ~]# scp /u01/bakdata/mysqldump/all_for_slave.sql 192.168.100.112:/u01/bakdata/mysqldump/
[email protected]'s password: 
all_for_slave.sql                                                               100%  639KB  20.7MB/s   00:00
[root@localhost ~]# mysql < /u01/bakdata/mysqldump/all_for_slave.sql
4、修改引數檔案,並重啟資料庫新增以下引數:
[root@localhost ~]# vi /etc/my.cnf
gtid_mode=on
log_slave_updates=1
enforce_gtid_consistency=1
重啟資料庫生效(5.7之後可以動態修改):
[root@localhost ~]# pkill mysql
[root@localhost ~]# mysqld_safe --defaults-file=/etc/my.cnf &
4、搭建主庫
主庫賦權:
mysql> grant replication slave on *.* to 'uslave'@'192.168.100.%' identified by 'uslave';
Query OK, 0 rows affected (0.02 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.04 sec)
從庫執行:
mysql> CHANGE MASTER TO MASTER_HOST='192.168.100.111',MASTER_USER='uslave',MASTER_PASSWORD='uslave',MASTER_PORT=3306,master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.07 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
從庫檢視狀態:
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.100.111
                  Master_User: uslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000012
          Read_Master_Log_Pos: 88357
               Relay_Log_File: localhost-relay-bin.000002
                Relay_Log_Pos: 88567
        Relay_Master_Log_File: mysql-bin.000012
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 88357
              Relay_Log_Space: 88775
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 3
                  Master_UUID: e1fe2aff-afc8-11eb-a7c9-08002765b4fe
             Master_Info_File: /u01/data/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
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: e1fe2aff-afc8-11eb-a7c9-08002765b4fe:1-241
            Executed_Gtid_Set: e1fe2aff-afc8-11eb-a7c9-08002765b4fe:1-241
                Auto_Position: 1
1 row in set (0.00 sec)
--最後可以看到事務ID

GTID侷限性

主庫執行:
mysql> create table t1 as select * from t;
ERROR 1786 (HY000): CREATE TABLE ... SELECT is forbidden when @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1.
GTID複製不支援這種sql語句。
  • 不支援 CREATE TABLE … SELECT 語句。 因為在 ROW 格式下,該語句將會被記錄為具有不同 GTID 的兩個事務,此時從伺服器將無法正確處理。
  • 事務,過程,函式和觸發器內部的 CREATE TEMPORARY TABLE 和 DROP TEMPORARY TABLE 語句均不受支援。
為防止執行不受支援的語句,建議配置和上文配置一樣,開啟 enforce-gtid-consistency 屬性, 開啟後在主庫上執行以上不受支援的語句都將丟擲異常並提示。GTID的優點:1.根據GTID可以知道事務最初是在哪個例項上提交的2.GTID的存在方便了Replication的Failover


來自為知筆記(Wiz)