EXEC模块在处理事务时,首先要对事务数据进行收集归类,通过事务ID把同一个事务的操作都归到一起。EXEC模块在初始化时,根据exec_sql参数指示的内存池大小来初始化内存池,收集事务操作时,都将从该内存池中分配内存,当事务入库完后,释放事务时把占用的内存还给内存池。在内存池没有耗尽的情况下,最多允许缓存事务的个数由exec_trx参数来控制,当达到该参数上限时,需要等前面已经提交的事务入库完成以后才会接收新的事务数据。
某些情况下,源端可能会产生超大的事务,当EXEC模块事务内存池不够使用时,先前在内存池中缓存的操作数据将会被刷到本地磁盘的TSK目录下,释放出内存用来缓存后续的操作,这个过程对同步的性能会产生比较大的影响,应该根据实际情况合理的配置exec_sql参数,尽可能的减少事务被缓存到磁盘的操作。
(1)exec_sql
含义:EXEC模块缓存事务SQL语句的内存大小,取值范围在32-40960,单位M,默认值512。
说明:EXEC模块从NET接收模块中获取到CPT模块发送过来的消息以后,按事务ID对这些消息进行归类,缓存到本机内存中。如果是提交的事务,则交给工作线程进行入库处理,而没有提交的事务则一直会在内存中缓存。当缓存的内存总数达到该参数的设定值时,EXEC模块会对没有提交的事务存盘,以便释放内存空间来接收新的消息。存盘操作就涉及到大量的IO,从而影响同步的性能,所以需要合理的配置该参数,以适应当前的同步环境。
一般大内存服务器可配置2048到4096不等,不建议再配置更大的值。
(2)exec_trx
含义:允许缓存事务的个数,取值范围在1000-10000,默认值5000。
说明:EXEC模块缓存事务个数的最大限制,当超过这个限制值时将不再接收消息,需要等现有的事务入库完毕后,事务个数降到限定值以下时才会重新开始接收。当停止消息接收时,整个同步链路会处在阻塞状态,通过查看统计信息可以获取到这一状态。
一般建议保持默认值即可
(3)vpools
含义:缓存事务使用内存池的个数,取值范围在1-255,默认值为7。
说明:该参数exec_sql配置的内存大小平均划分该参数指定的份数,事务缓存时,根据事务编号映射到具体的内存池上,这样在缓存和释放时可以减小对内存池的访问冲突。
建议保持默认值
数据库的事务提交相对事务中的修改操作来说需要花费更多的时间,事务在提交时,数据库需要等待前面操作产生的日志刷盘以后才能返回其结果,确保事务的一致性(ACID)。基于上面的原理,执行线程在入库事务数据时,应尽可能的减少对数据库的提交操作,把源端日志中多个小事务合并成一个大事务后再执行,一次提交多个事务,这种特性称之为事务合并,它由EXEC模块的enable_merge参数来控制。当该参数配置为1时,表示开启事务合并,0表示禁用事务合并。
由于事务执行时,事务之间可能会存在执行顺序上的依赖关系,执行线程把多合事务合并在一起执行,可能会造成执行线程相互冲突,从而影响到执行线程之间的并行度,反而会降低入库的性能,所以该参数需要结合实际的同步情况来配置。在开启了事务合并参数后,虽然多个事务只提交一次,但是合并的事务的信息还是需要登记到辅助表,在登记到辅助表时会采用参数批量绑定的方式入库,如果小事务很多,则会批量入库多行,会影响到同步的效率,这时可以配置commit_compress参数来启用提交压缩功能,将这些入库的事务信息,把多行压缩为一行或几行,提升入库效率。
为了保证事务的完整性,EXEC模块在入库事务时默认的情况下不会拆分事务,造成执行线程之间会出现执行顺序上的依赖关系。当同步环境对事务的完整性没有严格要求时,便可以启用事务分裂功能(trx_split参数配置为1),把一个事务按表拆分成N个小事务。执行线程在入库时,会收集相同表操作的小事务并合并成大事务后再执行,这样不同执行线程之间操作的表互不影响,可以有效的提升执行线程入库的并行度,达到提升同步性能的目的。只是在这种同步模式下,目标端数据库中的数据在单个时间节点上和源端数据表的数据分布是不同的,待所有事务同步完成以后,两边数据库的数据最终会保持一致。
注意:在启用事务分裂功能时,应该禁用目标端数据库同步表上的主外键关系,防止因入库先后顺序发生变化导致的错误。
(1)enable_merge
含义:是否启用事务合并功能,可选0(禁用)/1(启用),默认值1。
说明:在同步事务时,事务的提交相对来说是非常缓慢的,为了减少事务提交的次数。当启用该项功能时,工作线程在执行事务会一次性执行多个事务,然后一次提交让这些事务都生效,从而达到提升性能的目的。该参数在单个工作线程模式或commit_policy配置为1时建议开启,其它情况下请结合当前应用事务的特性来选择性的开启。
建议保持默认值
(2)trx_split
含义:是否启用事务分裂功能,可选0(禁用)或1(启用),默认值0。
说明:EXEC模块在收到事务提交消息时,有两种方式把该事务交给工作线程,一种是保证事务完整性的把事务整体交付,另一种则是把事务中的操作按每个操作针对的表进行拆分,拆分成N个事务,拆分后的事务中,每个事务包含某张表在原始事务中的所有操作,然后把这些事务依次交给工作线程进行入库。事务被拆分以后,事务中同一张表的操作入库顺序跟原始的事务保持一致,表与表之间则是无序的。这种方式在同步异常中止时无法保持事务的一致性。但由于事务拆分以后每个事务中的操作仅针对同一张表,在某些情况下可以提高入库操作批量的行数,从而提升同步性能。
建议开启
执行线程在把事务操作入库时,会有很多种原因导致事务入库失败。在这种入库失败的情况发生时,EXEC模块提供exec_policy参数来配置三种策略决定它下一步的动作。
(1)exec_policy
含义:事务入库出错时的执行策略,可选0、1或2,默认为1。
说明:事务在通过接口入库时,可能会产生错误,该参数指明了当入库发生错误时,EXEC模块采取何种策略。对于该参数值的解释如下:
0:忽略出错的事务后继续执行,该策略是丢弃掉整个出错的事务。
1:中断执行,该策略是如果入库发生错误,便终止同步进程,等待人工修复错误。
2:忽略出错的操作后继续执行,出错事务中的其它操作会继续进行入库,该参数和0的区别在于,0会保证事务的完整性,而它不保证,实现尽可能同步数据。
1)当配置为0时,出错时丢弃掉该事务后继续执行,需要注意的是,在开启了事务分裂功能的情况下,只丢弃出错事务中和出错表相同表的其它操作,属于该事务其它表的操作会由其它执行线程继续入库。
2)当配置为1时,出错后EXEC模块会主动终止DMHS进程,防止错误进一步扩散,这种情况下需要人工干预,定位出错的原因并修复以后方可重新启动DMHS进程继续同步。
3)当配置为2时,出错后EXEC模块只会丢弃当前出错的操作,该事务先前已经入库的操作会被保留,然后继续入库该事务后续的操作。
比较上述三种策略:
策略1)可以保证源端事务的完整性,但是会放大后续同步错误发生的可能;
策略2)则可以保证同步事务的完整性,但如果同步时经常出错则需要频繁的人工干预,维护成本高;
策略3)虽然不能保证事务的完整性,但是可以防止错误被进一步放大。
注意:当DMHS配置文件中不配置exec_policy参数时,DMHS服务器会默认设置exec_policy值为1。
推荐使用默认设置,能够最大程度保障数据一致性。
执行线程在并行对事务进行入库时,EXEC模块提供commit_policy参数用来配置提交策略,控制执行线程之间事务执行的并行度。EXEC模块提供四种提交策略,分别是:
1)配置为0:严格按照事务提交的顺序来提交事务。执行线程之间事务执行时数据入库是并行的,但是事务提交时则需要等待在它之前已经得交的事务先提交后才能提交。这种策略可以保证目标端的事务入库的提交顺序和源端是完全一致的,但是并不保证事务之间操作的顺序和源端一致。
2)配置为1:不相关的表并行提交,相关的表串行执行。执行线程之间在入库时需要判断其它执行线程是否存在和自己的事务有相互冲突的表,如果存在,则需要等待提交事务顺序在前面的执行线程先完成后再执行;如果没有则直接入库。这种策略可以有效的提升执行线程的并行度,但是会造成后提交的事务在目标库中先入库。
3)配置为2:不相关的表并行提交,相关的表按事务的提交顺序提交。这种提交策略是0和1的组合,可以最大限度的提升入库的并行度。
4)配置为3:提交策略按配置为0的方式执行,但是在事务操作入库时,事务操作先按表归类,实现相同的操作批量入库,某些场景下有助于提升性能。
执行线程为了防止入库冲突,每个事务入库之前都会对操作事务中涉及的表构造表锁来和其它执行线程互斥,但表锁的粒度相对来说较大,为了提升执行线程的并行度,EXEC模块还提供了lock_rows参数来启用行锁的功能。在启用行锁后,执行线程会把构造表锁改为构造行锁,执行线程之间相同表但是操作行不相同的事务在这种模式下就可以并行。
事务的提交在入库时往往是瓶颈所在,执行线程在等待其它事务提交时耗时较多,EXEC模块还提供了commit_prepare参数来缓解该问题。当开启该参数后,EXEC模块会自动开启lock_rows参数,执行线程在入库时,会检查其它有冲突的执行线程是否已经完成了入库,但是不会等待确认该执行线程是否已经在数据库中完成提交,这种情况下进行数据入库,数据冲突上锁的任务交由数据库来完成。
注意:当DMHS配置文件中不配置commit_policy参数时,DMHS服务器会默认设置commit_policy值为1。在对事务提交顺序没有严格要求的情况下,推荐使用默认设置,能够提高执行效率。
(1)commit_policy
含义:事务入库的事务提交策略,可选0、1、2,默认为1。
说明:数据入库按事务为单位,该参数还需要结合commit_prepare参数共同指明事务提交时的顺序策略,不同的策略对入库性的影响有着非常明显的区别。具体的参数解释如下:
1)0:严格按照接收到事务提交先后顺序来提交,多个事务并行入库时,事务之间单个操作并不遵守这个约定,但提交操作会遵守先后顺序。
2)1:多个事务并行入库时,如果事务之间有关联的表,那么这些事务称为关联事务,配置该参数时,关联事务会按各事务提交的先后顺序串行执行,非关联的事务则并行执行,并行执行的事务提交时,并不受事务提交先后顺序的限制,有可能后提交的事务先提交。
3)2:多个事务并行入库时,有关联的事务按配置0的约定方式执行,无关联的事务则并行执行
4)3:提交策略按配置为0的方式执行。事务操作入库时,事务操作先按表归类,实现相同的操作批量入库。
建议保持默认
(2)commit_prepare
含义:是否启用提交准备功能,可选0(禁用)/1(启用),默认值为0
说明:由于事务提交是一个非常缓慢的操作,为了保证提交顺序,EXEC模块往往会
花费大量的时间在等待事务提交上,该参数就是为了减少事务提交等待而进行的优化。启用该功能以后,事务在提交前会标识本事务的操作已经入库完成,在提交之前先唤醒其它等待它提交的事务,被唤醒的事务会检查它与唤醒它的事务有没有数据冲突,如果没有,则马上投入执行,否则继续挂起,直到唤醒它的事务完成提交后再执行。如果该参数为0,则会在完成事务提交以后才会唤醒等待它提交的事务。
不建议开启,保持默认关闭
(3)lock_rows
含义:事务入库时单个事务允许构造行锁的个数,取值范围在0-1000000,默认值为0。
说明:工作线程在对事务进行并行入库时,事务间可能存在数据冲突,需要通过对冲突的表或行来上锁达到互斥。该参数主要用在以下场景:
1)当commit_policy配置为0或2时,并开启了commit_prepare功能;
2)当commit_policy配置为1时。
建议保持默认
执行线程主要负责事务数据的入库,它可以配置一个或多个,由exec_thr参数决定,在采用多对一的架构时,执行线程为多个源端共用,这种情况下应适当多配,防止执行线程不足产生任务堆积。
每个执行线程都会和目标端数据库建立一个持久的数据连接来进行交互,在配置多个执行线程的情况下,数据库的连接数也会相应的增加,这需要结合数据库实际的情况来合理配置,避免连接数过多而影响了数据库对其它应用提供服务。每个执行线程在对事务数据入库时,并不是完全独立的并行运行,而是遵守提交策略制定的规则把事务有序的入库,当入库的表还存在主外键的依赖关系,为了防止入库顺序的错位引起约束报错,执行线程之间更需要频繁的交互,影响入库的性能。
单个执行线程对事务数据采用参数批量绑定的方式进行入库,每次绑定的行数除了受事务本身操作数的影响以外,还受exec_rows参数配置限制。该参数限定了每次批量绑定的行数,事务中INSERT、DELETE或UPDATE都是大批量的操作时,适当放大该参数有利于同步性能的提升,但副作用是会加剧EXEC模块对内存的消耗,应该结合实际的同步环境合理的配置该参数。
1.执行线程配置为1时,在多对一的同步环境中,EXEC模块会为每个源端创建一个独立的执行线程,这些执行线程负责各自的源端事务数据的入库,不会被其它源端共用。
2.目标端为DM数据库时,可以在源端SEND配置中禁用外键约束,这样可以防止EXEC模块加载表之间的引用关系,从而减少执行线程之间的引用冲突,提高执行线程之间的并行度,使入库性能达到最优。
(1)exec_thr
含义:EXEC模块用来数据入库的工作线程数,取值范围在1-1024,默认值为4。
说明:数据入库是由工作线程来完成的,每个工作线程对应一个事务,单个工作线程时,事务按提交顺序先后入库,如果配置了多个工作线程,那么需要按照提交策略来决定事务之间如何并行入库。
低配服务器视情况调整或保持默认,高配服务配置一般不超过64
(2)exec_rows
含义:数据入库时允许的最大批量行数,取值范围在1-2000,默认值1000。
说明:工作线程在对事务进行入库时,采取的是参数批量绑定的方式,这个参数指定了批量的最大行数,该参数对性能会有一定影响。取值小时,可以减少EXEC模块对内存的占用,但是会降低入库性能;取值大时虽然有助于提升入库性能,但是会加剧EXEC模块对内存的消耗。
低配服务器可保持默认,高配服务可调整为2000
EXEC模块在同步事务时,会不断的在DMHS_TRXID_TABLE表中登记已经入库完成的事务信息,为了清理这个表,EXEC模块需要像数据库一样定期的设置一个保存点来保存当前同步的进度,这就是检查点的功能。
检查点由MGR的调度模块发起,需要在base节点下使用参数ckpt_interval来控制检查点的执行频率。过高的频率会影响同步的性能,太低则会影响DMHS故障重启时恢复同步的速度,可以根据DMHS同步运行的稳定性调整到一个合理的值。
如果源端数据库存在长事务或大事务,则会影响到检查点,在这种情况下,EXEC模块的事务缓存区会长时间存在一个事务得不到提交,导致检查点的LSN无法向前推进,如果长时间维持这种情况,DMHS_TRXID_TABLE表的数据量将来持续的增加,源端归档文件也得不到及时的清理,就会造成很多的风险。一是源端归档磁盘空间不足;二是执行端辅助表占用大量的磁盘空间;三是在这种情况下DMHS如果发生故障重启,那么恢复的速度就会变得相当的缓慢。为了解决上述风险,EXEC模块提供了持久性事务和范围检查功能,请结合实际的情况来启用上述两个功能。
持久性事务指的是当检查点推进时发现被某个事务阻塞,EXEC模块则会把该事务缓存到本地TSK目录下,然后把该事务的起始LSN推进到触发检查点事务的LSN,这样检查点就可以继续推进,故障时EXEC模块初始化时会把TSK目录下缓存的事务重新加载进来,确保事务不被丢失。持义性事务的控制参数是save_point_times,该参数配置值的是事务阻塞检查的次数,当达到指定次数后,该事务会被缓存到TSK目录。
范围检查点则是专门针对DMHS_TRXID_TABLE的清理做的优化,当检查点被某个事务阻塞时,那么它将改做范围检查点,基于EXEC模块缓存的事务相邻的LSN区间值来清理该表,然后重新登记一个区间值。该功能可以有效的减少该表的数据规模,在故障重启时可以加快EXEC模块初始化的速度,但是它无助于源端归档文件的清理,在阻塞的事务不提交的情况下,归档依然会堆积。范围检查点的启动参数是enable_ckpt_range。
注意:当DMHS配置文件中不配置ckpt_interval参数时,DMHS服务器会默认设置ckpt_interval值为60。
(1)ckpt_interval
含义:检查点间隔,取值范围在10~65535,默认值60
说明:当同步服务中存在EXEC模块时,该参数表示EXEC模块检查点刷新的时间间隔,单位为秒。
建议保持默认值
(2)save_point_times
含义:事务允许阻塞检查点的次数,取值范围在0+,默认禁用该功能。
说明:EXEC模块需要定时的刷新检查点,以便清除已经过期的事务信息,当某个事务一直不提交时,那LSN比它大的事务信息就无法及时的清除,也会导致源端CPT无法及时的清理归档。指定了该参数以后,当某个事务阻塞检查点的次数达到该配置的值时,该事务就会被当作持久性事务缓存到本地磁盘上,它的LSN也会被推进到当前检查点的LSN,以便检查点能够正常的刷新。
建议保持默认禁用状态
(3)enable_ckpt_range
含义:是否需要启用范围检查点,可选项0/1,默认值0。
说明:范围检查点功能可以有效的缩减辅助表dmhs_trxid_table的数据规模,在同步异常恢复时可以加快恢复的速度,但是会轻微影响EXEC模块刷检查点的速度。
建议保持默认值