共计 6116 个字符,预计需要花费 16 分钟才能阅读完成。
这篇文章主要介绍“怎么理解 MySQL 的 GTID 复制”,在日常操作中,相信很多人在怎么理解 MySQL 的 GTID 复制问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么理解 MySQL 的 GTID 复制”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!
什么是 GTID
什么是 GTID 呢,简而言之,就是全局事务 ID(global transaction identifier),最初由 google 实现,官方 MySQL 在 5.6 才加入该功能。
GTID 是事务提交时创建分配的唯一标识符,所有事务均与 GTID 一一映射。
GTID 的格式类似于:
5882bfb0-c936-11e4-a843-000c292dc103:1
这个字符串,用“:”分开,前面表示这个服务器的 server_uuid,这是一个 128 位的随机字符串,在第一次启动时生成(函数 generate_server_uuid),对应的 variables 是只读变量 server_uuid。它能以极高的概率保证全局唯一性,并存到文件
DATADIR/auto.cnf 中。因此要注意保护这个文件不要被删除或修改。
第二部分是一个自增的事务 ID 号,事务 id 号 +server_uuid 来唯一标示一个事务。
mysql show global variables like %gtid%
+--------------------------+------------------------------------------+
| Variable_name | Value |
+--------------------------+------------------------------------------+
| enforce_gtid_consistency | ON |
| gtid_executed | 5882bfb0-c936-11e4-a843-000c292dc103:1-6 |
| gtid_mode | ON |
| gtid_owned | |
| gtid_purged | |
+--------------------------+------------------------------------------+
5 rows in set (0.00 sec)
mysql show global variables like %uuid%
+---------------+--------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------+
| server_uuid | 5882bfb0-c936-11e4-a843-000c292dc103 |
+---------------+--------------------------------------+
1 row in set (0.00 sec)
shell cat auto.cnf
[auto]
server-uuid=5882bfb0-c936-11e4-a843-000c292dc103
设置 GTID 复制
同步主从数据
mysql SET @@global.read_only = ON;
Query OK, 0 rows affected (0.01 sec)
停止所有数据库
shell mysqladmin -u root -p shutdown
设置开发 GTID 模式并启动所有数据库
shell vi my.cnf 添加如下内容
================================================================
[mysqld]
gtid_mode=ON
log-slave-updates=ON
enforce-gtid-consistency=ON # 强制 GTID 的一致性
================================================================
从库指定主库
mysql CHANGE MASTER TO
- MASTER_HOST = host,
- MASTER_PORT = port,
- MASTER_USER = user,
- MASTER_PASSWORD = password,
- MASTER_AUTO_POSITION = 1;
mysql START SLAVE;
Query OK, 0 rows affected (0.04 sec)
禁止 read-only 模式
mysql SET @@global.read_only = OFF;
Query OK, 0 rows affected (0.00 sec)
GTID 复制的限制
GTID 模式实例和非 GTID 模式实例是不能进行复制的,要求非常严格,要么都是 GTID,要么都不是
gtid_mode 是只读的,要改变状态必须 1) 关闭实例、2)修改配置文件、3) 重启实例
更新非事务引擎表
在同一事务中更新事务表与非事务表将导致多个 GTIDs 分配给同一事务
mysql cretea table tt (id int) engine=myisam;
mysql insert into tt values(1),(2);
mysql cretea table t (id int) engine=innodb;
mysql insert into t values(1),(2);
mysql set autocommit = 0;mysql begin;mysql update t set id = 3 where id =2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql update tt set id = 3 where id =2;
ERROR 1785 (HY000): When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, updates to non-transactional tables can
only be done in either autocommitted statements or single-statement transactions, and never in the same
statement as updates to transactional tables.
CREATE TABLE … SELECT statements
不安全的基于语句复制,实际是两个独立的事件,一个用于建表,一个用于向新表插入源表数据。
mysql create table t engine=innodb as select * from tt;
ERROR 1786 (HY000): CREATE TABLE ... SELECT is forbidden when @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1.
临时表
事务内部不能执行创建删除临时表语句,但可以在事务外执行,但必须设置 set autocommit = 1
mysql create temporary table tttt(id int);
ERROR 1787 (HY000): When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, the statements CREATE TEMPORARY TABLE and
DROP TEMPORARY TABLE can be executed in a non-transactional context only, and require that AUTOCOMMIT = 1.
mysql set autocommit = 1;
Query OK, 0 rows affected (0.00 sec)
mysql create temporary table tttt(id int);
Query OK, 0 rows affected (0.04 sec)
不执行不支持的语句
启用 –enforce-gtid-consistency 选项启动 GTID 模式,上述不支持的语句将会返回错误。
运维操作
a. 忽略复制错误
当备库复制出错时,传统的跳过错误的方法是设置 sql_slave_skip_counter, 然后再 START SLAVE。
但如果打开了 GTID,就会设置失败:
mysql stop slave;
Query OK, 0 rows affected (0.03 sec)
mysql set global sql_slave_skip_counter = 1;
ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON.
Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction
提示的错误信息告诉我们,可以通过生成一个空事务来跳过错误的事务。
我们手动产生一个备库复制错误:
[slave]
mysql alter table t add primary key pk_id(id);
Query OK, 2 rows affected (0.12 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql insert into t values(1);
mysql insert into t values(4);
mysql insert into t values(5);
mysql show master status ;
+-------------------+----------+--------------+------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------------------------------+
| mysql-info.000004 | 914 | | | 5882bfb0-c936-11e4-a843-000c292dc103:1-17 |
+-------------------+----------+--------------+------------------+-------------------------------------------+
1 row in set (0.00 sec)
mysql show slave status \G
*************************** 1. row ***************************
...
Slave_IO_Running: Yes
lave_SQL_Running: No
Last_Errno: 1062
Last_Error: Could not execute Write_rows event on table db_test.t; Duplicate entry 1 for key PRIMARY ,
Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event s master log mysql-info.000004, end_log_pos 401
Retrieved_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-15
Executed_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-14,
f1e6584a-c935-11e4-a840-000c29348dbe:1
Auto_Position: 1
1 row in set (0.00 sec)
mysql SET @@SESSION.GTID_NEXT= 5882bfb0-c936-11e4-a843-000c292dc103:15
Query OK, 0 rows affected (0.00 sec)
mysql begin;
Query OK, 0 rows affected (0.00 sec)
mysql commit;
Query OK, 0 rows affected (0.00 sec)
mysql SET SESSION GTID_NEXT = AUTOMATIC;
mysql start slave;
mysql show slave status\G
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Last_Errno: 0
Retrieved_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-17
Executed_Gtid_Set: 5882bfb0-c936-11e4-a843-000c292dc103:1-17,
f1e6584a-c935-11e4-a840-000c29348dbe:1
Auto_Position: 1
1 row in set (0.00 sec)
再查看 show slave status,就会发现错误事务已经被跳过了。这种方法的原理很简单,空事务产生的 GTID 加入到 GTID_EXECUTED 中,
这相当于告诉备库,这个 GTID 对应的事务已经执行了,此时主从数据不一致。
到此,关于“怎么理解 MySQL 的 GTID 复制”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!