赞
踩
这里讲的gtid是5.7版本的,5.7版本比5.6有一些增强,比如在线开启等
(Global Transaction ID)是全局事务ID,当在主库上提交事务或者被从库应用时,可以定位和追踪每一个事务,比如主库新事务都有一个全局ID,即使此事务被同步到任何从库上并应用都会标记着这个事务
GTID的组成: server_uuid:transaction_id,平时看到的gtid_executed或者Executed_Gtid_Set实际是个集合,m-n的方式,代表执行了事务m 到 事务n 这些ID
有了GTID对数据库分布式会有很大的帮助。尤其是复杂主从关系,我们可以省去手工去找偏移量,而是通过CHANGE MASTER TO MASTER_HOST=‘xxx’, MASTER_AUTO_POSITION=1的即可方便的搭建从库,在故障修复中也可以采用MASTER_AUTO_POSITION=‘X’的方式。
MySQL Server在写binlog的时候,会先写一个特殊的Binlog Event,类型为GTID_Event,指定下一个事务的GTID,然后再写事务的Binlog,主从同步时GTID_Event和事务的Binlog都会传递到从库,在从库应用Relay Log,从库在执行的时候也是用同样的GTID写binlog
1、CREATE TABLE … SELECT 复制表结构,复制数据
2、使用GTID复制模式时,不支持create temporary table 和 drop temporary table。但是在autocommit=1的情况下可以创建临时表,Master端创建临时表不产生GTID信息,所以不会同步到slave,但是在删除临时表的时候会产生GTID会导致,主从中断.
3、在一个事务中或语句中同时更新事务和非事务表,比如在一个事务中更新 innodb表和myisam表。要更新的所有非事务表是临时表除外
* 假设有4个binlog: bin.001,bin.002,bin.003,bin.004
* bin.001 : Previous-GTIDs=empty; binlog_event有:1-40
* bin.002 : Previous-GTIDs=1-40; binlog_event有:41-80
* bin.003 : Previous-GTIDs=1-80; binlog_event有:81-120
* bin.004 : Previous-GTIDs=1-120; binlog_event有:121-160
1. 假设现在我们要找GTID=$A,那么MySQL的扫描顺序为: 从最后一个binlog开始扫描(即:bin.004)
2. bin.004的Previous-GTIDs=1-120,如果$A=140 > Previous-GTIDs,那么肯定在bin.004中
3. bin.004的Previous-GTIDs=1-120,如果$A=88 包含在Previous-GTIDs中,那么继续对比上一个binlog文件 bin.003,然后再循环前面2个步骤,直到找到为止
查看Previous_gtid_log_event
mysql> show binlog events in 'mysql-bin.000002'; +------------------+-----+----------------+-----------+-------------+----------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+----------------+-----------+-------------+----------------------------------------+ | mysql-bin.000002 | 4 | Format_desc | 1546 | 123 | Server ver: 5.7.17-log, Binlog ver: 4 | | mysql-bin.000002 | 123 | Previous_gtids | 1546 | 190 | 635cd94d-5731-11ec-b22e-5e04a6f03178:4 | +------------------+-----+----------------+-----------+-------------+----------------------------------------+ 2 rows in set (0.00 sec) mysql> show binlog events in 'mysql-bin.000001'; +------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+ | mysql-bin.000001 | 4 | Format_desc | 1546 | 123 | Server ver: 5.7.17-log, Binlog ver: 4 | | mysql-bin.000001 | 123 | Previous_gtids | 1546 | 150 | | | mysql-bin.000001 | 150 | Gtid | 1547 | 211 | SET @@SESSION.GTID_NEXT= '635cd94d-5731-11ec-b22e-5e04a6f03178:4' | | mysql-bin.000001 | 211 | Query | 1547 | 270 | BEGIN | | mysql-bin.000001 | 270 | Table_map | 1547 | 322 | table_id: 221 (orch_meta.zjk_test) | | mysql-bin.000001 | 322 | Write_rows | 1547 | 358 | table_id: 221 flags: STMT_END_F | | mysql-bin.000001 | 358 | Xid | 1547 | 385 | COMMIT /* xid=1848 */ | +------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------------+ 7 rows in set (0.00 sec)
因为mysql-bin.000001是第一个binlog,所以没有Previous_gtids,第二个binlog是从第一个轮转过来的,轮转时会添加上Previous_gtids
开启GTID依赖参数
START SLAVE [thread_types] [until_option] [connection_options]
thread_types:
[thread_type [, thread_type] ... ]
thread_type:
IO_THREAD | SQL_THREAD
until_option:
UNTIL { {SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS} = gtid_set
| MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos
| RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos
| SQL_AFTER_MTS_GAPS }
* 举个栗子:
1. START SLAVE SQL_THREAD UNTIL SQL_BEFORE_GTIDS = 3E11FA47-71CA-11E1-9E33-C80AA9429562:11-56
表示,当SQL_thread 执行到3E11FA47-71CA-11E1-9E33-C80AA9429562:10 的时候停止,下一个事务是11
2. START SLAVE SQL_THREAD UNTIL SQL_AFTER_GTIDS = 3E11FA47-71CA-11E1-9E33-C80AA9429562:11-56
表示,当SQL_thread 执行到3E11FA47-71CA-11E1-9E33-C80AA9429562:56 的时候停止,56是最后一个提交的事务。
mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.170.35.100 Master_User: replic Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 869 Relay_Log_File: res-4vder6u3-0-relay-bin.000002 Relay_Log_Pos: 1074 Relay_Master_Log_File: mysql-bin.000001 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: 869 Relay_Log_Space: 1282 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Replicate_Ignore_Table: 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: 1535 Master_UUID: 3b59d3a8-567a-11ec-b9dc-b6cf24031444 Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 3b59d3a8-567a-11ec-b9dc-b6cf24031444:1, ff4738fd-5678-11ec-ae90-7e370957d2bd:10-11 Executed_Gtid_Set: 3b59d3a8-567a-11ec-b9dc-b6cf24031444:1, ff4738fd-5678-11ec-ae90-7e370957d2bd:1-11 Auto_Position: 1 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec)
其中四个参数与GTID相关:
mysql> select @@server_uuid;
+--------------------------------------+
| @@server_uuid |
+--------------------------------------+
| 3e726a5b-567a-11ec-b87d-1edc0754deed |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 855
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 3b59d3a8-567a-11ec-b9dc-b6cf24031444:1,ff4738fd-5678-11ec-ae90-7e370957d2bd:1-11
Executed_Gtid_Set: 跟备库show slave status中的Executed_Gtid_Set同样的意思,从上面看也是有两个值,且没有自己,证明此库自己未执行过事务,可以排除此库之前是主库过,证明此库的主库之前挂载到其他库上过是:A->B->C这种架构
注意:如果此时你手动gtid_purged时候,只保留了上面两个中的一个,此时start slave会有问题,因为向主库请求时,主库有执行ff4738fd-5678-11ec-ae90-7e370957d2bd:1-11相关,发现备库没有,以为备库没执行过,会重新发送此部分log,但是此部分binlog如果已被清除则复制中断,如果未被清除就会有重复消费的问题。
GTID采用com_binlog_dump_gtid来dump binlog
如果明确知道可以跳过某个事务时,可以执行下面操作注入一个新的事务,前提是当前slave已经中断了,比如报错主键冲突了
以下备库上执行
stop slave;
set gtid_next='xxxxx:N'; 指定下一个事务执行的版本,即想要跳过的GTID
begin;commit; 注入一个空事物
set gtid_next='AUTOMATIC' --自动的寻找GTID事务
start slave;
还有一种方法是直接重置自己的gtid_purged,让其从最新的位置开始拉取数据,这种方法会清空所有binlog并重置为从头开始,操作时要注意
stop slave;
show master status; 记录gtid_executed
reset master;
set global gtid_purged=xxx;
start slave;
mysqldump --set-gtid-purged=ON的记录,发现多了SET @@SESSION.SQL_LOG_BIN= 0; SET @@GLOBAL.GTID_PURGED=‘635cd94d-5731-11ec-b22e-5e04a6f03178:1-4’;两行
-- MySQL dump 10.13 Distrib 5.7.17, for linux-glibc2.5 (x86_64) -- -- Host: 10.170.1.218 Database: -- ------------------------------------------------------ -- Server version 5.7.17-log /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN; SET @@SESSION.SQL_LOG_BIN= 0; -- -- GTID state at the beginning of the backup -- SET @@GLOBAL.GTID_PURGED='635cd94d-5731-11ec-b22e-5e04a6f03178:1-4'; -- -- Position to start replication or point-in-time recovery from -- -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=190;
下面对几种场景进行分析
未开启GTID的库,果断设置–set-gtid-purged=OFF,毫无疑问,下面只分析开启GTID的库
mysql> show master status\G *************************** 1. row *************************** File: mysql-bin.000002 Position: 2389 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1be70bfd-57d7-11ec-927a-8683ca7e0e5a:1-6 这是在2时候生成的 1 row in set (0.00 sec) mysql> select *from mysql.gtid_executed; Empty set (0.00 sec) mysql> select @@gtid_Mode; +-------------+ | @@gtid_Mode | +-------------+ | ON | +-------------+ 1 row in set (0.00 sec)
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 762535
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 1db37736-57d7-11ec-92a6-968a0ae0bc3b:1-137 这是步骤3时候mysqldump生成的自己的GTID
1 row in set (0.00 sec)
mysql> select @@server_uuid;
+--------------------------------------+
| @@server_uuid |
+--------------------------------------+
| 1db37736-57d7-11ec-92a6-968a0ae0bc3b |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> show master status\G *************************** 1. row *************************** File: mysql-bin.000002 Position: 762535 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1be70bfd-57d7-11ec-927a-8683ca7e0e5a:1-6, 这是第4时候把B搭到A上同步过来A的 1db37736-57d7-11ec-92a6-968a0ae0bc3b:1-137 这是步骤3时候mysqldump生成的自己的GTID 1 row in set (0.00 sec) mysql> select @@server_uuid; +--------------------------------------+ | @@server_uuid | +--------------------------------------+ | 1db37736-57d7-11ec-92a6-968a0ae0bc3b | +--------------------------------------+ 1 row in set (0.00 sec)
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 1db37736-57d7-11ec-92a6-968a0ae0bc3b:1-137
Executed_Gtid_Set: 1be70bfd-57d7-11ec-927a-8683ca7e0e5a:1-6,
1db37736-57d7-11ec-92a6-968a0ae0bc3b:1-137
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
mysql> select *from mysql.gtid_executed;
Empty set (0.00 sec)
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 3124
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 08348f5a-57fc-11ec-9291-4a45cefb566c:1-151 A的UUID
1 row in set (0.00 sec)
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 764430
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 0196c665-5801-11ec-be27-1a69be8e5285:1-5 C的UUID
1 row in set (0.00 sec)
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 764430
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 0196c665-5801-11ec-be27-1a69be8e5285:1-146 记录binlog自己增长了
1 row in set (0.00 sec)
*************************** 1. row ***************************
File: mysql-bin.000001
Position: 3124
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 08348f5a-57fc-11ec-9291-4a45cefb566c:1-152 A的UUID 比第一步增加了一个事务
1 row in set (0.00 sec)
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 764430
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 0196c665-5801-11ec-be27-1a69be8e5285:1-146, 记录binlog自己增长了
08348f5a-57fc-11ec-9291-4a45cefb566c:152 搭到A上后,A执行了一个152事务,这里就同步过来了
1 row in set (0.00 sec)
使用xtrabackup备份恢复后需要注意的点是恢复的实例拉起后mysql.gtid_executed表中的数据可能不是最新的,由于所有数据库服务器都配置开启log_bin参数和log_slave_updates参数,因此每次执行事务不会更新mysql.gtid_executed表。xtrabackup备份过程中执行的FLUSH操作不会导致binlog rotation所以不会更新gtid_executed表。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。