关于 MySQL GTID 复制

2022-08-18 16:24:11 浏览数 (1)

MySQL5.7以后都基本用GTID方式复制了,相对于binlog和position号方式,在failover时候减少很多人工切换操作

GTID,global transaction identitifiers,基于全局事务的复制方式,由server_uuid:transaction_id组成,server_uuid在数据库启动过程生成,在/data/auto.cnf中

复制过程:master事务提交时GTID,记录到binlog;然后master的binlog传送到slave的relaylog,slave读取GTID生成gtid_next系统参数;slave校验GTID是否在binlog并进一步应用事务(5.7后是存放在gtid_executed系统表,这样不用开启log_slave_updates参数,从而不用把relaylog记录再记录到binlog,减少slave压力)

下面操作下:

首先主从都配置gtid_mode、enforce_gtid_consistency参数,其中备库多加个log_slave_updates=1

[root@localhost /usr/local/mysql/data]$ cat /etc/my.cnf [mysqld] datadir=/usr/local/mysql/data log_bin=mysql-bin server_id=1 gtid_mode=on enforce_gtid_consistency=on [root@localhost /usr/local/mysql/data]$

mysql> show variables like '%gtid%'; ---------------------------------- ----------- | Variable_name                    | Value    | ---------------------------------- ----------- | binlog_gtid_simple_recovery      | ON        | | enforce_gtid_consistency        | ON        | | gtid_executed_compression_period | 1000      | | gtid_mode                        | ON        | | gtid_next                        | AUTOMATIC | | gtid_owned                      |          | | gtid_purged                      |          | | session_track_gtids              | OFF      | ---------------------------------- ----------- 8 rows in set (0.00 sec) mysql>

然后将之前异步复制的配置去掉,重新配置slave中主库信息即可

mysql> show variables like '%log_slave_updates%'; ------------------- ------- | Variable_name    | Value | ------------------- ------- | log_slave_updates | ON    | ------------------- ------- 1 row in set (0.00 sec) mysql> stop slave; Query OK, 0 rows affected (0.01 sec) mysql> reset slave all; Query OK, 0 rows affected (0.02 sec) mysql> change master to     -> master_host='192.0.1.10',     -> master_user='scott',     -> master_password='tiger',     -> master_port=3306,     -> master_auto_position=1; Query OK, 0 rows affected, 2 warnings (0.02 sec) mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql> show slave statusG *************************** 1. row ***************************               Slave_IO_State: Waiting for master to send event                   Master_Host: 192.0.1.10                   Master_User: scott                   Master_Port: 3306                 Connect_Retry: 60               Master_Log_File: mysql-bin.000004           Read_Master_Log_Pos: 573               Relay_Log_File: localhost-relay-bin.000002                 Relay_Log_Pos: 786         Relay_Master_Log_File: mysql-bin.000004             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: 573               Relay_Log_Space: 997               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: 1                   Master_UUID: 531fa6d1-627f-11e9-8dc7-000c297887a1             Master_Info_File: /data/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: 531fa6d1-627f-11e9-8dc7-000c297887a1:1-2             Executed_Gtid_Set: 531fa6d1-627f-11e9-8dc7-000c297887a1:1-2                 Auto_Position: 1         Replicate_Rewrite_DB:                 Channel_Name:           Master_TLS_Version: 1 row in set (0.00 sec) mysql>

测试一下,ok的,主库状态可以看到

mysql> show master status; ------------------ ---------- -------------- ------------------ ------------------------------------------ | File            | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        | ------------------ ---------- -------------- ------------------ ------------------------------------------ | mysql-bin.000004 |      573 |              |                  | 531fa6d1-627f-11e9-8dc7-000c297887a1:1-2 | ------------------ ---------- -------------- ------------------ ------------------------------------------ 1 row in set (0.00 sec) mysql>

将slave中log_slave_updates关掉,就能看到mysql.gtid_executed表中记录已执行gtid信息了

mysql> select * from mysql.gtid_executed; -------------------------------------- ---------------- -------------- | source_uuid                          | interval_start | interval_end | -------------------------------------- ---------------- -------------- | 531fa6d1-627f-11e9-8dc7-000c297887a1 |              1 |            2 | | 531fa6d1-627f-11e9-8dc7-000c297887a1 |              3 |            3 | -------------------------------------- ---------------- -------------- 2 rows in set (0.00 sec)

由于是基于事务的,所以就有了限制条件: create table select的方式在基于行复制的情况下会被拆分为创建表和insert数据两个事件,某些情况下这两个事件会被分配相同GTID导致后面insert数据部分被忽略而产生错误; 一个事务中既包含InnoDB表又包含MyISAM表会导致可能产生多个gtid,或者表在主从库中存储引擎不一致都会产生gtid复制异常

0 人点赞