16.1.6.5 全局 TransactionID 系统变量

本节中描述的 MySQL Server 系统变量用于监视和控制全局事务标识符(GTID)。有关更多信息,请参见第 16.1.3 节“使用全局事务标识符进行复制”

PropertyValue
Command-Line Format--binlog-gtid-simple-recovery[={OFF|ON}]
System Variablebinlog_gtid_simple_recovery
ScopeGlobal
DynamicNo
TypeBoolean
Default ValueON

此变量控制 MySQL 启动或重新启动时在搜索 GTID 期间如何迭代二进制日志文件。

binlog_gtid_simple_recovery=TRUE为默认值时,将在启动时根据最新和最早的二进制日志文件中的Previous_gtids_log_event的值来计算gtid_executedgtid_purged的值。有关计算的说明,请参见gtid_purged 系统变量。服务器重新启动期间,此设置仅访问两个二进制日志文件。如果服务器上的所有二进制日志都是使用 MySQL 5.7.8 或更高版本生成的,而您使用的是 MySQL 5.7.8 或更高版本,则可以始终安全地使用binlog_gtid_simple_recovery=TRUE

在以下两种情况下,使用binlog_gtid_simple_recovery=TRUEgtid_executedgtid_purged可能会错误地初始化:

  • 最新的二进制日志由 MySQL 5.7.5 或更早版本生成,对于某些二进制日志,gtid_modeON,对于最新的二进制日志为OFF

    • 在 MySQL 5.7.7 或更早版本上发布了SET @@GLOBAL.gtid_purged语句,并且尚未清除在SET @@GLOBAL.gtid_purged语句时处于活动状态的二进制日志。

如果在任何一种情况下都计算出错误的 GTID 集,即使以后使用binlog_gtid_simple_recovery=FALSE重新启动服务器,它也将保持错误。如果这两种情况都适用于服务器,请在启动或重新启动服务器之前设置binlog_gtid_simple_recovery=FALSE。要检查第二种情况,如果您使用的是 MySQL 5.7.7 或更早版本,则在发出SET @@GLOBAL.gtid_purged语句后记下当前的二进制日志文件名,可以使用显示主状态进行检查。如果在清除该文件之前重新启动服务器,则应设置binlog_gtid_simple_recovery=FALSE

设置binlog_gtid_simple_recovery=FALSE时,更改了gtid_purged 系统变量中所述的计算gtid_executedgtid_purged的方法以迭代二进制日志文件,如下所示:

  • 代替使用最新二进制日志文件中的Previous_gtids_log_event和 GTID 日志事件的值,而是从最新二进制日志文件中进行gtid_executed的计算,并使用Previous_gtids_log_event的值以及第一个二进制日志文件中的 GTID 日志事件Previous_gtids_log_event值。如果服务器的最新二进制日志文件没有 GTID 日志事件,例如,如果使用gtid_mode=ON,但后来服务器更改为gtid_mode=OFF,则此过程可能需要很长时间。

    • 代替使用最旧的二进制日志文件中的Previous_gtids_log_event的值,对gtid_purged的计算从最旧的二进制日志文件中进行迭代,并使用第一个二进制日志文件中的Previous_gtids_log_event的值,在此它会找到非空的Previous_gtids_log_event值或至少一个 GTID 日志事件(指示从该点开始使用 GTID)。如果服务器的较旧的二进制日志文件没有 GTID 日志事件,例如,如果gtid_mode=ON是最近才在服务器上设置的,则此过程可能会花费很长时间。

在 MySQL 版本 5.7.5 中,此变量添加为simplified_binlog_gtid_recovery,在 MySQL 版本 5.7.6 中将其重命名为binlog_gtid_simple_recovery

PropertyValue
Command-Line Format--enforce-gtid-consistency[=value]
System Variableenforce_gtid_consistency
ScopeGlobal
DynamicYes
TypeEnumeration
Default ValueOFF
Valid ValuesOFF

ON
WARN

根据此变量的值,服务器通过允许仅执行可以使用 GTID 安全记录的语句来实现 GTID 一致性。您必须将此变量设置为ON,然后才能启用基于 GTID 的复制。

enforce_gtid_consistency可以配置为以下值:

  • OFF:允许所有事务违反 GTID 一致性。

    • ON:不允许任何事务违反 GTID 一致性。

    • WARN:允许所有事务违反 GTID 一致性,但是在这种情况下会生成警告。 WARN已在 MySQL 5.7.6 中添加。

enforce_gtid_consistency设置为ON时,只能记录可以使用 GTID 安全语句记录的语句,因此此处列出的操作不能与该选项一起使用:

  • 创建 table...选择 statements

    • Transaction 中的创建临时 table拖放临时 table语句

    • 事务或语句同时更新事务 table 和非事务 table。如果所有* nontransactional *table 都是临时的,则有一个 exception,即与事务 DML 相同的事务或同一语句中允许使用非事务 DML。

--enforce-gtid-consistency仅在为语句执行二进制日志记录时才有效。如果在服务器上禁用了二进制日志记录,或者由于过滤器将语句删除而未将语句写入二进制日志,则不会检查或强制执行未记录语句的 GTID 一致性。

有关更多信息,请参见第 16.1.3.6 节,“使用 GTID 复制的限制”

在 MySQL 5.7.6 之前,布尔值enforce_gtid_consistency默认为OFF。为了保持与先前发行版的兼容性,在 MySQL 5.7.6 中,枚举默认为OFF,而将--enforce-gtid-consistency设置为无值将被解释为将值设置为ON。该变量还具有以下值的多个文本别名:0=OFF=FALSE1=ON=TRUE2=WARN。这与其他枚举类型不同,但是与以前版本中使用的布尔类型保持兼容。这些更改影响变量返回的内容。使用SELECT @@ENFORCE_GTID_CONSISTENCYSHOW VARIABLES LIKE 'ENFORCE_GTID_CONSISTENCY'SELECT * FROM INFORMATION_SCHEMA.VARIABLES WHERE 'VARIABLE_NAME' = 'ENFORCE_GTID_CONSISTENCY'都返回文本形式,而不是数字形式。这是不兼容的更改,因为@@ENFORCE_GTID_CONSISTENCY返回布尔值的数字形式,但返回SHOW和信息模式的文本形式。

PropertyValue
System Variablegtid_executed
System Variablegtid_executed
ScopeGlobal
ScopeGlobal, Session
DynamicNo
DynamicNo
TypeString
Unitset of GTIDs

与全局范围一起使用时,此变量包含服务器上执行的所有事务的集合以及由SET gtid_purged语句设置的 GTID 的 table 示。这与显示主状态显示从站状态的输出中Executed_Gtid_Set列的值相同。此变量的值是 GTID 集,有关更多信息,请参见GTID Sets

服务器启动时,将初始化@@GLOBAL.gtid_executed。有关如何迭代二进制日志以填充gtid_executed的更多信息,请参见binlog_gtid_simple_recovery。然后,在执行事务或执行任何SET gtid_purged语句时,会将 GTID 添加到集合中。

在任何给定时间可以在二进制日志中找到的事务集等于GTID_SUBTRACT(@@GLOBAL.gtid_executed, @@GLOBAL.gtid_purged);也就是说,针对二进制日志中尚未清除的所有事务。

发出RESET MASTER会使该变量的全局值(而不是会话值)重置为空字符串。除了由于RESET MASTER清除 GTID 之外,不会从该集合中移除 GTID。

在 MySQL 5.7.7 之前,此变量还可以用于会话范围,其中包含 table 示当前会话中写入缓存的事务集的 table 示。会话范围在 MySQL 5.7.7 中已弃用。

PropertyValue
Command-Line Format--gtid-executed-compression-period=#
System Variablegtid_executed_compression_period
ScopeGlobal
DynamicYes
TypeInteger
Default Value1000
Minimum Value0
Maximum Value4294967295

每次处理完这么多事务后,都要压缩mysql.gtid_executedtable。设置为 0table 示此 table 未压缩。由于使用二进制日志时不会压缩 table,因此除非禁用了二进制日志记录,否则设置变量的值将无效。

有关更多信息,请参见mysql.gtid_exectedtable 压缩

此变量在 MySQL 5.7.5 版本中以executed_gtids_compression_period的形式添加,并在 MySQL 5.7.6 版本中重命名为gtid_executed_compression_period

PropertyValue
Command-Line Format--gtid-mode=MODE
System Variablegtid_mode
ScopeGlobal
DynamicYes
TypeEnumeration
Default ValueOFF
Valid ValuesOFF

OFF_PERMISSIVE
ON_PERMISSIVE
ON

控制是否启用基于 GTID 的日志记录以及日志可以包含的事务类型。在 MySQL 5.7.6 之前,此变量是只读的,并且仅在服务器启动时使用--gtid-mode设置。在 MySQL 5.7.5 之前,使用--gtid-mode=ON启动服务器要求还使用--log-bin--log-slave-updates选项启动服务器。从 MySQL 5.7.5 开始,这不再是必需的。参见mysql.gtid_executed Table

MySQL 5.7.6 允许动态设置此变量。您必须具有足以设置全局系统变量的特权。参见第 5.1.8.1 节“系统变量特权”enforce_gtid_consistency必须为 true 才能设置gtid_mode=ON。修改此变量之前,请参见第 16.1.4 节“更改在线服务器上的复制模式”

在 MySQL 5.7.6 及更高版本中登录的事务可以是匿名的,也可以使用 GTID。匿名事务依赖于二进制日志文件和位置来标识特定事务。 GTID 事务具有唯一的标识符,该标识符用于引用事务。 MySQL 5.7.6 中添加的OFF_PERMISSIVEON_PERMISSIVE模式允许在拓扑中混合使用这些事务类型。现在,不同的模式是:

  • OFF:新事务和复制事务都必须是匿名的。

    • OFF_PERMISSIVE:新 Transaction 是匿名的。复制的事务可以是匿名事务也可以是 GTID 事务。

    • ON_PERMISSIVE:新 Transaction 是 GTIDTransaction。复制的事务可以是匿名事务也可以是 GTID 事务。

    • ON:新事务和复制事务都必须是 GTID 事务。

从一个值更改为另一个值一次只能一次。例如,如果gtid_mode当前设置为OFF_PERMISSIVE,则可以更改为OFFON_PERMISSIVE,但不能更改为ON

在 MySQL 5.7.6 和更高版本中,gtid_purgedgtid_executed的值是持久的,而与gtid_mode的值无关。因此,即使在更改gtid_mode的值之后,这些变量也包含正确的值。在 MySQL 5.7.5 和更早版本中,gtid_purgedgtid_executed的值在gtid_mode=OFF时不是持久的。因此,在将gtid_mode更改为OFF之后,一旦清除了所有包含 GTID 的二进制日志,这些变量的值就会丢失。

PropertyValue
System Variablegtid_next
ScopeSession
DynamicYes
TypeEnumeration
Default ValueAUTOMATIC
Valid ValuesAUTOMATIC

ANONYMOUS
UUID:NUMBER

此变量用于指定是否以及如何获取下一个 GTID。

设置此系统变量的会话值是受限制的操作。会话用户必须具有足以设置受限会话变量的特权。参见第 5.1.8.1 节“系统变量特权”

gtid_next可以采用以下任何值:

  • AUTOMATIC:使用下一个自动生成的全局事务 ID。

    • ANONYMOUS:事务没有全局标识符,仅由文件和位置标识。

      • UUID NUMBER *格式的全局事务 ID。

上述选项中的哪一个有效,取决于gtid_mode的设置,有关更多信息,请参见第 16.1.4.1 节“复制模式概念”。如果gtid_modeOFF,则设置此变量无效。

在将此变量设置为* UUID NUMBER *之后,并且事务已提交或回滚,必须在其他任何语句之前再次发出显式SET GTID_NEXT语句。

在 MySQL 5.7.5 及更高版本中,当将DROP TABLEDROP TEMPORARY TABLE用于非临时 table 与临时 table 的组合,或使用事务性存储引擎的临时 table 与使用非事务性存储引擎的临时 table 的组合时,将失败并出现显式错误。在 MySQL 5.7.5 之前的版本中,当启用 GTID 但gtid_next不是AUTOMATIC时,DROP TABLE与这些 table 的任何组合一起使用时均无法正常工作。错误#17620053)

在 MySQL 5.7.1 中,如果将gtid_next设置为除以下以外的任何值,则不能执行任何语句更改为主START SLAVESTOP SLAVEREPAIR TABLEOPTIMIZE TABLEANALYZE TABLECHECK TABLECREATE SERVERALTER SERVERDROP SERVERCACHE INDEX将索引加载到缓存中FLUSHRESET AUTOMATIC;在这种情况下,该语句将失败并显示错误。在 MySQL 5.7.2 及更高版本中,不允许这样的语句。 (错误#16062608,错误#16715809,错误#69045)(错误#16062608)

PropertyValue
System Variablegtid_owned
ScopeGlobal, Session
DynamicNo
TypeString
Unitset of GTIDs

此只读变量主要供内部使用。其内容取决于其范围。

  • 与全局范围一起使用时,gtid_owned包含服务器上当前正在使用的所有 GTID 的列 table,以及拥有它们的线程的 ID。该变量主要用于多线程副本检查事务是否已经在另一个线程上应用。申请者线程在处理 Transaction 的所有时间中一直拥有 Transaction 的 GTID 的所有权,因此@@global.gtid_owned显示了在处理期间的 GTID 和所有者。提交(或回滚)事务后,应用程序线程将释放 GTID 的所有权。

    • 与会话作用域一起使用时,gtid_owned持有该会话当前正在使用并拥有的单个 GTID。当 Client 端通过设置gtid_next为事务显式分配了 GTID 时,此变量主要用于测试和调试 GTID 的使用。在这种情况下,@@session.gtid_owned在 Client 端处理事务期间一直显示 GTID,直到事务已提交(或回滚)为止。Client 完成 Transaction 处理后,将清除该变量。如果gtid_next=AUTOMATIC用于会话,则gtid_owned仅在事务的 commit 语句执行期间短暂填充,因此从相关会话中无法观察到它,尽管如果在正确的位置读取@@global.gtid_owned则会列出。如果您需要跟踪会话中 Client 端处理的 GTID,则可以启用由session_track_gtids系统变量控制的会话状态跟踪器。
  • gtid_purged

PropertyValue
System Variablegtid_purged
ScopeGlobal
DynamicYes
TypeString
Unitset of GTIDs

gtid_purged系统变量(@@GLOBAL.gtid_purged)的全局值是一个 GTID 集,由服务器上已提交但服务器上任何二进制日志文件中不存在的所有事务的 GTID 组成。 gtid_purgedgtid_executed的子集。以下类别的 GTID 位于gtid_purged中:

  • 在副本数据库上禁用了二进制日志记录的情况下提交的复制事务的 GTID。

    • 写入到现已清除的二进制日志文件中的事务的 GTID。

    • 由语句SET @@GLOBAL.gtid_purged显式添加到集合中的 GTID。

服务器启动或重新启动时,gtid_purged的全局值将初始化为一组 GTID。有关如何计算此 GTID 集的信息,请参见gtid_purged 系统变量。如果服务器上存在来自 MySQL 5.7.7 或更早版本的二进制日志,则可能需要在服务器的配置文件中设置binlog_gtid_simple_recovery=FALSE才能进行正确的计算。有关需要此设置的情况的详细信息,请参见binlog_gtid_simple_recovery的描述。

发出RESET MASTER会将gtid_purged的值重置为空字符串。

您可以设置gtid_purged的值,以在服务器上记录已应用某个 GTID 集中的事务,尽管服务器上任何二进制日志中都不存在这些事务。此操作的一个示例用例是,正在还原服务器上一个或多个数据库的备份,但是没有包含服务器上事务的相关二进制日志。

在 MySQL 5.7 中,仅当gtid_executed为空字符串,因此gtid_purged为空字符串时,才可以更新gtid_purged的值。以前没有启动复制,或者以前没有使用 GTID 的情况就是这种情况。在 MySQL 5.7.6 之前,也只能在gtid_mode=ON时设置gtid_purged。在 MySQL 5.7.6 和更高版本中,gtid_purged是可设置的,而与gtid_mode的值无关。

要将gtid_purged的值替换为您指定的 GTID 集,请使用以下语句:

SET @@GLOBAL.gtid_purged = 'gtid_set'

Note

如果使用的是 MySQL 5.7.7 或更早版本,则在发出SET @@GLOBAL.gtid_purged语句后,可能需要在服务器的配置文件中设置binlog_gtid_simple_recovery=FALSE才能重新启动服务器,否则gtid_purged可能计算不正确。有关需要此设置的情况的详细信息,请参见binlog_gtid_simple_recovery的描述。如果服务器上的所有二进制日志都是使用 MySQL 5.7.8 或更高版本生成的,而您使用的是 MySQL 5.7.8 或更高版本,则可以始终安全地使用binlog_gtid_simple_recovery=TRUE(这是 MySQL 5.7.7 的默认设置)。