复现
工作时需要拉一下测试环境的数据到开发环境,所以就是 mysqldump 老哥出场了…
1 | # mysqldump -h localhost -u root -p --tables test_table --where="str='str1'" > test_table_data.sql |
上面的警告内容翻译如下:
1 | 默认情况下,来自具有 GTID 的服务器的部分转储将包括所有事务的 GTID,即使是那些更改了数据库被抑制部分的事务。如果不想恢复 gtid,请使用 --set-gtid-purged=OFF 参数。 |
得知警告原因之后,就会想到 GTID 是用来保证事务全局唯一的配置信息,另外发现数据已经完整转储出来,那么接下来这个 GTID 是什么意思呢?
GTID
GTID (Global Transaction IDentifier) 是全局事务标识,其具有全局唯一性,一个事务对应一个 GTID。
由于其唯一性不仅限于主服务器,GTID 在所有的从服务器上也是唯一的;一个 GTID 在一个服务器上只执行一次,从而避免重复执行导致数据混乱或主从不一致。
在传统的复制里面,当发生故障需要主从切换时,服务器需要找到 binlog 和 pos 点,然后将其设定为新的主节点开启复制。相对来说比较麻烦也容易出错,因此在 MySQL 5.6 版本里会通过内部机制自动匹配 GTID 断点,不再寻找 binlog 和 pos 点,此时只需要知道主节点的 IP、端口、以及账号密码就可以自动复制。
产生
GTID 的生成受 GTID_NEXT 控制。
在主服务器上 GTID_NEXT 默认值是 AUTOMATIC ,即在每次事务提交时自动生成 GTID,并且它会从当前已执行的 GTID 集合(即gtid_executed)中找一个大于 0 的未使用的最小值作为下个事务 GTID。而现实中在实际的更新事务记录之前,会将 GTID 写入到 binlog(set GTID_NEXT 记录)。
在从服务器上,首先从 binlog 先读取到主库的 GTID(get GTID_NEXT记录),然后执行事务时使用该 GTID。
产生步骤:
- 主服务器更新数据时,会在事务前产生
GTID,一同记录到binlog日志中。 binlog传送到从服务器后,被写入到本地的relay log中,接着从服务器读取GTID,并将其设定为自己的GTID。- 从服务器的
SQL线程从relay log中获取GTID,然后对比从服务器端的binlog中是否有记录。 - 如果有记录,说明该
GTID的事务已经执行,从服务器会忽略。 - 如果没有记录,从服务器就会从
relay log中执行该GTID的事务,并记录到binlog。
组成
GDIT 由两部分组成: source_id 和 transaction_id 。source_id 是产生 GTID 的服务器,即 server_uuid,在第一次启动时生成(sql/mysqld.cc: generate_server_uuid())并保存到 DATADIR/auto.cnf 文件里。transaction_id 是序列号(sequence number),在每台 MySQL 服务器上都是从 1 开始自增长的顺序号,是事务的唯一标识。
引用
http://mysql.taobao.org/monthly/2020/05/09/
个人备注
此博客内容均为作者学习所做笔记,侵删!
若转作其他用途,请注明来源!