023、半同步複製+GTID複製
阿新 • • 發佈:2021-07-26
半同步複製
半同步複製 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、從庫安裝外掛3、開啟半同步複製開關主庫執行:mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; Query OK, 0 rows affected (0.09 sec)
從庫執行: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)
4、檢視引數狀態主庫檢視狀態: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;
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。
- 在解析過程中會判斷是否有主鍵,如果沒有就用二級索引,如果沒有就用全部掃描。
[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 語句均不受支援。
來自為知筆記(Wiz)