• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 存储的用于操纵GTID的函数示例

    MySQL包含一些内置(本机)函数,可用于基于GTID的复制。这些功能如下:

    GTID_SUBSET(set1,set2)

    给定两组全局事务标识符set1set2,如果中的所有GTID set1也在中,则返回true set2。否则返回false。

    GTID_SUBTRACT(set1,set2)

    给定两组全局事务标识符set1set2,仅返回set1不在中的那些GTID set2

    WAIT_FOR_EXECUTED_GTID_SET(gtid_set[,timeout])

    等待服务器应用所有全局事务标识符包含在中的所有事务gtid_set。在指定的秒数过去之后,可选的超时功能使功能停止等待。

    有关这些功能的详细信息,请参见“与全局事务标识符(GTID)一起使用的功能”。

    您可以定义自己的存储函数以使用GTID。有关定义存储函数的信息,请参见存储对象。以下示例显示了一些有用的存储函数,这些函数可以基于内置函数GTID_SUBSET()GTID_SUBTRACT()函数创建。

    请注意,在这些存储的函数中,已使用delimiter命令将MySQL语句的定界符更改为竖线,如下所示:

    mysql> delimiter |
    

    所有这些函数都将GTID集的字符串表示形式用作参数,因此GTID集与它们一起使用时必须始终用引号引起来。

    如果两个GTID集是同一集合,即使它们的格式不同,此函数也会返回非零(true)。

    CREATE FUNCTION GTID_IS_EQUAL(gtid_set_1 LONGTEXT, gtid_set_2 LONGTEXT)
    RETURNS INT
      RETURN GTID_SUBSET(gtid_set_1, gtid_set_2) AND GTID_SUBSET(gtid_set_2, gtid_set_1)|
    

    如果两个GTID集不相交,则此函数返回非零(true)。

    CREATE FUNCTION GTID_IS_DISJOINT(gtid_set_1 LONGTEXT, gtid_set_2 LONGTEXT)
    RETURNS INT
      RETURN GTID_SUBSET(gtid_set_1, GTID_SUBTRACT(gtid_set_1, gtid_set_2))|
    

    如果两个GTID集不相交,则此函数返回非零(true),并且sum是两个集的并集。

    CREATE FUNCTION GTID_IS_DISJOINT_UNION(gtid_set_1 LONGTEXT, gtid_set_2 LONGTEXT, sum LONGTEXT)
    RETURNS INT
      RETURN GTID_IS_EQUAL(GTID_SUBTRACT(sum, gtid_set_1), gtid_set_2) AND
             GTID_IS_EQUAL(GTID_SUBTRACT(sum, gtid_set_2), gtid_set_1)|
    

    此函数以大写形式返回GTID集的规范化形式,没有空格,也没有重复项。UUID以字母顺序排列,间隔以数字顺序排列。

    CREATE FUNCTION GTID_NORMALIZE(g LONGTEXT)
    RETURNS LONGTEXT
    RETURN GTID_SUBTRACT(g, '')|
    

    此函数返回两个GTID集的并集。

    CREATE FUNCTION GTID_UNION(gtid_set_1 LONGTEXT, gtid_set_2 LONGTEXT)
    RETURNS LONGTEXT
      RETURN GTID_NORMALIZE(CONCAT(gtid_set_1, ',', gtid_set_2))|
    

    此函数返回两个GTID集的交集。

    CREATE FUNCTION GTID_INTERSECTION(gtid_set_1 LONGTEXT, gtid_set_2 LONGTEXT)
    RETURNS LONGTEXT
      RETURN GTID_SUBTRACT(gtid_set_1, GTID_SUBTRACT(gtid_set_1, gtid_set_2))|
    

    该函数返回两个GTID集之间的对称差,即存在于gtid_set_1但不存在于其中的GTID gtid_set_2,以及存在于gtid_set_2但不存在于其中的GTID gtid_set_1

    CREATE FUNCTION GTID_SYMMETRIC_DIFFERENCE(gtid_set_1 LONGTEXT, gtid_set_2 LONGTEXT)
    RETURNS LONGTEXT
      RETURN GTID_SUBTRACT(CONCAT(gtid_set_1, ',', gtid_set_2), GTID_INTERSECTION(gtid_set_1, gtid_set_2))|
    

    此函数从GTID集合中删除指定来源的所有GTID,并返回剩余的GTID(如果有)。UUID是发起事务的服务器使用的标识符,通常是该server_uuid值。

    CREATE FUNCTION GTID_SUBTRACT_UUID(gtid_set LONGTEXT, uuid TEXT)
    RETURNS LONGTEXT
      RETURN GTID_SUBTRACT(gtid_set, CONCAT(UUID, ':1-', (1 << 63) - 2))|
    

    此函数将先前列出的函数反向,以仅返回GTID集中来自具有指定标识符(UUID)的服务器的GTID。

    CREATE FUNCTION GTID_INTERSECTION_WITH_UUID(gtid_set LONGTEXT, uuid TEXT)
    RETURNS LONGTEXT
      RETURN GTID_SUBTRACT(gtid_set, GTID_SUBTRACT_UUID(gtid_set, uuid))|
    

    示例17.1验证复制从属服务器是否最新

    内置的功能GTID_SUBSETGTID_SUBTRACT可用于检查复制从具有至少每一笔交易,一个主已申请施加。

    要使用进行此检查GTID_SUBSET,请在从站上执行以下语句:

    SELECT GTID_SUBSET(master_gtid_executed, slave_gtid_executed)
    

    如果返回0(假),master_gtid_executed则中不存在某些GTID slave_gtid_executed,因此主服务器已应用了从属服务器未应用的某些事务,因此从属服务器不是最新的。

    要使用进行检查GTID_SUBTRACT,请在从站上执行以下语句:

    SELECT GTID_SUBTRACT(master_gtid_executed, slave_gtid_executed)
    

    该语句返回中的master_gtid_executed但不在中的所有GTID slave_gtid_executed。如果返回任何GTID,则主服务器已应用了从属服务器未应用的某些事务,因此从属服务器不是最新的。

    示例17.2备份和还原方案

    存储的功能GTID_IS_EQUALGTID_IS_DISJOINTGTID_IS_DISJOINT_UNION可以用于验证涉及多个数据库和服务器的备份和还原操作。在此示例场景中,server1包含database db1,并且server2包含database db2。目标是将数据库复制db2server1,其结果server1应该是两个数据库的并集。使用的过程是server2使用mysqlpumpmysqldump进行备份,然后在上还原此备份server1

    如果备份程序的选项--set-gtid-purged设置为ON或默认为AUTO,则该程序的输出包含一条SET @@GLOBAL.gtid_purged语句,该语句会将gtid_executed集合从添加server2gtid_purgedserver1。该gtid_purged集合包含已在服务器上提交但在服务器上的任何二进制日志文件中都不存在的所有事务的GTID。将数据库db2复制到时server1,必须将提交的事务的GTID(server2不在的二进制日志文件server1中)添加到server1gtid_purged集合中,以使该集合完整。

    在这种情况下,存储的功能可用于协助执行以下步骤:

    • 使用GTID_IS_EQUAL来验证备份操作计算的正确GTID一套SET @@GLOBAL.gtid_purged说法。在上server2,从mysqlpumpmysqldump输出中提取该语句,并将GTID集存储到本地变量中,例如$gtid_purged_set。然后执行以下语句:

      server2> SELECT GTID_IS_EQUAL($gtid_purged_set, @@GLOBAL.gtid_executed);
      

      如果结果为1,则两个GTID集相等,并且该集已正确计算。

    • 使用GTID_IS_DISJOINT验证,在该GTID集mysqlpumpmysqldump的输出不重叠与gtid_executed上一套server1。如果存在任何重叠,并且由于某些原因在两个服务器上都存在相同的GTID,则在将数据库复制db2到时会看到错误server1。要检查on server1gtid_purged从输出中提取并存储集合,如上所述,然后执行以下语句:

      server1> SELECT GTID_IS_DISJOINT($gtid_purged_set, @@GLOBAL.gtid_executed);
      

      如果结果为1,则两个GTID集之间没有重叠,因此不存在重复的GTID。

    • 使用GTID_IS_DISJOINT_UNION验证恢复操作导致的正确GTID状态server1。在还原备份之前,请通过执行以下语句在上server1获取现有gtid_executed集:

      server1> SELECT @@GLOBAL.gtid_executed;
      

      将结果存储在局部变量中$original_gtid_executedgtid_purged如上所述,还将集合存储在局部变量中。备份从server2还原到后server1,执行以下语句来验证GTID状态:

      server1> SELECT GTID_IS_DISJOINT_UNION($original_gtid_executed, 
                                             $gtid_purged_set, 
                                             @@GLOBAL.gtid_executed);
      

      如果结果是1,存储功能已证实,原来gtid_executed设定的从server1$original_gtid_executed)和gtid_purged一个从添加组server2$gtid_purged_set)没有重叠,也该更新gtid_executed的设定server1,现在由以前的gtid_executed一组来自server1加上gtid_purged从集server2,这是理想的结果。确保在进行任何进一步的事务之前执行此检查server1,否则gtid_executed集中的新事务将导致它失败。

    例17.3选择最新的从站进行手动故障转移

    存储的功能GTID_UNION可用于从一组从服务器中标识最新的复制从服务器,以便在复制主服务器意外停止后执行手动故障转移操作。如果某些从属服务器出现复制滞后,则可以使用此存储的函数来计算最新的从属服务器,而无需等待所有从属服务器应用其现有中继日志,从而最大程度地缩短了故障转移时间。该函数可以返回gtid_executed每个从属服务器上的集合与该从属服务器接收的事务集的并集,该集合记录在“性能模式”表中replication_connection_status。您可以比较这些结果,以找出哪个从站的事务记录是最新的,即使尚未提交所有事务也是如此。

    在每个复制从属上,通过发出以下语句来计算事务的完整记录:

    SELECT GTID_UNION(RECEIVED_TRANSACTION_SET, @@GLOBAL.gtid_executed) 
        FROM performance_schema.replication_connection_status 
        WHERE channel_name = 'name';
    

    然后,您可以比较每个从属服务器的结果,以参见哪个具有最新的事务记录,并将该从属服务器用作新的复制主服务器。

    示例17.4检查复制从属服务器上的无关事务

    所存储的功能GTID_SUBTRACT_UUID可用于检查复制从属是否已接收到不是源自其指定主服务器的事务。如果存在,则复制设置或代理,路由器或负载平衡器可能存在问题。通过从GTID集中删除来自指定原始服务器的所有GTID,并返回剩余的GTID(如果有),可以使用此功能。

    对于具有单个主服务器的复制从服务器,发出以下语句,并提供原始复制主服务器的标识符,通常为该server_uuid值:

    SELECT GTID_SUBTRACT_UUID(@@GLOBAL.gtid_executed, server_uuid_of_master);
    

    如果结果不为空,则返回的事务是不是源自指定主服务器的额外事务。

    对于多主复制拓扑中的从属,请重复该功能,例如:

    SELECT GTID_SUBTRACT_UUID(GTID_SUBTRACT_UUID(@@GLOBAL.gtid_executed,
                                                 server_uuid_of_master_1),
                                                 server_uuid_of_master_2);
    

    如果结果不为空,则返回的事务是不是源自任何指定主服务器的额外事务。

    示例17.5验证复制拓扑中的服务器是只读的

    存储的功能GTID_INTERSECTION_WITH_UUID可用于验证服务器未发起任何GTID并处于只读状态。该函数仅从GTID集中返回源自具有指定标识符的服务器的GTID。如果服务器gtid_executed集合中的任何事务都有服务器自己的标识符,则服务器本身将发起这些事务。您可以在服务器上发出以下语句进行检查:

    SELECT GTID_INTERSECTION_WITH_UUID(@@GLOBAL.gtid_executed, my_server_uuid);
    

    示例17.6在多主复制设置中验证其他从服务器

    The stored function GTID_INTERSECTION_WITH_UUID could be used to find out if a slave attached to a multi-master replication setup has applied all the transactions originating from one particular master. In this scenario,master1 and master2 are both masters and slaves and replicate to each other.master2 also has its own replication slave. The replication slave will also receive and apply master1's transactions if master2 is configured with log_slave_updates=ON, but it will not do so if master2 uses log_slave_updates=OFF. Whatever the case, we currently only want to find out if the replication slave is up to date with master2. In this situation, the stored function GTID_INTERSECTION_WITH_UUID可以用于标识master2发起的交易,丢弃master2从中复制的交易master1GTID_SUBSET然后可以使用内置功能将结果gtid_executed与从站上的设置进行比较。如果从属服务器使用进行了最新更新master2,则gtid_executed从属服务器上的集合包含相交集中的所有事务(源自的事务master2)。

    要执行此检查,请将master2gtid_executed集合,master2服务器的UUID和从属的gtid_executed集合存储到客户端变量中,如下所示:

        $master2_gtid_executed :=
          master2> SELECT @@GLOBAL.gtid_executed;
        $master2_server_uuid :=
          master2> SELECT @@GLOBAL.server_uuid;
        $slave_gtid_executed :=
          slave> SELECT @@GLOBAL.gtid_executed;
    

    然后使用GTID_INTERSECTION_WITH_UUIDGTID_SUBSET将这些变量作为输入,如下所示:

    SELECT GTID_SUBSET(GTID_INTERSECTION_WITH_UUID($master2_gtid_executed,
                                                   $master2_server_uuid),
                                                   $slave_gtid_executed);
    

    从所述服务器标识符master2$master2_server_uuid)用于GTID_INTERSECTION_WITH_UUID识别和仅返回从那些GTIDs master2gtid_executed起源于组master2,省略那些起源于master1。然后使用,将生成的GTID集与从站上所有已执行GTID的集进行比较GTID_SUBSET。如果此语句返回非零(true),则来自master2(第一个集合输入)的所有标识的GTID 也在从属gtid_executed集合(第二个集合输入)中,这意味着从属已复制了所有源自的事务master2