作者:Nuno Carvalho 译:徐轶韬
在MySQL 8.0.14中,Group Replication再次得到了改进。现在,开发人员可以指定所有群组事务的一致性级别,甚至是单个事务的一致性级别。
请注意,这是关于群组中事务的全局同步的一致性。不同事务的隔离级别适用于每个服务器。
之前详细说明了开发人员可以选择的两个同步点:读取或写入。实际上,这些名称是简化的,正确的术语是:在事务执行之前和之后。
一致性级别
开发人员可以选择以下一致性级别:
EVENTUAL(默认值)
事务在执行之前不等待应用先前的事务,也不等待其他成员应用其更改。
这是8.0.14之前的群组复制行为。BEFORE
事务将在开始执行之前等待所有先前的事务完成。这可确保此事务将在最新的数据快照上执行,而不管其在哪个成员上执行。AFTER
事务将等待其更改已应用于其他成员。这可确保一旦此事务完成,所有后续事务都会读取包含其更改的数据库状态,而不管它们在哪个成员上执行。
BEFORE_AND_AFTER
此事务将等到:1)所有先前的事务在开始执行之前完成; 2)其变更已适用于其他成员。这可确保:1)此事务将在最新的数据快照上执行; 2)一旦此事务完成,所有后续事务都会读取包含其更改的数据库状态,而不管它们在哪个成员上执行。
正如您可能已经意识到的那样,BEFORE一致性级别可以用于读取和写入事务。AFTER一致性级别对于只读事务是“不操作”(无操作),因为它们不会产生变化。
这些不同的一致性级别提供了灵活性:1)DBA,谁可以使用这些选项来设置基础设施; 2)开发人员,能够使用最符合应用程序要求的一致性级别。
场景1
希望在不担心读取陈旧的情况下对读取进行负载平衡,群组写操作比群组读操作少得多。
在这种情况下,您应该选择AFTER。
场景2
有一个经过大量写操作的数据集,偶尔进行读取时不必担心管理/读取陈旧数据。
在这种情况下,你应该选择BEFORE。
场景3
希望工作负载中的特定事务始终从群组中读取最新数据,以便每当更新敏感数据(例如文件或类似数据的凭据)时,强制执行读取的最新的值。
在这种情况下,你应该选择BEFORE。
场景4
有一个主要是只读(RO)数据的群组,希望读写(RW)事务一旦提交就应用到任何地方,以便后续读取包括最新的数据,也包括最新写入,并且无需在每个RO事务上进行同步,仅在RW事务进行时同步。
在这种情况下,您应该选择AFTER。
场景5
有一个主要是只读数据的群组,希望读写(RW)事务始终从群组中读取最新数据,并在提交后应用到任何地方,以便后续读取包含写入的最新数据,并且不会在每个只读(RO)事务上进行同步,但仅在RW上执行。
在这种情况下,您应该选择BEFORE_AND_AFTER。
一致性范围
您可以自由选择强制执行一致性级别的范围。这很重要,因为如果将它们设置在全局范围内,一致性级别可能会对性能产生负面影响。
因此,我们确保可以使用以下范围内的group_replication_consistency系统变量设置一致性级别:
Session
SET @@SESSION.group_replication_consistency= 'BEFORE';
将强制执行当前会话的一致性级别。
Global
1 | SET @@GLOBAL.group_replication_consistency= 'BEFORE'; |
将强制执行所有会话的一致性级别。
在特定会话上设置一致性级别的可能性,允许开发人员利用以下场景:
场景6
特定系统处理几个不需要强一致性级别的指令,尽管有一种指令需要:管理对文档的访问权限。在这种情况下,系统会更改访问权限,并希望确保所有客户端都能看到正确的权限。
您只需要在这些指令上SET @@SESSION.group_replication_consistency= ‘BEFORE’ ,并使用EVENTUAL运行其他指令。
场景7
在场景6中描述的同一系统上,每天指令都需要进行一些分析处理,因此需要始终读取最新的数据。
要实现这一点,您只需要在该特定指令上 SET@@SESSION.group_replication_consistency= ‘BEFORE’ 。
总而言之,如果只有一些事务实际需要它,则不需要对全部事务运行指定的一致性级别。
但是,我要强调一点,所有读写事务都是在群组复制中完全排序的,因此即使通过发出以下内容将一致性级别设置为AFTER到当前会话:
SET @@SESSION.group_replication_consistency= 'AFTER';
此事务将等待其更改应用于所有成员,这意味着等待可能在次要节点队列上的此事务和所有先前事务。在实践中,一致性级别AFTER等待所有事务,直到包括此事务。
一致性上下文
我们还可以根据对群组的影响,即对其他成员的影响,对一致性级别分类。
BEFORE一致性级别,除了在事务流上的排序,只影响本地成员。也就是说,它不需要与其他成员协调,也不会对其交易产生影响。
换句话说,BEFORE仅影响使用它的事务。
AFTER和BEFORE_AND_AFTER一致性级别确实有对其他成员执行并发事务的副作用。这些一致性级别将使其他成员等待事务 - 如果具有一致性级别EVENTUAL的事务在执行AFTER或BEFORE_AND_AFTER的事务时启动- 直到AFTER事务在该成员上提交才可以执行,即使其他成员事务具有EVENTUAL一致性级别。
换句话说,AFTER和BEFORE_AND_AFTER会影响所有ONLINE成员。
例E1

请注意,即使T2一致性级别是EVENTUAL,如果它在T1已经处于M2的提交阶段时开始执行,则T2等待T1完成提交,然后才执行。
保障
您只能在ONLINE成员上使用BEFORE,AFTER和BEFORE_AND_AFTER的一致性级别,尝试在其他状态的成员上使用它们会导致会话错误。
一致性级别不是EVENTUAL的事务将等待执行,直到达到wait_timeout值,默认为8小时。如果超时,则抛出ER_GR_HOLD_WAIT_TIMEOUT错误。
结论
自首次发布以来,Group Replication一直在不断改进。MySQL 8.0.14包括最受欢迎的功能之一,可以指定群组的一致性级别,甚至允许只有一部分事务需要更强的一致性的更复杂场景。
请尝试并将您的反馈发送给我们。




