作者 罗小波 · 数据库技术专家
出品 沃趣科技
对于组复制这样的分布式系统来说,主要的需求之一是它需要有数据的一致性保证。换句话说,需要保证在组成员之间分布的事务的全局同步的一致性。本节将介绍组复制如何根据组中发生的事件处理一致性保证、以及如何最佳配置组的一致性保证。
4.2.1. 理解事务一致性保证
就分布式一致性保证而言,组复制无论是在正常或者故障修复的操作中,它始终是一个最终一致性的系统。这意味着一旦传入组复制的流量减慢或停止,所有组成员将具有相同的数据内容。与系统一致性相关的事件可以分为:手动操作或由故障自动触发的控制操作、数据流操作。
对于组复制,与一致性相关的控制操作包括:
添加和移除组成员,关于添加和移除组成员的数据一致性保证,详见可参考"4.3. 分布式恢复"。
网络故障保护。
主要节点故障转移:单主模式中,主要节点的故障转移也包括通过group_replication_set_as_primary() 函数触发的操作。
主要节点故障转移一致性保护
在单主模式的组中,如果主要节点发生故障转移,一个辅助节点被提升为新主要节点时,对于存在积压事务的情况下新的主要节点如何处理新写入的事务,有两种可选的处理方式:无论事务积压的大小如何,允许立即处理新写入的事务;在新的主要节点中进行访问限制,直到积压事务被应用完成才处理新写入的事务。
使用第一种方式:在主要节点发生故障之后,为了确保组成员资格以最短的时间达到稳定(重新配置组视图),组会通过选举产生一个新的主要节点,然后新的主要节点在应用来自旧的主要节点的积压事务时,立即允许新的事务写入。这种方式能够确保写一致性,但是,在新的主要节点应用完成积压事务之前,读操作可能会查询到陈旧的数据。例如:如果客户端C1刚好在旧的主要节点发生故障之前成功写入了A=2 WHERE A=1(将A=1修改为A=2),则当客户端C1重新连接到新的主要节点时,新的主要节点应用完成积压事务并完全追赶上旧的主要节点脱离集群时的状态之前,它可能会读取到A=1。
使用第二种方式:与第一种方式相比,在主要节点发生故障之后,仍然会通过组选举产生一个新的主要节点来保护稳定的组成员资格,但是,新的主要节点需要等待完全应用完成来自旧的主要节点中的积压事务之后,才允许新的事务写入。这就避免了客户端C1连接到新的主要节点时读取到陈旧的数据。不过,这样做的代价是,故障转移所需的时间可能会比较长(故障转移所需的时间与积压事务的大小成正比),在正确的配置均衡的组中,积压事务应该保持一个较小值。
在MySQL 8.0.14之前,不支持配置故障转移策略,默认情况下采用可用性最大化的策略(第一种方式)。在MySQL 8.0.14及更高版本中可以使用系统变量group_replication_consistency配置组成员在主要节点故障转移期间提供的事务一致性保证级别。详情可参考"4.2.2. 配置事务一致性保证"。
数据流操作
数据流与组中读写操作的一致性保护有关,尤其是当这些读写操作分布在所有成员中时,数据一致性的保护尤其重要。数据流操作适用于单主模式和多主模式的组。在单主模式中,通常将只读事务和读写事务进行拆分,将读写事务路由到主要节点,将只读事务均匀分配给其余的辅助节点。对于组复制来说,可能存在多个数据库Server,但是,对应用访问来说,它应该作为一个整体对外提供服务,因此,理论上,对于应用来说,在主要节点上写入的数据可以在辅助节点上即时查询。尽管组复制是使用基于Paxos算法的组通讯系统(GCS)协议编写的,但是组复制的某些流程部分是异步的,这意味着主要节点写入的事务在辅助节点中是异步应用的,因此可能出现这样的情况:客户端C2在主要节点上写入B=2 where B=1(将B=1修改为B=2),然后,客户端C2立即连接到其他辅助节点中执行查询可能会读取到B=1,这是由于该事务在辅助节点中可能处于积压状态(在辅助节点中还未来得及应用)。
事务同步点(位置)
在读取或写入事务时你可以根据需要选择是否需要配置组的数据强一致性。如果配置了组的数据强一致性,则,只读事务不会读取到陈旧的数据,读写事务在非发起写事务的组成员中不会造成数据延迟(通过系统变量group_replication_consistency进行配置,详情可参考"4.2.2. 配置事务一致性保证")。
如果需要实时读取数据,则可以配置为在读取时进行数据同步,当前客户端会话在执行只读事务时将等待一个给定的点位(应用完成所有之前的更新事务的时间点)之后才会真正开始执行。使用这种方法只影响当前会话,不影响所有其他并发数据操作(只读和读写事务)。
如果在执行修改数据时实时同步给其他组成员,则可以配置为在写入时进行数据同步,当客户端会话执行读写事务时将一直等待,直到所有其他的辅助节点都已写入其数据。由于组复制对写入操作遵循的是全局顺序,因此,这意味着一个读写事务需要等待其他所有成员应用完成它们队列中所有先前写入的事务以及本次写入的事务。
在读取时进行数据同步和在写入时进行数据同步,这两种方法都可以确保上述对于客户端C2在主要节点写入数据,然后再连接到辅助节点执行查询时无法读取到最新数据的问题。这两种选择各有其优缺点,这些优缺点与系统的工作负载直接相关,以下是一些根据不同的工作负载类型选择不同的数据同步方法的建议。
在这些情况下,您应该选择在写入时进行同步。
* 组中的访问读多写少,希望对读取操作进行负载均衡,从任何读成员中读取时都希望能够读取到最新的数据,且不对读负载均衡中的任何成员通过配置相关的限制来避免读取到陈旧的数据。
* 组中的访问读多写少,希望在读写事务提交后就应用于所有组成员,以便后续的读取操作能够读取到最新的数据(包括发起事务写入的成员)。这样可确保每个RO事务执行不受到影响,而只影响RW事务的提交时长。
在这些情况下,您应该选择在读取时进行同步。
* 组中的访问写多读少,希望对读操作进行负载均衡,从任何读成员读取时都希望能够读取到最新的数据,且不对读负载均衡中的任何成员通过配置相关的限制来避免读取到陈旧的数据。
* 希望工作负载中的特定事务始终从组中读取最新数据,例如:每当敏感数据被更新时(例如文件或类似数据的凭据)希望强制读取最新数据。
4.2.2. 配置事务一致性保证
在"4.2.1. 理解事务一致性保证"中的"务同步点(位置)"部分我们简单介绍了两个概念:事务同步点可以选择"读时同步"和"写时同步",但这是为了方便理解的一种简化术语,在组复制中使用的术语是:事务执行前(before)和执行后(after)。本节将介绍不同的一致性级设置对组处理的只读(RO)和读写(RW)事务的不同影响(不同的一致性级别设置,分别对应着RO和RW事务在执行前、执行后的不同的组合)。
4.2.2.1. 一致性级别详解
事务一致性级别由系统变量group_replication_consistency进行设置,可以在会话级别根据需要动态对某个事务进行设置,你可以使用这些不同设置值来灵活地为组复制中事务提供一致性保证。下面根据系统变量group_replication_consistency的有效值列表对一致性级别进行详细介绍。
EVENTUAL:RO和RW事务在执行之前都不会等待前面的事务应用完成(即,事务直接执行,不等待积压事务应用完成)。这是group_replication_consistency变量的默认值(也是引入该系统变量之前组复制的默认行为)。RW事务不等待其他成员应用事务。意味着设置该值的成员中的事务可以先于其他成员外部化。还意味着,在发生主要节点故障转移时,新的主要节点不需要等待积压的事务(来自旧的主要节点的事务)立即接受新的RO和RW事务,这可能造成新的RO事务读取到陈旧的数据(因为之前旧主要节点中的最新数据还未同步到新的主要节点)、新的RW事务可能由于冲突导致回滚(冲突认证检测会发现新的RW事务可能与来自旧主要节点的积压RW事务发生冲突)。
EVENTUAL一致性级别的流程图如下。
结合上图对EVENTUAL一致性级别算法的简要描述。
* 1. 事务T1(一致性级别为EVENTUAL)从组成员M1开始执行。
* 2. 事务T1执行到提交点(commit)时,在这里会将事务的变更数据广播发送给所有组成员(包括发起事务T1的M1成员,对于M1来说,T1就是它的本地事务,对于M2和M3来说,T1就是它的远端事务)。
* 3. 事务T1被组中的所有成员接收到之后,所有成员都会各自对其进行冲突认证检测:如果存在冲突,则对于M1来说,回滚T1事务,对于M2和M3来说,丢弃接收到的T1事务数据包;如果不存在冲突,则对于M1来说,提交T1事务,对于M2和M3来说,对T1事务进行排队等待执行与提交。
* 4. 事务T2(一致性级别为EVENTUAL)从组成员M3上开始执行,紧接着,M3接收到T1事务的数据,这时,在M3中,T2事务不需要等待T1事务应用(提交)完成就可以继续往后执行,如果T2事务操作的数据与T1事务存在重叠,则T2读取到的数据就可能不是最新的,且对于T2事务来说,如果与T1事务存在冲突,还存在着被回滚的可能。
BEFORE_ON_PRIMARY_FAILOVER:新RO或RW事务在新当选的主要节点应用完成来自旧的主要节点的积压事务之前,会被保持(不应用,类似于处在等待状态,积压事务被应用完成之后,才会处理新的RO和RW事务)。这确保当主要节点故障转移发生时,客户端总是能查询到发生故障的主要节点上的最新值,从而保证了一致性。但这意味着新的主要节点在应用积压事务过程中的延迟(这里指的是客户端访问新主要节点的响应延迟)客户端需要自行处理。通常这种延迟很小,但是实际延迟时间的长短取决于积压事务的大小。
BEFORE:RW事务在应用(applied)之前会等待所有前面的事务(积压事务)完成。RO事务在执行(executed)之前会等待所有前面的事务(积压事务)完成。这样使得事务仅通过牺牲响应延迟就可以确保读取到最新的值。实际上,只是确保了RO事务上的同步,对于RW事务来说,只是等待了它之前积压的事务完成,并不会等待它在所有的其他组成员上完成应用(不过,由于RO事务要求同步,RO事务能够将一部分甚至大部分数据进行同步,所以能够一定程度上减少RW事务上的同步开销,也就是说,该一致性级别适合于写多读少的场景)。
BEFORE一致性级别的流程图如下。
结合上图对BEFORE一致性级别算法的简要描述。
* 1. 事务T1(一致性级别为EVENTUAL)从组成员M1开始执行。
* 2. 事务T1执行到提交点(commit)时,在这里会将事务的变更数据广播发送给所有组成员。
* 3. 事务T1被组中的所有成员接收到之后,所有成员都会各自对其进行冲突认证检测:如果存在冲突,则对于M1来说,回滚T1事务,对于M2和M3来说,丢弃接收到的T1事务数据包;如果不存在冲突,则对于M1来说,提交T1事务,对于M2和M3来说,对T1事务进行排队等待执行与提交。
* 4. 事务T2(一致性级别为BEFORE)从组成员M3上开始执行,在T2执行之前,会向所有组成员发送一条消息,该消息提供了T2事务的全局顺序(从上图中我们可以得知,T1事务的全局顺序在T2之前,因为T1事务先执行)。
* 5. 组中的成员收到并按顺序处理该消息时,M3将从消息流中获取组复制应用程序的RECEIVED_TRANSACTION_SET(RECEIVED_TRANSACTION_SET是被允许提交的远程事务的集合,无论这些事务是否实际上已经提交,它们都包含在此集合中)。该集合提供了在T2事务之前存在的所有远程事务,由于Server已经确保了本地事务的一致性,所以这里只需要跟踪远程事务。尽管M3之前已经将包含了T2事务的全局顺序的消息发送给了组中的所有成员,但是只有M3才需要对其进行操作,因此其他组成员会丢弃该消息而不采取任何行动。
* 6. 在M3中,在应用(提交)完成了RECEIVED_TRANSACTION_SET中所有的远程事务之后,事务T2才开始执行,这与可以确保T2不会读取或执行像你对于全局顺序(这里的全局顺序为:T1->T2)来说已经过时的数据。这种等待仅发生在执行了一致性级别为BEFORE的事务的Server上(这里为执行了一致性级别为BEFORE的T2事务的组成员M3),对于组中的其他组成员(这里指组成员M1和M2)不受此等待的影响。
* 7. 一旦T2事务开始执行,接下来就会按照步骤2和步骤3继续往下执行。
PS:对于BEFORE这个一致性级别,它涵盖了BEFORE_ON_PRIMARY_FAILOVER提供的一致性保证。
AFTER:RW事务会等待它的更改被应用到所有其他成员。此一致性级别对RO事务没有影响(因为RO事务不会产生数据变更)。它只确保在本地成员上提交RW事务时,该RW事务的数据变更会在组中其他所有成员中应用,以便所有后续的事务在任何成员上都能够获取到最新的数据(通过确保只在RW事务上使用同步,RW事务会将所有写入的新数据都实时同步到组中其他的所有成员中,这就减少了RO事务上的同步开销。也就是说,该一致性级别比较适合读多写少的场景)。
AFTER一致性级别的流程图如下。
结合上图对AFTER一致性级别算法的简要描述。
* 1. 事务T1(一致性级别为AFTER)从组成员M1开始执行。
* 2. 事务T1执行到提交点(commit)时,在这里会将事务的变更数据广播发送给所有组成员。
* 3. 事务T1被组中的所有成员接收到之后,所有成员都会各自对其进行冲突认证检测:如果存在冲突,则对于M1来说,回滚T1事务,对于M2和M3来说,丢弃接收到的T1事务数据包;如果不存在冲突,则进入步骤4。
* 4. 在其他组成员上(这里指M2和M3),T1事务被排队执行,一旦事务进入prepare阶段(即,数据在等待commit指令的存储引擎上持久化完成),它将向所有的成员发送ACK确认。
* 5. 一旦所有的成员都接收到来自所有成员的ACK确认(对于M1来说,T1事务是由它自己发起,所以已经隐含确认了prepare状态),此时,所有成员都将继续执行T1事务的提交操作(commit)。
* 6. 事务T2(一致性级别为EVENTUAL)从组成员M3开始执行,此时由于T1事务正在提交过程中(还未提交完成),所以T2事务会持续等待T1事务完成之后才开始执行,这样,就可以确保T1事务之后的任何事务都将读取到T1的数据变更(最新数据)。
* 7. 一旦事务T2开始执行,接下来就会按照"EVENTUAL一致性级别算法的简要描述"中的步骤2和步骤3继续往下执行(注意,由于T2事务的一致性级别是EVENTUAL,所以T2事务的后续步骤不会按照"AFTER一致性级别算法的简要描述"中的步骤2和 步骤3往下执行)。
PS:对于AFTER这个一致性级别,它涵盖了BEFORE_ON_PRIMARY_FAILOVER提供的一致性保证。
BEFORE_AND_AFTER:一致性级别要求最高,RW和RO事务执行时都要求数据同步,RW事务在执行时需要等待之前的积压事务应用完成,且需要等待自己的数据变更在其他所有组成员上都应用。RO事务在执行时需要等待之前的积压事务应用完成。该一致性级别适合对数据的读写一致性都要求高的场景。
BEFORE_AND_AFTER一致性级别的流程图如下。
结合上图对BEFORE_AND_AFTER一致性级别算法的简要描述。
* BEFORE_AND_AFTER一致性级别下,同一事务会将BEFORE和AFTER一致性级别的算法结合在一起。
PS:对于BEFORE_AND_AFTER一致性级别,它涵盖了BEFORE_ON_PRIMARY_FAILOVER提供的一致性保证。
一致性级别BEFORE和BEFORE_AND_AFTER都可以用于RO和RW事务。但AFTER一致性级别对RO事务没有影响,因为RO事务不会产生数据变更。
4.2.2.2. 如何选择一致性级别
不同的一致性级别有不同的适用场景。下面是一些不同一致性级别的适用场景建议:
场景1:读多写少,且在不允许读取到陈旧的数据的情况下,还要求配置读负载均衡。在这种情况下,应该选择一致性级别为 AFTER。
场景2:写多读少,且不允许读取到陈旧的数据。在这种情况下,你应该选择一致性级别为 BEFORE。
场景3:工作负载中的特定事务(如:更新敏感数据)需要读取组的最新数据。在这种情况下,应该选择一致性级别为 BEFORE。
场景4:读多写少,且希望RW事务一旦提交就会被同步到组中的其他任何成员,以便后续的RO事务都能够读取到最新数据,不会导致RO事务读取最新数据时产生同步开销。在这种情况下,应该选择一致性级别为 AFTER。
场景5:读多写少,且希望RW事务一旦提交就会被同步到组中的其他任何成员,且希望后续的RW和RO事务总是能够读取到最新的数据,也不希望后续RO事务读取最新数据时产生同步开销。这种情况下,应该选择一致性级别为 BEFORE_AND_AFTER。
您可以根据需要自行选择强制执行一致性级别的范围。要注意:如果将一致性级别设置为全局范围,则会对组性能产生负面影响。因此,除非必须,否则建议只在会话级别根据需要动态使用系统变量group_replication_consistency来配置组的一致性级别。
# 若要在当前会话上强制执行一致性级别,用如下语句设置
mysql> SET @@SESSION.group_replication_consistency= 'BEFORE';
# 要在所有会话上强制执行一致性级别,使用如下语句设置
mysql> SET @@GLOBAL.group_replication_consistency= 'BEFORE';
在特定会话上设置一致性级别的场景可能有如下一些:
场景6:在该应用场景中,多数语句不需要强一致性,只有少数语句(例如:某一种类型的语句)要求强一致性。例如:关于访问某库表的权限修改,在此场景中,希望确保任何时候所有客户端都看到正确的权限。只需要在操作修改库表权限的会话中先执行set @@SESSION.group_replication_consistency= 'AFTER' 语句即可(其他任何操作不需要修改一致性级别,保持系统变量group_replication_consistency的全局值为"EVENTUAL")。
场景7:与场景6中描述的相同的系统上,每天都要读取最新数据执行一次数据分析处理。只需要在执行该分析处理的会话中先执行set @@SESSION.group_replication_consistency=‘BEFORE’ 语句即可。
总而言之,除非必须,否则不需要全局针对所有事务都运行较高的一致性级别,特别是只有一部分事务有一致性级别要求的场景中。
注意:所有RW事务在组中都是全局排序的,所以,一旦在当前会话中设置会话级别的一致性级别为AFTER,则在该会话中执行RW事务时会等待其他成员应用完成该事务。也就是说,由于RW事务全局是排序的,而该RW事务是后发起的,所以,实际上等于还需要同时等待该RW事务之前所有的积压事务应用完成,而不仅仅只是该RW事务。
4.2.2.3. 一致性级别的影响
分类一致性级别的另一种方法是根据对组的影响进行划分,即一致性级别对其他成员的影响。
对于BEFORE一致性级别,除了在事务流上排序之外,它只影响本地成员,即,它不需要协调其他成员,也不影响其他成员的事务。换句话说,BEFORE一致性级别只影响使用该一致性级别的事务。
AFTER和BEFORE_AND_AFTER一致性级别对在其他成员上执行的并发事务具有副作用,当执行具有AFTER或BEFORE_AND_AFTER一致性级别的事务时,即使后续的事务是以EVENTUAL一致性级别运行的也仍然需要等待AFTER或BEFORE_AND_AFTER一致性级别的事务执行完成。对于其他成员也是如此。即,AFTER或BEFORE_AND_AFTER一致性级别会影响所有的ONLINE成员。
为了进一步说明这一点,假设一个组包含三个组成员:M1、M2、M3,在M1上执行了如下语句:
# 修改一致性级别为AFTER
mysql> SET @@SESSION.group_replication_consistency= AFTER;
# 执行一个INSERT语句
mysql> BEGIN;
mysql> INSERT INTO t1 VALUES (1); # 为了方便看到效果,这里最好是一个大事务
mysql> COMMIT;
然后,在应用上述事务时,对成员M2 执行如下语句:
# 修改一致性级别为EVENTUAL
mysql> SET SESSION group_replication_consistency= EVENTUAL;
# 执行DML事务,就可以发现M2执行的事务被阻塞,需要等待上述执行先执行完成。需要注意的是,如果在M2执行事务时,M1中的事务还没有被M2收到时,select语句是可以立即执行成功的,但如果M1中的事务被M2收到并进入队列之后,执行select ... for update语句也会被阻塞
只能在ONLINE状态的组成员中使用BEFORE、AFTER_AND_BEFORE一致性级别,试图在其他状态(其他状态包括:RECOVERING、OFFLINE、ERROR、UNREACHABLE)的成员上使用时会导致报错。
如果一个非EVENTUAL的一致性级别的事务执行时,持续等待且一直未返回,当达到了系统变量wait_timeout配置的超时时间(默认为8小时)之后,会抛出ER_GR_HOLD_WAIT_TIMEOUT错误信息。
4.2.2.4. 一致性对选主的影响
本节描述在一个单主模式的主中,一致性级别是如何影响选主的(选举主要节点)。例如:组自动检测故障并调整处于活动状态的成员的视图,换句话说就是成员资格配置。此外,如果组以单主模式部署,每当组成员资格发生更改时,都会检查所有的组成员状态,以便检测组中是否仍然存在主要节点。如果没有,则从辅助节点成员列表中选择一个组成员提升为新的主要节点。这个过程就是选举一个辅助节点晋升为主要节点的过程。
当系统检测到故障并自动重新配置时,你也许希望一旦辅助节点晋升完成,则新的主要节点与旧的主要节点之间的数据状态相同。换句话说,你可能希望新的主要节点能够对外提供读写访问时,新的主要节点就已经应用完成了所有积压事务,即,一旦应用程序完成了故障转移到新的主要节点时,就不会读取或者修改陈旧的数据记录(即使是暂时的也不行)。
从MySQL 8.0.14版本开始,辅助节点晋升为主要节点之后,你可以指定新主要节点的行为,通过新增的系统变量group_replication_consistency来控制新的主要节点采用什么一致性级别(默认为EVENTUAL),如果设置为BEFORE_ON_PRIMARY_FAILOVER,则在对外提供读写访问之前,会先应用完成积压事务。这就确保了客户端完成了故障转移到新主要节点之后,能够看到最新数据。同时,也可以防止出现下列不正常的现象:
RO和RW事务不会读取到陈旧的数据,这可以防止这些陈旧数据被应用程序访问到。
不会导致新执行的RW事务发生荒谬的回滚,这是因为与复制事务(远程事务)存在写冲突的新的RW事务此时会处于待处理状态,需要先应用积压事务才会处理新的RW事务。
读写事务不会发生读偏差(不会读取到陈旧的数据),如:
mysql> BEGIN;
# 假设x=1在t1表中,x=2还在积压事务中,那么,在这里需要等待积压事务应用完成,才能执行查询,以便读取到最新的数据x=2
mysql> SELECT x FROM t1;
mysql> INSERT x INTO t2;
mysql> COMMIT;
以上事务如果不使用BEFORE_ON_PRIMARY_FAILOVER一致性级别,那么,将导致插入t2表中的值为x=1,而不是x=2(因为发生了读偏差),但是,无论是否设置为BEFORE_ON_PRIMARY_FAILOVER一致性级别,都不会导致写冲突,而最多只会发生读偏差,从而导致写入t2表的数据不是最新的。
为了确保组中所有的组成员无论谁被晋升为新的主要节点之后,都会提供相同的一致性级别,组的所有成员都应该在配置中持久化一致性级别为BEFORE_ON_PRIMARY_FAILOVER(或更高的一致性级别)。这可以防止应用程序故障转移完成之后查询到陈旧的数据,设置语句如下:
# 使用set语句将系统变量group_replication_consistency的值持久化为BEFORE_ON_PRIMARY_FAILOVER
root@localhost : (none):57: > SET PERSIST group_replication_consistency='BEFORE_ON_PRIMARY_FAILOVER';
Query OK, 0 rows affected (0.02 sec)
# 上述语句执行完成之后,该系统变量值会被持久化到auto.cnf文件中(该文件是一个JSON格式数组,且其中已经存在了组辅助的一些预设持久化变量,注意:对于使用 SET PERSIST语句持久化系统变量的操作,只会影响到当前成员,其他成员不会进行同步,所以,建议在所有组成员中都执行相同的操作)
[root@node1 ~]# cat /data//mysqldata1/mydata/mysqld-auto.cnf
{ "Version" : 1 , "mysql_server" : { "group_replication_consistency" : { "Value" : "BEFORE_ON_PRIMARY_FAILOVER" , "Metadata" : { "Timestamp" : 1569841133777625 , "User" : "root" , "Host" : "localhost" } } , "mysql_server_static_options" : { "group
_replication_enforce_update_everywhere_checks" : { "Value" : "OFF" , "Metadata" : { "Timestamp" : 1569402731795015 , "User" : "mysql.session" , "Host" : "localhost" } } , "group_replication_single_primary_mode" : { "Value" : "ON" , "Metadata" : {
"Timestamp" : 1569402731795762 , "User" : "mysql.session" , "Host" : "localhost" } } } } }
尽管在使用BEFORE_ON_PRIMARY_FAILOVER一致性级别时,在未应用完成所有的积压事务之前,所有的写操作都会进入待处理状态,但并不是所有的读操作都被阻塞,对于一些不修改数据的查询是允许执行的(例如:对于一些状态表的查看等,这对一些问题排查和性能监控非常有用)。
SHOW 语句
SET 语句
DO 语句
EMPTY 语句
USE 语句
对performannce_schema和sys 数据库使用 SELECT 语句
对informationn_schema.processlist表使用SELECT 语句
对不指定表的用户自定义函数使用SELECT 语句
STOP GROUP_REPLICATION 语句
SHUTDOWN 语句
RESET PERSIST 语句
事务不能永远处于待处理状态(on-hold),如果处于该状态的时间超过系统变量wait_timeout设置的值,则会返回ER_GR_HOLD_WAIT_TIMEOUT错误信息。
关于克隆插件,详见链接:https://dev.mysql.com/doc/refman/8.0/en/clone-plugin.html
| 作者简介
罗小波·数据库技术专家
《千金良方——MySQL性能优化金字塔法则》作者之一。熟悉MySQL体系结构,擅长数据库的整体调优,喜好专研开源技术,并热衷于开源技术的推广,在线上线下做过多次公开的数据库专题分享,发表过近100篇数据库相关的研究文章。
延伸阅读
组复制常规操作-在线配置组 | 全方位认识 MySQL 8.0 Group Replication
组复制监控 | 全方位认识 MySQL 8.0 Group Replication
组复制安装部署 | 全方位认识 MySQL 8.0 Group Replication
组复制背景 | 全方位认识 MySQL 8.0 Group Replication
全文完。
Enjoy MySQL 8.0 :)
叶老师的「MySQL核心优化」大课已升级到MySQL 8.0,扫码开启MySQL 8.0修行之旅吧