MySQL-mysqldump warning GTID

复现

工作时需要拉一下测试环境的数据到开发环境,所以就是 mysqldump 老哥出场了…

1
2
3
# mysqldump -h localhost -u root -p --tables test_table --where="str='str1'" > test_table_data.sql
Enter password:
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.

上面的警告内容翻译如下:

1
2
默认情况下,来自具有 GTID 的服务器的部分转储将包括所有事务的 GTID,即使是那些更改了数据库被抑制部分的事务。如果不想恢复 gtid,请使用 --set-gtid-purged=OFF 参数。
如果要进行完整的转储,请使用参数 --all-databases --triggers --routines --events

得知警告原因之后,就会想到 GTID 是用来保证事务全局唯一的配置信息,另外发现数据已经完整转储出来,那么接下来这个 GTID 是什么意思呢?


GTID

GTID (Global Transaction IDentifier) 是全局事务标识,其具有全局唯一性,一个事务对应一个 GTID
由于其唯一性不仅限于主服务器,GTID 在所有的从服务器上也是唯一的;一个 GTID 在一个服务器上只执行一次,从而避免重复执行导致数据混乱或主从不一致。

在传统的复制里面,当发生故障需要主从切换时,服务器需要找到 binlogpos 点,然后将其设定为新的主节点开启复制。相对来说比较麻烦也容易出错,因此在 MySQL 5.6 版本里会通过内部机制自动匹配 GTID 断点,不再寻找 binlogpos 点,此时只需要知道主节点的 IP、端口、以及账号密码就可以自动复制。

产生

GTID 的生成受 GTID_NEXT 控制。

在主服务器上 GTID_NEXT 默认值是 AUTOMATIC ,即在每次事务提交时自动生成 GTID,并且它会从当前已执行的 GTID 集合(即gtid_executed)中找一个大于 0 的未使用的最小值作为下个事务 GTID。而现实中在实际的更新事务记录之前,会将 GTID 写入到 binlogset GTID_NEXT 记录)。
在从服务器上,首先从 binlog 先读取到主库的 GTIDget GTID_NEXT记录),然后执行事务时使用该 GTID

产生步骤:

  • 主服务器更新数据时,会在事务前产生 GTID,一同记录到 binlog 日志中。
  • binlog 传送到从服务器后,被写入到本地的 relay log 中,接着从服务器读取 GTID,并将其设定为自己的 GTID
  • 从服务器的 SQL 线程从 relay log 中获取 GTID,然后对比从服务器端的 binlog 中是否有记录。
  • 如果有记录,说明该 GTID 的事务已经执行,从服务器会忽略。
  • 如果没有记录,从服务器就会从 relay log 中执行该 GTID 的事务,并记录到 binlog

组成

GDIT 由两部分组成: source_idtransaction_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/


个人备注

此博客内容均为作者学习所做笔记,侵删!
若转作其他用途,请注明来源!