• 环境基于Centos7.6

1.gtid_executed表作用

该表会记录当前执行的GTID。GTID即全局事务ID (global transaction identifier), 其保证为每一个在主上提交的事务在复制集群中可以生成一个唯一的ID。

mysql主从结构在一主一从情况下对于GTID来说就没有优势了,而对于2台主以上的结构优势异常明显,可以在数据不丢失的情况下切换新主。

使用GTID需要注意: 在构建主从复制之前,在一台将成为主的实例上进行一些操作(如数据清理等),通过GTID复制,这些在主从成立之前的操作也会被复制到从服务器上,引起复制失败。也就是说通过GTID复制都是从最先开始的事务日志开始,即使这些操作在复制之前执行。比如在server1上执行一些drop、delete的清理操作,接着在server2上执行change的操作,会使得server2也进行server1的清理操作。

2.gtid_executed表详情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
表结构
mysql> SHOW CREATE TABLE mysql.gtid_executed\G
*************************** 1. row ***************************
Table: gtid_executed
Create Table: CREATE TABLE `gtid_executed` (
`source_uuid` char(36) NOT NULL COMMENT 'uuid of the source where the transaction was originally
executed.', `interval_start` bigint(20) NOT NULL COMMENT 'First number of interval.',
`interval_end` bigint(20) NOT NULL COMMENT 'Last number of interval.',
PRIMARY KEY (`source_uuid`,`interval_start`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

MySQL 5.7对于表mysql.gtid_executed的更新策略也有些不同,如果没有主服务器没有开启log_bin或者从服务器没有开启log_slave_updates,其会每一个事物更新表gtid_executed,这样服务器重启后可以快速知道当前服务器执行到的GTID位置。因此,用户可能在服务器上看到类似如下的内容:

mysql> select * from mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| 05e16691-bf69-11e5-97cf-fa163e30f9a2 | 1 | 4334294 |
| 05e16691-bf69-11e5-97cf-fa163e30f9a2 | 4334296 | 4352984 |
| 05e16691-bf69-11e5-97cf-fa163e30f9a2 | 4352985 | 4352985 |
| 05e16691-bf69-11e5-97cf-fa163e30f9a2 | 4352986 | 4352986 |
| 05e16691-bf69-11e5-97cf-fa163e30f9a2 | 4352987 | 4352987 |
| 05e16691-bf69-11e5-97cf-fa163e30f9a2 | 4352988 | 4352988 |
......
那这样岂不是表gtid_executed中的记录会疯狂增长。为此,MySQL 5.7又引入了新的线程,用来对此表进行压缩,该线程如下所示:

mysql> select thread_id,thread_os_id,name,

-> processlist_command,processlist_state from threads

-> where name like '%compress%'\G
*************************** 1. row ***************************
thread_id: 39
thread_os_id: 23816
name: thread/sql/compress_gtid_table
processlist_command: Daemon
processlist_state: Suspending
1 row in set (0.01 sec)
参数gtid_executed_compression_period用来控制每执行多少个事务,对此表进行压缩,默认值为1000。因此,过一段时间后,上述的表mysql.gtid_executed会压缩成如下的内容:

mysql> select * from mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| 05e16691-bf69-11e5-97cf-fa163e30f9a2 | 1 | 4334294 |
| 05e16691-bf69-11e5-97cf-fa163e30f9a2 | 4334296 | 4354329 |
......
若MySQL服务器启用了二进制日志,则表mysql.gtid_executed的更新仅在二进制rotation时发生,因为发生重启等情况依旧可以通过扫描二进制日志判断得知当前运行的GTID位置。