作为近实时数据复制产品,Q 复制以表为单位定义复制关系,以事务为单位复制数据变化,因此,如果源端应用提交的事务经常会涉及到多张表,这些表需要被定义在同一数据通道里,即同一个队列映射里,也可以称之为一个一致性组(Consistency Group,CG),这样原事务就能完整地在目标端得到应用。换句话说,Q 复制是在队列映射级别保证数据的一致性的。然而,在现实应用中,特别是大型的企业,源端可能有上百种应用同时运行,这就造成无法完美地将相关表定义在同一队列映射中。另一方面,由于表中数据量的不同、性能要求的不同、数据库的部署的多样性,造成有些情况下无法将相关表定义在一起。针对这个问题,Q 复制在 V10.2.1 中,创新性地提出了多队列映射之间的协同,即 MCG Sync(Multiple Consistency Group Synchronization)。本文将详细介绍 MCG Sync 功能的基本原理和使用,相信会对既希望通过分组提高 Q 复制性能又希望保持数据一致性的用户大有帮助。
在 Q 复制中,源表与目标表之间的复制关系是定义在 Q 预定中,即 QSUB。在定义 Q 预定 QSUB 时,又需要指明该 QSUB 使用哪个队列映射 QMAP。一个队列映射 QMAP,则定义了源端队列管理器中的发送队列 SENDQ 和目标端队列管理器中的接收队列 RECVQ 的映射关系,换句话说,队列映射 QMAP 实际上是定义了一个数据通道,以传输 QSUB 的数据变化。QSUB 和 QMAP 的关系可以简单概括为,一个 QSUB 只能存在于一个队列映射 QMAP 中,但一个队列映射 QMAP 可以包含多个 QSUB。
在实际应用中,与单个应用交互的服务器、系统、数据库和数据库表等对象不可能是单一的。从数据库层面,数据库设计人员在设计数据库表时,会根据业务需求、范式规范等因素,将应用涉及的字段定义在不同表中。而从系统架构层面,为了有效地利用资源、分散风险、增强可维护性等等原因,数据库表在物理上可能也会分布在不同系统和服务器上。因此,单个数据通道是通常是不能满足业务需求,也就是说通常不可能在定义所有 QSUB 使用同一个 QMAP。在定义 QSUB 时,Q 复制设计人员就需要从数据量的大小、表之间的相关性等因素将不同的表定义在不同的数据通道即 QMAP 中。另一方面,从系统和应用的扩展性看,即使早期一个 QMAP 能满足业务需求,随着时间的推移、业务的扩展,也必然会出现多个分组。
众所周知,Q 复制中的数据的一致性是 QMAP 级别的。也就是说,源端 Q Capture 程序捕获到数据变化后,以事务为单位将变化传输到目标端,目标端的 Q Apply 程序也是以事务为单位应用该变化。尽管为了提高扩展性(Scalability),目标端 Q Apply 程序会对事务进行依赖性分析,以提高事务应用的并行度,导致事务间的顺序不是与他们在源端发生的顺序相同,Q 复制不会更改事务内的操作顺序。换句话说,对于单个事务,如果其涉及到表都在同一个 QMAP 中,原事务在目标端会被严格地重演,数据必然是一致的。因此,通常我们建议将事务涉及到的所有表定义在同一个队列映射里。如果一个事务涉及到多张表,而这些表又被分散到多个 QMAP 中,那么源事务就会被分成几个事务在不同 QMAP 中传输。而由于中间数据传输速率的不同,这个事务的不同部分到达目标接收队列的时间会出现偏差。同时,由于目标端多个接收队列之间是完全独立的,处理不同接收队列的不同 browser 间不存在通信,也就不能保证数据应用到目标表的顺序是否与原事务保持一致,最终很可能会导致数据发生各种不一致的情况。
然而,用户应用千差万别,除非将所有表都定义在同一数据通道里,数据的一致性才能得到保障,但这又违背了客观情况。例如在一个主机上的 data sharing 环境里,尽管系统有多个成员,为了保证数据的一致性,Q Apply 程序只能运行在单个成员上,这就将 Q 复制的处理能力限制在了一个成员上。对于许多大型的企业,数据量是巨大的,特别是某些批量处理产生的事务量,很容易就能超过单个 data sharing 成员的容量,最终导致 Q 复制远远落后于源端事务提交的速率,而同时其他 data sharing 成员的能力又不能得到有效利用。因此,分组势在必行,数据一致性又不可丢,如何平衡二者,我们在下节会进行讨论。
在讨论如何平衡分组和数据一致性前,先简单介绍一下什么是 MCG Sync 功能。MCG Sync 功能时针对于多个接收队列 RECVQ 的 Q 复制拓扑。该功能可以保证在一些计划外的中断发生时,即便某些接收队列 RECVQ 中的数据丢失了,在将负载切换到备用站点前,仍然能找到一个时间点,在这个时间点上,数据是确定一致的。对于多个接收队列 RECVQ 的灾难恢复,此功能是至关重要的。
我们首先定义两个概念:
用户可以使用 ASNCLP 命令行配置工具创建 MCG 组,并将一系列的一致性组即队列映射 QMAP 指定为该 MCG 组的成员。对于同一个 MCG 组里协同开关为开启状态的队列映射,Q Apply 程序将对它们进行协同,其 browser 进程将确保 Q Apply 程序不应用那些对其他一致性组来说还未得到的变化。如果不这么限制,我们就不能保证在某一个时间点上,事务是完整一致的。该协同开关可以方便地通过命令动态地打开或关闭。
另外,一旦开启协同工作模式,用户还可以:
Q 复制 MCG Sync 功能的关键在于在跨队列映射的情况下,如何协同不同的 Q Apply 程序,并且保证被拆分的事务能够完整、一致地在目标端重现。本节将首先讨论分组和数据一致性平衡,而后介绍 Q 复制 MCG Sync 的原理。
分组,对数据复制产品来说,实际上代表的是对可并行性、可扩展性的性能需求。纵观表级别数据复制技术的发展,针对可扩展性和数据一致性,我们可以粗略地定义两个极端:
Q 复制技术实现的是介于这两者之间的事务一致性。也就是说,以事务作为最小的工作单元,经过分析,对于不存在关联性的事务,并发地应用;对于存在关联性的事务,按照源事务发生的顺序严格执行。但在 MCG Sync 功能之前,Q 复制只能在单个队列映射里同时兼顾性能和数据一致性,对可扩展性来说仍然做得不够。客户虽然可以很方便地配置多个队列映射,增大并行性,但实际上就使之成为了以队列映射级别为对象的对象级一致性。对于某些查询的应用,即对数据的实时性要求不太高的情况下,该配置能满足需求,但一旦出现不可预期的中断,事务的某个部分丢失了,这就会造成 failover 之前无法保障数据处于一致的状态。因此,如何既提高可扩展性,又保证队列映射级别的时间点一致性,是 MCG Sync 功能要解决的问题。
Q Apply 程序内部存在多个进程,其中的 browser 进程负责从目标队列管理器中的接收队列 RECVQ 中读取从 MQ 消息。接收队列 RECVQ 中的 MQ 消息是由 Q Capture 程序捕获数据变化后根据变化构建并发送过来的。除了包含数据变化,MQ 消息中还包含了日志的序列号(Log Sequence Number,LSN),即源端数据库提交事务的事务号。Q Apply 程序的 browser 进程不断地读取 MQ 消息,直到 Q Apply 程序的内存满了。此时 browser 程序将它读到内存里的所有消息中最大的事务号通知给与它同处与一个 MCG 组的其他 Q Apply 程序,该事务号我们称之为 MAX_CMT_SEQ_READ。
该通知是通过更新所有 Q Apply 程序能够共同访问的一张控制表 ASN.IBMQREP_MCGSYNC。每个 MCG 组都共享一张 ASN.IBMQREP_MCGSYNC。MCG 组里的每个 CG 都在这张表中对应一行,browser 程序在阶段性地更新自己读到的最大事务号的同时,也查询其他 CG 的最大事务号,由此确定其内存中的消息是否可以被应用到目标端。
确定消息是否可以被应用的基本原则就是,找出最大的一个事务点,比该点小的事务的所有部分都已到达接收队列 RECVQ 并已被对应的 browser 进程读入内存。对于这个事务点,我们称之为 NEXT_APPLYUPTO_TIME。
如果在某段时间内,源端并未发生数据变化,那么 Q Capture 程序就会规律地发送心跳消息(Heartbeat)。心跳消息中也会包含一个日志序列号,该序列号代表的是 Q Capture 程序当前在日志中检测到的最大事务号,如果 Q Capture 程序正好读到日志末尾,则该值为当前时间。因此,需要特别提醒地是,如果要使用 MCG Sync 功能,一定同时要确保心跳消息是打开的,这样在其中一个 CG 没有数据变化时,browser 尽管无法得到更多有关数据变化的序列号,也还能从心跳消息中读到更新的时间点,从而保障整个 MCG 组的进程继续前行,不会因此被阻塞。
目前 Q 复制支持两种 MCG Sync 的模式:Unbridled 和 In Step。在创建 MCG 组时用户可以选择其中之一。
Q 复制 MCG Sync 功能的实现包括控制表的变化、新的 Admin 配置命令、新的操作命令等。
为了实现 MCG Sync 功能,Q Apply 端新增了两个控制表,这两个控制表都以 ASN 作为模式名,ASN.IBMQREP_MCGPARMS 表和 ASN.IBMQREP_MCGSYNC 表。对于一个 MCG 组,只需要一份 ASN.IBMQREP_MCGPARMS 表和 ASN.IBMQREP_MCGSYNC 表,因为这两个表是由 MCG 组所涉及的所有 Q Apply 程序共同访问和使用的。另外,为了更好地监控协同的状态,Q Apply 端还新增了监控表 IBMQREP_MCGMON 表。
ASN.IBMQREP_MCGPARMS 表中只有一行,用于定义 Q Apply 程序处理 MCG 组所需的参数,包括 browser 通知 MAX_CMT_SEQ_TIME 和检测 NEXT_APPLYUPTO_TIME 的频率,In Step 模式中 Q Apply 程序被运行应用的毫秒数。该表由 MCGNAME 列作为关键字,具体定义如表 1 所列。
表 1. ASN.IBMQREP_MCGPARMS 表
名称 | 位置 | 数据类型 | 取值范围 | 说明 |
---|---|---|---|---|
MCGNAME | ASN.IBMQREP_MCGPARMS | VARCHAR(64);NOT NULLABLE | N/A | MCG 组名,唯一标识一个 MCG 组。 |
MCGSYNCINT | ASN.IBMQREP_MCGPARMS | INTEGER; NOT NULLABLE; 单位毫秒 | 默认值 1000;建议值 100~3000 | 定义 Q Apply 程序更新 ASN.IBMQREP_MCGSYNC 表和检测 NEXT_APPLYUPTO_TIME 的频率 |
MCGSYNCSTEP | ASN.IBMQREP_MCGPARMS | INTEGER;NOT NULLABLE | 默认值 0。>=0 的整数 | 当值为 0 时,代表 Unbridled 模式;当值大于 0 时,代表 In Step 模式中 Q Apply 程序被运行应用的毫秒数。 |
需要注意的是,在设置 MCGSYNCSTEP 的毫秒数时,用户需要考虑性能需求。一个太小的值可能会导致性能瓶颈。另外,一个小于 MCGSYNCINT 的值是没有意义的,因为 Q Apply 程序以 MCGSYNCINT 为周期进行协同,小于 MCGSYNCINT 的 Step 会导致在一个特定周期内 Q Apply 程序无法充分发挥能力。因此一个合理的 MCGSYNCSTEP 值非常关键,通常我们建议 MCGSYNCSTEP 的值两倍于 MCGSYNCINT 的值。
ASN.IBMQREP_MCGSYNC 表用于协同各个一致性组。该表关键字由 MCGNAME、REPQMAPNAME、APPLY_SCHEMA 组成,用于唯一标识一个一致性组,表的具体定义如表 2 所列。
表 2. ASN.IBMQREP_MCGSYNC 表
名称 | 位置 | 数据类型 | 取值范围 | 说明 |
---|---|---|---|---|
MCGNAME | ASN.IBMQREP_MCGSYNC | VARCHAR(64);NOT NULLABLE | N/A | MCG 组名,唯一标识一个 MCG 组。 |
REPQMAPNAME | ASN.IBMQREP_MCGSYNC | VARCHAR(64); NOT NULLABLE; 单位毫秒 | N/A | 即队列映射的名字,也是该一致性组的名字,与 IBMQREP_SENDQUEUES 和 IBMQREP_RECVQUEUES 中的队列映射名字一致。 |
APPLY_SCHEMA | ASN.IBMQREP_MCGSYNC | VARCHAR(30);NOT NULLABLE | N/A | 即 Q Apply 程序的模式。 |
UPDATE_TIME | ASN.IBMQREP_MCGSYNC | TIMESTAMP;NOT NULLABLE | N/A | 即 Q Apply 程序更新 ASN.IBMQREP_MCGSYNC 表的当前时间 |
MAX_CMT_SEQ_READ | ASN.IBMQREP_MCGSYNC | VARCHAR(16) FOR BIT DATA;NOT NULLABLE | 初始值 x' 00000000000000000000000000000000' | 即 browser 进程读到的最大事务的事务号 |
MAX_CMT_TIME_READ | ASN.IBMQREP_MCGSYNC | BIGINT;NOT NULLABLE | 初始值为 0 | 即 browser 进程读到的最大事务的提交时间 |
OLDEST_TRANS | ASN.IBMQREP_MCGSYNC | BIGINT;NOT NULLABLE | N/A | 是一个时间戳,用于确认 Q Apply 程序相对于源端进程的差距。 |
NEXT_APPLYUPTO_TIME | ASN.IBMQREP_MCGSYNC | BIGINT;NOT NULLABLE | N/A | 代表对于该一致性组来说,它能够应用的最大事务的时间戳。 |
NUM_TRANS | ASN.IBMQREP_MCGSYNC | INTEGER;NOT NULLABLE | N/A | 指的是 Q Apply 程序当前内存中该一致性组所属的事务数。 |
NUM_MSGS | ASN.IBMQREP_MCGSYNC | INTEGER;NOT NULLABLE | N/A | 指的是 Q Apply 程序当前内存中该一致性组所属的消息数。 |
STATE | ASN.IBMQREP_MCGSYNC | CHAR(1);NOT NULLABLE | [N,A,I] | N 代表 New,指的是该一致性组处于新建状态; A 代表 Active,指的是该一致性组处于活动、协同状态; I 代表 Inactive,指的是该一致性组处于不活动、未协同状态。 |
STATE_CHANGE_TIME | ASN.IBMQREP_MCGSYNC | TIMESTAMP | N/A | 记录一致性状态变化时的时间戳。 |
需要注意的是,对于 OLDEST_TRANS 的值:
而对于 NEXT_APPLUPTO_TIME 的值:
每个 Q Apply 程序都新增了 IBMQREP_MCGMON 表。该表以 MONITOR_INTERVAL 为周期,记录了 MCG 组协同的性能数据。该表由 MONITOR_TIME、RECVQ 列作为关键字,具体定义如表 3 所列。
表 3. IBMQREP_MCGMON 表
名称 | 位置 | 数据类型 | 取值范围 | 说明 |
---|---|---|---|---|
MONITOR_TIME | IBMQREP_MCGMON | TIMESTAMP | N/A | Q Apply 程序插入当前行的当前时间。 |
MCGNAME | IBMQREP_MCGMON | VARCHAR(64) | N/A | MCG 组名,唯一标识一个 MCG 组。 |
RECVQ | IBMQREP_MCGMON | VARCHAR(48) | N/A | 指的是该一致性组使用的接收队列 RECVQ,与 IBMQREP_RECVQUEUES 中的 RECVQ 一致。 |
MAX_CMT_SEQ_READ | IBMQREP_MCGMON | VARCHAR(10) FOR BIT DATA | N/A | 与 ASN.IBMQREP_MCGSYNC 中的 MAX_CMT_SEQ_READ 一致。 |
MAX_CMT_TIME_READ | IBMQREP_MCGMON | TIMESTAMP | N/A | ASN.IBMQREP_MCGSYNC 中的 MAX_CMT_TIME_READ 一致。 |
NUM_ACTIVE_CGS | IBMQREP_MCGMON | SMALLINT | N/A | 指的是该一致性组所在的 MCG 组中活动的一致性组的数目。即对于同一个 MCGNAME,ASN.IBMQREP_MCGSYNC 中 STATE 为 A 的 CG 数目。 |
LOWEST_MCG_MAX_CMT_SEQ_READ | IBMQREP_MCGMON | VARCHAR(16) FOR BIT DATA | 即同一个 MCG 组中 MAX_CMT_SEQ_READ 的最小值。 | |
LOWEST_MCG_OLDEST_TRANS | IBMQREP_MCGMON | TIMESTAMP | N/A | 即同一个 MCG 组中 OLDEST_TRANS 的最小值。 |
NEXT_APPLYUPTO_TIME | IBMQREP_MCGMON | TIMESTAMP | N/A | 与 ASN.IBMQREP_MCGSYNC 中的 NEXT_APPLYUPTO_TIME 一致。 |
NUM_TRANS_MCG_DELAY | IBMQREP_MCGMON | INTEGER | N/A | 代表 Q Apply 程序内存中,针对该一致性组,由于与别的一致性协同导致的还未被应用的事务数。 |
CURRENT_NUM_TRANS | IBMQREP_MCGMON | INTEGER | N/A | 代表 Q Apply 程序内存中,针对该一致性组的事务数。 |
CURRENT_NUM_MSGS | IBMQREP_MCGMON | INTEGER | N/A | 代表 Q Apply 程序内存中,针对该一致性组的消息数。 |
MCG_REFRESH_TIME | IBMQREP_MCGMON | TIMESTAMP | N/A | 代表 ASN.IBMQREP_MCGSYNC 表最后被更新的本地时间。 |
IS_MOST_BEHIND | IBMQREP_MCGMON | CHAR(1) | [Y,N] | Y 代表该一致性组是整个 MCG 组中最慢的。 |
IBMQREP_MCGMON |
在源端控制表 IBMQREP_SENDQUEUES 表和目标端控制表 IBMQREP_RECVQUEUES 表中,为了标识 MCG 组,都新增了一列 MCGNAME。它用于定义该队列映射所属的 MCG 组。该列的具体定义如表 3。
表 4. MCGNAME 列
名称 | 位置 | 数据类型 | 取值范围 | 说明 |
---|---|---|---|---|
MCGNAME | IBMQREP_SENDQUEUES,IBMQREP_RECVQUEUES | VARCHAR(64) | N/A | MCG 组名,唯一标识一个 MCG 组。 |
为了配置 MCG Sync 功能时,ASNCLP 新增了 CREATE MULTIPLE CONSISTENCY GROUP 和 ALTER MULTIPLE CONSISTENCY GROUP 来创建、修改 MCG 组,同时又修改了已有的 CREATE REPLQMAP 命令和 ALTER REPLQMAP 命令用于定义队列映射是否加入或退出 MCG 组。有关 MCG 组管理具体的语法,读者可参考清单 1。有关队列映射加入或退出 MCG 组的语法,读者可以参考清单 2。
清单 1. CREATE/ALTER MULTIPLE CONSISTENCY GROUP
>>-CREATE--+-MULTIPLE CONSISTENCY GROUP-+--NAME--groupname------> '-MCG------------------------' >--+-------------------------+--+---------------------------+-->< '-SYNCHINTERVAL--interval-' | .-UNBRIDLED--. | '-SYNCHMODE--+-IN STEP--n-+-' >>-ALTER--+- MULTIPLE CONSISTENCY GROUP-+--NAME--groupname------> '-MCG-------------------------' >--+-------------------------+--+---------------------------+-->< '-SYNCHINTERVAL--interval-' | .-UNBRIDLED--. | '-SYNCHMODE--+-IN STEP--n-+-'
清单 2. CREATE/ALTER REPLQMAP
>>-CREATE REPLQMAP--qmapname--+------------------------------+-> '-DESC-"description"-' >--+-----------------------------------------------+----------->< '-(--NODE--x--,--NODE--y--)-' >--+-----------------------------------------------+----------->< '-USING--| queue-map-options |--| mcg-options |-' queue-map-options |--| queue-options |--| other-options |-------------------------| queue-options .-MQDEFAULTS--------------------------------. |--+-------------------------------------------------------------+--> '-ADMINQ--"admnqname"--RECVQ--"recvqname"--SENDQ--"sendqname"-' >--+----------------------+-------------------------------------| '-| multiplex-option |-' multiplex-option |--PARALLEL SENDQS--number--------------------------------------| other-options |--+--------------------------+---------------------------------> '-NUM APPLY AGENTS--number-' >--+----------------------------+--+---------------------+------> '-MAXAGENTS CORRELID--number-' '-MEMORY LIMIT--limit-' >--+---------------------+--+------------------------------+----> '-ERROR ACTION--+-S-+-' '-HEARTBEAT INTERVAL--interval-' '-Q-' >--+------------------------+--+-------------------------+------| '-MAX MESSAGE SIZE--size-' '-MRI MEMORY LIMIT--limit-' mcg-options |--+-----------------------+------------------------------------| '-ADD TO MCG--groupname-' >>-ALTER REPLQMAP--qmapname-------------------------------------> >--| queue-map-options |--| mcg-options |---------------------->< queue-map-options |--USING--| options |-------------------------------------------| options |--+-------------------+--+-------------------+-----------------> '-DESC--description-' '-ADMINQ--admnqname-' >--+------------------+--+------------------+-------------------> '-RECVQ--recvqname-' '-SENDQ--sendqname-' >--+-------------------------+--+--------------------------+----> '-PARALLEL SENDQS--number-' '-NUM APPLY AGENTS--number-' >--+----------------------------+--+---------------------+------> '-MAXAGENTS CORRELID--number-' '-MEMORY LIMIT--limit-' >--+---------------------+--+------------------------------+----> '-ERROR ACTION--+-S-+-' '-HEARTBEAT INTERVAL--interval-' '-Q-' >--+------------------------+--+-------------------------+------| '-MAX MESSAGE SIZE--size-' '-MRI MEMORY LIMIT--limit-' mcg-options |--+-----------------+--groupname-------------------------------| +-ADD TO MCG------+ '-REMOVE FROM MCG-'
为了方便用户将一致性组加入或退出 MCG Sync,新增了两个 Q Apply 端的操作 MCGSYNCON 和 MCGSYNCOFF 命令。用法与 STARTQ/STOPQ 类似,其参数值可为队列映射名 QMAP 或接受队列 RECVQ 名。当 Q Apply 程序接收到 MCGSYNCON 命令时,会将 ASN.IBMQREP_MCGSYNC 表中相应的一致性组的状态置为 A,这样该一致性组的协同开关就打开了。反之,MCGSYNCOFF 将使改一致性组退出协同状态,独立运行。具体语法如清单 3 所示。
清单 3. MCGSYNCON/MCGSYNCOFF
对于 LUW 平台: asnqacmd apply_server=xxxx MCGSYNCON/MCGSYNCOFF=<QMAPNAME>|<RECVQNAME> 对于 z/OS 平台: f xxxx,MCGSYNCON/MCGSYNCOFF=<QMAPNAME>|<RECVQNAME>
本节将通过配置图 1 所示的一个部署在源数据库 SRCDB 和目标数据库 TRGDB 之间的 Q 复制的例子来向读者展现如何使用 Q 复制的 MCG Sync 功能。其中,在源端存在两个 Q Capture 程序,模式名分别为 Green 和 Yellow,而在目标端也存在两个 Q Apply 程序,模式名分别为 Green 和 Yellow。在这两对 Q Capture 程序和 Q Apply 程序之间,我们将定义四个队列映射 CG1、CG2、CG3 和 CG4,这四个队列映射将作为 MCG 组 MCG1 的成员,相互协同工作。本例中将略去 MQ 对象的创建,重点介绍 MCG 组的创建和 MCG 操作命令的使用等。
图 1. Q 复制 MCG Sync 功能的简单实例
这里略去源端和目标端数据库的创建,及表的创建以及 QSUB 的创建。清单 4 列出了创建 MCG 组 MCG1 和队列映射 CG1、CG2、CG3、CG4 的 ASNCLP 命令。
清单 4. ASNCLP 脚本创建 MCG 和 QMAP
ASNCLP SESSION SET TO Q REPLICATION; SET RUN SCRIPT NOW STOP ON SQL ERROR ON; SET SERVER CAPTURE TO DBALIAS SRCDB ID xxxx PASSWORD "xxxx"; SET SERVER TARGET TO DBALIAS TRGDB ID xxxx PASSWORD "xxxx"; CREATE MCG NAME MCG1 SYNCHINTERVAL 2000; SET CAPTURE SCHEMA SOURCE GREEN; SET APPLY SCHEMA GREEN; CREATE REPLQMAP CG1 USING ADMINQ“ADMINQ” RECVQ“DATAQ1” SENDQ“DATAQ1” ADD TO MCG MCG1; CREATE REPLQMAP CG2 USING ADMINQ“ADMINQ” RECVQ“DATAQ2” SENDQ“DATAQ2” ADD TO MCG MCG1; SET CAPTURE SCHEMA SOURCE GREEN; SET APPLY SCHEMA YELLOW; CREATE REPLQMAP CG3 USING ADMINQ“ADMINQ” RECVQ“DATAQ3” SENDQ“DATAQ3” ADD TO MCG MCG1; SET CAPTURE SCHEMA SOURCE YELLOW; SET APPLY SCHEMA YELLOW; CREATE REPLQMAP CG4 USING ADMINQ“ADMINQ” RECVQ“DATAQ4” SENDQ“DATAQ4” ADD TO MCG MCG1; QUIT;
通过查询源端的控制表 IBMQREP_SENDQUEUES 及目标端的控制表 IBMQREP_RECVQUEUES,ASN.IBMQREP_MCGPARMS,ASN.IBMQREP_MCGSYNC 可以验证 MCG Sync 配置是否完整。
清单 5. 验证 MCG Sync 的配置
db2 => select substr(pubqmapname,1,6) as pubqmapname,substr(sendq,1,6) as sendq, substr(recvq,1,6) as recvq,mcgname from green.ibmqrep_sendqueues PUBQMAPNAME SENDQ RECVQ MCGNAME ----------- ------ ------ ------------------------------------------------------ CG1 DATAQ1 DATAQ1 MCG1 CG2 DATAQ2 DATAQ2 MCG1 CG3 DATAQ3 DATAQ3 MCG1 3 record(s) selected. db2 => select substr(pubqmapname,1,6) as pubqmapname,substr(sendq,1,6) as sendq, substr(recvq,1,6) as recvq,mcgname from yellow.ibmqrep_sendqueues PUBQMAPNAME SENDQ RECVQ MCGNAME ----------- ------ ------ ------------------------------------------------------ CG4 DATAQ4 DATAQ4 MCG1 1 record(s) selected. db2 => select substr(repqmapname,1,6) as repqmapname,substr(sendq,1,6) as sendq, substr(recvq,1,6) as recvq,mcgname from green.ibmqrep_recvqueues REPQMAPNAME SENDQ RECVQ MCGNAME ----------- ------ ------ ------------------------------------------------------ CG1 DATAQ1 DATAQ1 MCG1 CG2 DATAQ2 DATAQ2 MCG1 2 record(s) selected. db2 => select substr(repqmapname,1,6) as repqmapname,substr(sendq,1,6) as sendq, substr(recvq,1,6) as recvq,mcgname from yellow.ibmqrep_recvqueues REPQMAPNAME SENDQ RECVQ MCGNAME ----------- ------ ------ ------------------------------------------------------ CG3 DATAQ3 DATAQ3 MCG1 CG4 DATAQ4 DATAQ4 MCG1 2 record(s) selected. db2 => select * from asn.ibmqrep_mcgparms MCGNAME MCGSYNCINT MCGSYNCSTEP -------------------------------------------------------- ----------- ----------- MCG1 2000 0 1 record(s) selected. db2 => select * from asn.ibmqrep_mcgsync MCGNAME REPQMAPNAME APPLY_SCHEMA UPDATE_TIME MAX_CMT_SEQ_READ MAX_CMT_TIME_READ ---------------------------------------------------------------- --------------- OLDEST_TRANS STATE STATE_CHANGE_TIME NUM_TRANS NUM_MSGS NEXT_APPLYUPTO_TIME ------------------------------------------------- ------------------------------ MCG1 CG1 GREEN 2015-09-17-22.17.45.101619 x'00000000000000000000000000000000' 0 0 N - 0 0 0 MCG1 CG2 GREEN 2015-09-17-22.17.45.101619 x'00000000000000000000000000000000' 0 0 N - 0 0 0 MCG1 CG3 YELLOW 2015-09-17-22.17.45.100859 x'00000000000000000000000000000000' 0 0 N - 0 0 0 MCG1 CG4 YELLOW 2015-09-17-22.17.45.100859 x'00000000000000000000000000000000' 0 0 N - 0 0 0 4 record(s) selected.
启动 Q Capture 程序和 Q Apply 程序与平时并无不同。Q Apply 程序在启动时会验证 ASN.IBMQREP_MCGSYNC 表里的配置是否与 IBMQREP_RECVQUEUES 表里的配置一致,以及 ASN.IBMQREP_MCGPARMS 表是否设置完整。当 Q Apply 程序检查到 ASN.IBMQREP_MCGSYNC 的 STATE 为 N 时,会自动激活该一致性组的协同状态。在源端提交一些事务后,就可以看到 ASN.IBMQREP_MCGSYNC 表有相应的变化。清单 6 列出了一个快照供读者参考。
清单 6. ASN.IBMQREP_MCGSYNC 表
db2 => select * from asn.ibmqrep_mcgsync MCGNAME REPQMAPNAME APPLY_SCHEMA UPDATE_TIME MAX_CMT_SEQ_READ ---------------------------------------------------------------- --------------- MAX_CMT_TIME_READ OLDEST_TRANS STATE STATE_CHANGE_TIME NUM_TRANS NUM_MSGS ---------------------------------------------------------------- --------------- NEXT_APPLYUPTO_TIME ---------------------------------------------------------------- --------------- MCG1 CG1 GREEN 2015-10-15-03.12.30.205770 x'0000000004DA4A9B00000000A80F2E0D' 1443601084000010 1443598960000039 A 2015-09-17-23.47.45.194221 15616 15619 1443600812000025 MCG1 CG2 GREEN 2015-10-15-03.12.30.229810 x'0000000004DA7DC200000000A813D541' 1443601186000032 1443598932000015 A 2015-09-17-23.47.45.201619 16646 16651 1443600812000025 MCG1 CG3 YELLOW 2015-10-15-03.12.30.193478 x'0000000004DA67A400000000A811CACC' 1443601140000033 1443598959000026 A 2015-09-17-23.47.47.200859 17131 17137 1443600812000025 MCG1 CG4 YELLOW 2015-10-15-03.12.30.193478 x'0000000004DA67A400000000A811CACC' 1443601140000033 1443598959000026 A 2015-09-17-23.47.47.200859 17131 17137 1443600812000025 4 record(s) selected.
如清单 7 所示,通过使用 MCGSYNCON 和 MCGSYNCOFF 命令,可以动态地将一个一致性组移出或加入一个 MCG 组。当 Q Apply 程序收到 MCGSYNCOFF 命令时,会将 ASN.IBMQREP_MCGSYNC 表相应的 STATE 置为 I,并不再更新该行值。但该一致性组的复制进程并未停止,只是它不在与其他一致性组协同。而当 Q Apply 程序收到 MCGSYNCON 命令时,会将 ASN.IBMQREP_MCGSYNC 表里的 STATE 置为 A,重启 browser 进程,及时更新表中相应的行。
清单 7. MCGSYNCOFF/MCGSYNCON CG1
asnqacmd apply_server=trgdb MCGSYNCOFF=CG1 asnqacmd apply_server=trgdb MCGSYNCON=DATAQ1
本文首先讨论了大型客户在部署 Q 复制过程中面临的分组的需求,进而讨论了 Q 复制技术如何不断地权衡扩展性和数据一致性,从而提出了创新性的 MCG Sync 功能。在介绍了 Q 复制 MCG Sync 功能的原理后,又详细介绍了 MCG Sync 功能的具体实现,用户可以通过这一节的内容了解到该功能带来的变化。最后通过一个实例向读者展示了如何配置和使用这一功能。对于拥有大数据中心的客户来说,相信这一功能可以极大地满足分组、failover 等数据持续可用的需求。