【发明内容】
本发明要解决的技术问题是在搭建主备同步的环境中,目的端数据库往往是用作查询库来分担主库的压力,表在添加列时,长时间的同步延时将影响到应用的查询功能,如何缩短大表修改操作同步延时并且减少同步对目的端数据库上应用程序的影响就成为业界亟待解决的技术问题。
本发明进一步要解决的问题是例如采用系统时间作为添加列情况下,可能发生的直接通过表达式生成目的端数据库添加表默认值方式,会产生目的端数据库添加列中插入数据与源端数据库添加列不一致的问题。
本发明采用如下技术方案:
第一方面,本发明提供了一种基于日志解析的数据库添加列同步方法,包括:
源端数据库的同步系统判断日志中待同步的操作为DDL事务,则根据该事务号收集后续属于所述DDL事务的日志;
当收集到上述DDL事务相关的用户表INSERT操作日志时,则判断DDL事务中否为添加列的操作,如果是,则提取INSERT操作中新列的值构造出默认值常量表达式为EXP_NEW;
使用默认值常量表达式EXP_NEW作为目的端数据库中添加列的定义表达式,然后把添加列操作发送到目标端同步服务执行;
源端数据库同步系统继续捕获日志,直到捕获到所述DDL事务的提交日志;则根据前面收集的系统表操作日志还原出原始的添加列操作,并提取出源端数据库中添加列的定义表达式为EXP_OLD;
当捕获该添加列的提交日志时,判断目的端的定义表达式EXP_NEW和源端数据库中添加列的定义表达式EXP_OLD是否等价,如果等价则完成该事务同步,否则,使用表达式EXP_OLD构造一个修改列默认值的操作发送到目标库执行,完成该事务同步。
优选的,所述源端数据库的同步系统判断日志中待同步的操作为DDL事务,则根据该事务号收集后续属于所述DDL事务的日志,还包括:
当首先收集到对应所述DDL事务的日志内容不是用户表INSERT操作,而是提交日志时,判断DDL事务为添加列的操作,则使用EXP_OLD表达式作为默认值向目的端同步系统发送添加列操作。
优选的,目的端数据库的同步系统在接收到源端数据库的同步系统的添加列操作后,直接在目的端数据库上对该表执行添加列操作,完成所述DDL事务同步。
优选的,目的端数据库在所述DDL前,若接收到查询请求,所述方法还包括:
所述目的端数据库的原表被锁定,从而处于不可被访问状态;其中,在完成所述DDL事物同步后,通过所述替换原表的新建表完成所述查询请求。
优选的,所述源端数据库同步系统继续捕获日志,还包括:
当捕获到该添加列的回滚日志时,由于目标端已经执行了添加列的操作,所以要构造删除列的操作发送到目标端执行,完成该事务同步。
优选的,所述当收集到对应所述DDL事务的日志内容为用户表INSERT操作时,判断DDL事务是否为添加列的操作,具体包括:
针对DDL事务,源端数据库会生成系统表的日志和对应普通表的日志;
在收集完系统表的日志以后,通过系统表日志反推所述DDL事务所属操作;
其中,收集完系统表的日志的条件是:产生DDL事务的提交或回滚消息,和/或,对应所述DDL事务的普通表的日志产生。
优选的,所述数据库包括Oracle和/或达梦数据库。
优选的,在所述方法中在源端数据库及目的端数据库部署同步系统,源端数据库同步系统从源端数据库读取日志,而目标端数据库同步系统则是负责把源端发过来的同步操作应用到目的端数据库。
第二方面,本发明还提供了一种基于日志解析的数据库添加列同步装置,用于实现第一方面所述的基于日志解析的数据库添加列同步方法,所述装置包括:
至少一个处理器;以及,与所述至少一个处理器通信连接的存储器;其中,所述存储器存储有可被所述至少一个处理器执行的指令,所述指令被所述处理器执行,用于执行第一方面所述的基于日志解析的数据库添加列同步方法。
第三方面,本发明还提供了一种非易失性计算机存储介质,所述计算机存储介质存储有计算机可执行指令,该计算机可执行指令被一个或多个处理器执行,用于完成第一方面所述的基于日志解析的数据库添加列同步方法。
本发明通过捕捉对应DDL事物的用户表操作日志,作为触发目的端进行添加列操作的依据,进一步的在捕获到事务的提交日志或者回滚日志,对添加列操作进行修正,从而基本上可以保证源和目的数据库几乎在同一时刻对表进行添加列的操作,,这样缩短了添加列操作同步造成的延时从而减轻了添加列操作同步对目的端应用的影响。
进一步的,本发明解决了特定情况下源端数据库中添加列的定义表达式EXP_OLD和实际生成的常量表达式EXP_NEW,在目的端数据库适用时候会产生不匹配的问题,并通过使用默认值常量表达式EXP_NEW作为目的端数据库中添加列的定义表达式,然后把添加列操作发送到目标端同步服务执行,保证了目的端数据库在执行添加列操作时候,添加列中的数据能够与源端数据库的添加列中数据内容一致,而通过最后校对来修改添加列的定义。
【具体实施方式】
为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。
在本发明的描述中,术语“内”、“外”、“纵向”、“横向”、“上”、“下”、“顶”、“底”等指示的方位或位置关系为基于附图所示的方位或位置关系,仅是为了便于描述本发明而不是要求本发明必须以特定的方位构造和操作,因此不应当理解为对本发明的限制。
此外,下面所描述的本发明各个实施方式中所涉及到的技术特征只要彼此之间未构成冲突就可以相互组合。
实施例1:
本发明实施例1提供了一种基于日志解析的数据库添加列同步方法,述数据库包括Oracle和/或达梦数据库中,本发明实施例在源端数据库及目的端数据库部署同步系统,源端数据库同步系统从源端数据库读取日志,而目标端数据库同步系统则是负责把源端发过来的同步操作应用到目的端数据库。如图1所示,包括:
在步骤201中,源端数据库的同步系统判断日志中待同步的操作为DDL事务,则根据该事务号收集后续属于所述DDL事务的日志。
针对DDL事务,源端数据库会生成系统表的日志和对应普通表的日志;而在本发明实施例的步骤201中主要指代的是搜集系统表的日志。
在步骤202中,当收集到对应所述DDL事务的日志内容为用户表INSERT操作时(当表处于修改状态时,例如本发明实施例中的添加列,该表在数据库内部是锁定的,其它事务不能对该表进行操作,只有当DDL完成后,该表才能被其它事务访问,而所述INSERT操作便为分界岭,在INSERT操作之前属于DDL操作),则判断DDL事务中否为添加列的操作,如果是,则提取INSERT操作中新列的值构造出默认值常量表达式为EXP_NEW。
在现有技术中,通常是在源端数据库完成了添加列操作之后,才会向目的端数据库发送现有的添加列操作,这也是背景技术中所分析的“该操作大约需要在源端数据库执行花费约60分钟,该操作同步到目的库也同样至少要花费60分钟才能完成,那么就会造成数据同步至少延迟60分钟”的原因。而在本发明实施例中,不同的是,一旦通过日志收集到是添加列操作(此时,对于源端来说也才刚开始添加列的操作过程),便通过进一步的步骤203使用默认值常量表达式EXP_NEW作为目的端数据库中添加列的定义表达式,然后把添加列操作发送到目标端同步服务执行,这里实际上是将背景技术中举例的延迟60分钟(来自源端数据库执行花费约60分钟)执行的操作,提前准备着完成。
本发明实施例的上述步骤改进的实际意义在于,具体应用中,一旦添加列操作在源端数据库被执行后,除了各别因为宕机、网络中断等原因外,99%以上概率都会被正常完成。因为有这样的稳定完成的客观因素在,从而实现上述的“当收集到上述DDL事务相关的用户表INSERT操作日志时,则判断DDL事务中否为添加列的操作,如果是,则提取INSERT操作中新列的值构造出默认值常量表达式为EXP_NEW”成为了一种有效的、可行的操作方式,从而成为最后能够取得“基本上可以保证源和目的数据库几乎在同一时刻对表进行添加列的操作”的根本所在。
在步骤203中,使用默认值常量表达式EXP_NEW作为目的端数据库中添加列的定义表达式,然后把添加列操作发送到目标端同步服务执行。
需要强调的是,步骤203的操作仍然会如现有技术一般,将目的端数据库中的原表进行锁定操作。但是,相比较现有技术中,是在收到提交日志的时候才出发目的端的同步服务执行而言,本发明实施例将相应的同步操作提前了至少一个阶段。
在步骤204中,源端数据库同步系统继续捕获日志,直到捕获到所述DDL事务的提交日志;则根据前面收集的系统表操作日志还原出原始的添加列操作,并提取出源端数据库中添加列的定义表达式为EXP_OLD。
在步骤205中,当捕获该添加列的提交日志时,判断目的端的定义表达式EXP_NEW和源端数据库中添加列的定义表达式EXP_OLD是否等价,如果等价则完成该事务同步,否则,使用表达式EXP_OLD构造一个修改列默认值的操作发送到目标库执行,完成该事务同步。
本发明实施例通过捕捉对应DDL事物的用户表操作日志,作为触发目的端进行表添加列操作的依据,进一步的在捕获到事务的提交日志或者回滚日志,才进行目的端数据库的添加列操作执行完成。进一步的,本发明解决了特定情况下源端数据库中添加列的定义表达式EXP_OLD和实际生成的常量表达式EXP_NEW,在目的端数据库适用时候会产生不匹配的问题,并通过使用默认值常量表达式EXP_NEW作为目的端数据库中添加列的定义表达式,然后把添加列操作发送到目标端同步服务执行,保证了目的端数据库在执行添加列操作时候,添加列中的数据能够与源端数据库的添加列中数据内容一致,而通过最后校对来修改添加列的定义。这是因为数据库中的添加列实现机制,其会根据添加列的定义去给添加列中个单元赋值,而若果源端数据库中添加列的定义公式是填充“系统时间”,那么如果仍然按照相应的定义进行目的端数据库的赋值,则会发生在目的端添加列中填充的数据和源端数据库不一致的情况。而本发明实施例所提出的方法步骤,则可以通过先将同步操作的第203步骤中的“使用默认值常量表达式EXP_NEW作为目的端数据库中添加列的定义表达式,然后把添加列操作发送到目标端同步服务执行”操作,保证目的端数据库在完成同步操作过程中不至于发生不一致问题,然后最后通过步骤205完成上述添加列中定义属性的校对和修改,从而完成整个添加列的同步操作。
如图2所示,在执行完步骤201中的所述源端数据库的同步系统判断日志中待同步的操作为DDL事务,则根据该事务号收集后续属于所述DDL事务的日志后,除了可能遇到上述步骤202中情况外,还可能遇到另一种情况,具体的:
在步骤206中,当首先收集到对应所述DDL事务的日志内容不是用户表INSERT操作,而是提交日志时,判断DDL事务为添加列的操作,则使用EXP_OLD表达式作为默认值向目的端同步系统发送添加列操作。此处,考虑到若首先收集到并非步骤202中的INSERT操作,而是上述步骤206中的提交日志,则可以认定此时需要被执行添加列操作的原表是一个空表,此时使用现有常规机制也不会存在背景技术中所描述的延时存在,因为空表的建立在现有数据库机制下也是很快能够完成的,而此时使用本发明实施例所提出的步骤203-205方法过程,就显得有些冗余;因此,在此情况下,可以直接利用两边同步系统之间的添加列操作指令进行同步。
进一步从目的端数据库来看,在接收到上述步骤206来自源端数据库的添加列操作,目的端数据库的同步系统在接收到源端数据库的同步系统的添加列操作后,直接在目的端数据库上对该表执行添加列操作,完成所述DDL事务同步。
在本发明实施例中,目的端数据库在完成所述DDL事务同步前,若接收到查询请求,所述方法还包括:
所述目的端数据库的原表被锁定,从而处于不可被访问状态;其中,在完成所述DDL事物同步后,通过所述替换原表的新建表完成所述查询请求。
如图3所示,所述源端数据库同步系统继续捕获日志,除了包括步骤205中所描述的提交日志外,还包括回滚日志的情况,具体的:
在步骤207中,当捕获到该添加列的回滚日志时,由于目标端已经执行了添加列的操作,所以要构造删除列的操作发送到目标端执行,完成该事务同步。
在本发明实施例中,所述当收集到对应所述DDL事务的日志内容为用户表INSERT操作时,判断DDL事务是否为添加列的操作,如图4所示,具体包括:
在步骤301中,针对DDL事务,源端数据库会生成系统表的日志,然后生成对应普通表的日志。
在步骤302中,在收集完系统表的日志以后,通过系统表日志反推所述DDL事务所属操作;例如在本发明实施例1中,通过用户表的INSERT操作日志反推出是添加列操作。这里的反推通常是通过例如实施例3所述的,通过对SYS.COL分析,来确定表中列的定义多了一列,从而确定是添加列操作。
其中,收集完系统表的日志的条件是:产生DDL事务的提交或回滚消息,和/或,对应所述DDL事务的普通表的日志产生。
实施例2:
本发明实施例从一个较为完整的方法步骤过程阐述本发明实施例1的实现过程,相比较实施例1而言,本发明实施例的过程表现更为完善、也更为实例化。在本发明实施例中,在源端数据库及目的端数据库部署同步系统,源端数据库同步系统从源端数据库读取日志,而目标端数据库同步系统则是负责把源端发过来的同步操作应用到目的端数据库,如图5所示,包括以下步骤:
401、在源端数据库及目的端数据库部署同步系统,源端数据库同步系统从源端数据库读取日志,而目标端数据库同步系统则是负责把源端发过来的同步操作应到目的端数据库。
402、源端数据库同步系统判断日志中的操作是否属于系统表操作,如果是则归类为DDL事务,获取该DDL操作的事务号,根据该事务号收集后续属于该事务的日志。
403、当收集到上述DDL事务的提交日志时,则使用传统的方式同步该添加列。
404、当收集到上述DDL事务相关的用户表INSERT操作日志时,则需要判断DDL事务中否为添加列的操作,如果是,则提取INSERT操作中新列的值构造出默认值常量表达式为EXP_NEW,然后根据前面收集的系统表操作日志还原出原始的添加列操作,并提取出原始的默认值表达式为EXP_OLD。
405、使用表达式EXP_NEW替换原始的默认值表达式EXP_OLD,然后把添加列操作发送到目标端同步服务执行。
406、源端数据库同步系统继续捕获日志,后续属于上述添加列事务的DML日志都可以直接丢弃,直到捕获到该事务的提交或是回滚日志。
407、当捕获到该添加列的回滚日志时,由于目标端已经执行了添加列的操作,所以要构造删除列的操作发送到目标端执行,完成该事务同步。
408、当捕获该添加列的提交日志时,判断默认值表达式EXP_NEW和EXP_OLD是否等价,如果等价则完成该事务同步,否则,使用表达式EXP_OLD构造一个修改列默认值的操作发送到目标库执行,完成该事务同步。
上述方案运行时,基本上可以保证源和目的数据库几乎在同一时刻对表进行添加列的操作,并且目的端在添加列时,采用的是保留原表创建新表的方式来进行,原表的查询操作不受添加列操作同步的影响,这样即缩短了添加列操作同步造成的延时又减轻了添加列操作同步对目的端应用的影响。
实施例3:
本发明实施例以源端数据库为ORACLE时,将上述实施例2的方法内容进一步展开实例化阐述如下:
源端数据库的所有对象信息,都存放在相关的系统字典表中(如SYS.OBJ$、SYS.COL$、SYS.ICOL$),以ORACLE为例,表的表定义存放在SYS.OBJ$系统表,列定义定放在SYS.COL$系统表。当ORACLE为表A添加一个带默认值的列C时,它会先在SYS.COL$系统表中插入一行列定义,同步服务就可以在日志中通过捕获SYS.COL$系统表的操作获取到C列的定义信息;数据库在构造完A表的字典以后,便会对表A中记录的数据进行构造,它需要把添加列的默认值写到每行记录中去,这个操作会在日志中产生大量针对表A的INSERT日志,同步服务捕获表A的插入操作时,便可以知道系统表的日志操作已经结束,可以根据前面收集到的系统表操作还原出原始添加列操作,并得到修改以后的表结构,获得添加列的默认值表达式EXP_OLD。然后根据分析事务中表A的INSERT日志,从插入列中提取到添加列的默认值常量表达式EXP_NEW。
其次,在捕获到添加列操作提交日志时,需要判断默认值表达式EXP_OLD和EXP_NEW是否等价,如果不等价,则需要接着修改目标端数据库添加列的默认值表达式为EXP_OLD。这是由于在添加列时,列的默认值可以定义为一个表达式,表达式可以是常量,也可以是复杂的函数计算表达式。当默认值为函数计算表达式时,添加列操作时数据库会根据EXP_OLD表达式运算得到具体的常量表达式EXP_NEW,并把它插入到表的记录中。由于目的端数据库和源数据库针对EXP_OLD表达式运算得到的结果不能保证完全一致(例如EXP_OLD定义为SYSDATE函数),那么目的端数据库在添加列时,应该先以常量表达式EXP_NEW来添加列,这样才能保证目的端数据库添加列以后该列的值和源数据库保持一致,添加列完成以后,源端需要把原始的默认值表达式EXP_OLD发送到目标端,这样才能保证目的端数据库添加列的默认值表达式和源端的一致。
举例如下:
源数据库现有表A,A拥有1行数据,在源端执行添加列操作:
ALTER TABLE A ADD COL DATE DEFAULT SYSDATE;
如图6所示,同步过程如下:
在步骤501中,源端数据同步服务收集该添加列的系统表操作日志。
在步骤502中,当在添加列的DDL事务中发现A的INSERT操作日志时,解析系统表的日志还原得到添加列的操作ALTER TABLE A ADD COL DATE DEFAULT SYSDATE。
在步骤503中,在A的INSERT日志中提取到COL列的新值,假如是:2019-10-01。
在步骤504中,源端数据同步把默认值替换后的添加列操作发送给目的端执行,替换后的操作为ALTER TABLE A ADD COL DATE DEFAULT‘2019-10-01’。
在步骤505中,如果源端添加列操作被回滚,则需要构造删除列的SQL发送到目标端执行,上述例子构造的SQL为ALTER TABLE A DROP COLUMN COL。
在步骤506中,如果源端添加列操作提交,则需要修正目的端数据库A表上COL列的默认值表达式,由DEFAULT‘2019-10-01’改为DEFAULT SYSDATE,上述例子构造的SQL为ALTER TABLE A MODIFY COL DEFAULT SYSDATE。
在步骤507中,完成同步。
本发明实施例通过捕捉对应DDL事物的用户表操作日志,作为触发目的端进行表添加列操作的依据,进一步的在捕获到事务的提交日志或者回滚日志,对添加列操作进行修正,从而基本上可以保证源端数据库和目的端数据库几乎在同一时刻对表进行添加列的操作,这样缩短了添加列操作同步造成的延时并减轻了添加列操作同步对目的端应用的影响。
并且,本发明实施例采用了先根据源端数据库收集到的INSERT操作,给目的端数据库添加列插入默认值,然后再去修改目的端数据库中添加列的默认值表达式的方式,克服了现有技术中例如上述采用系统时间作为添加列情况下,可能发生的直接通过表达式生成目的端数据库添加表默认值方式,会产生添加列中插入数据与源端数据库添加列不一致的问题。
实施例4:
如图7所示,是本发明实施例的基于日志解析的数据库添加列同步装置的架构示意图。本实施例的基于日志解析的数据库添加列同步装置包括一个或多个处理器21以及存储器22。其中,图7中以一个处理器21为例。
处理器21和存储器22可以通过总线或者其他方式连接,图7中以通过总线连接为例。
存储器22作为一种非易失性计算机可读存储介质,可用于存储非易失性软件程序和非易失性计算机可执行程序,如实施例1中的基于日志解析的数据库添加列同步方法。处理器21通过运行存储在存储器22中的非易失性软件程序和指令,从而执行基于日志解析的数据库添加列同步方法。
存储器22可以包括高速随机存取存储器,还可以包括非易失性存储器,例如至少一个磁盘存储器件、闪存器件、或其他非易失性固态存储器件。在一些实施例中,存储器22可选包括相对于处理器21远程设置的存储器,这些远程存储器可以通过网络连接至处理器21。上述网络的实例包括但不限于互联网、企业内部网、局域网、移动通信网及其组合。
所述程序指令/模块存储在所述存储器22中,当被所述一个或者多个处理器21执行时,执行上述实施例1中的基于日志解析的数据库添加列同步方法,例如,执行以上描述的图1-图6所示的各个步骤。
值得说明的是,上述装置和系统内的模块、单元之间的信息交互、执行过程等内容,由于与本发明的处理方法实施例基于同一构思,具体内容可参见本发明方法实施例中的叙述,此处不再赘述。
本领域普通技术人员可以理解实施例的各种方法中的全部或部分步骤是可以通过程序来指令相关的硬件来完成,该程序可以存储于一计算机可读存储介质中,存储介质可以包括:只读存储器(ROM,Read Only Memory)、随机存取存储器(RAM,Random AccessMemory)、磁盘或光盘等。
以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。