3.6 小型机下移x86服务器实施
跨平台数据平滑迁移方案中,做到“平滑”两字最难实现。所谓“平滑”,是指制定的迁移方案中无论是迁移变更还是回退,要对现有生产业务影响降到最低,所以难点就在其中。正如本章开始介绍的,涉及小型机下移x86服务器的系统大多是重要交易系统,任何的失误都可能对外服务造成较大影响,因此“平滑”二字在整个方案中尤为重要。
小型机下移x86服务器项目涉及的系统错综复杂,许多系统间存在一定耦合性,变更任何一个关键节点,可能都会对周边系统造成影响。从方案层面做到尽可能的完善,但世上并没有万全之策,考虑再多也会百密一疏。所以,在制订数据迁移方案时,把重点放到平滑迁移的同时,一定要做到平滑回退,即以最小的代价将系统回退至迁移前的状态,保证快速恢复业务。
前期花了大量时间仔细梳理了每套待下移系统的架构以及业务间关联关系,形成《某某系统小型机下移技术分析报告》,然后结合实际测试情况,再编写《某某系统小型机下移技术方案》,技术方案主要目的是将前期的各方面分析落地形成具体的方案及操作步骤。目前,我们已经将这些总结成为最佳实践,其中涉及跨平台数据平滑迁移的方案也可以有许多应用场景。
3.6.1 Java程序迁移
图3-5 Java应用程序迁移示意图
如图3-5所示,应用系统在x86服务器的优化方案中介绍过,待下移系统在实施前,都要进行智能DNS改造。这项优化的主要目的是为了在系统下移后,实现跨机房的系统平滑切换。其带来的附属好处则能够做到平滑回退,当需要应用程序级回退时,只需要将DNS指向老应用集群即可(即小型机环境)。
对于单独运行在JVM中的应用,只需要提前将应用WAR包复制到应用目录即可,并且需要准备应用相关配置文件及相关程序脚本。
针对部署在应用服务器的应用程序,除了在新的集群部署应用WAR包以外,还需要对相关应用服务器(如WAS)的相关参数进行优化调整。系统下移后,应用集群不发生扩容的,需要将原集群的相关参数同步到新集群中,其中主要包括Web容器、JVM参数、JDBC连接池参数等。
注意:WebSphere Application Server(WAS)中的JDBC数据源默认隔离级别
如果使用WAS提供的JDBC数据源连接Db2数据库时,应该注意默认隔离级别的设定。因为默认情况下,WAS连接Db2采用默认RS隔离级别。而Db2默认隔离级别是CS,通常的应用程序均采用CS隔离级别,除非在某种业务场景上对数据完整性有很高要求时,才会使用高于CS的隔离级别。所以,一般为了更好的并发性能,选择在上线前将WAS连接数据库的默认隔离级别改为CS。
操作步骤:
进入管理控制台→资源→数据源→${数据源名称}(Db2下移后的新数据源名)→定制属性,找到并单击WebSphereDefaultIsolationLevel,将其值修改为2(默认为空),确认后保存,需要重启WAS服务器生效。
针对系统下移后,已对应用集群扩容的系统,需要根据倒漏斗设计原则调整以上提及的性能参数,做出合理的扩容,并考虑后端数据库连接数及关联系统的相关参数配置,以免造成多米诺式性能问题爆发。
知识点:什么是倒漏斗设计原则?
在这个设计模型中,从Web服务器到应用服务器再到数据库服务器,其处理请求的最大并发数逐层减少,这样可以提升系统整体的处理能力。例如,将Web服务器的最大连接数调整为200,WAS的Web容器调整为150,JDBC最大连接数调整为70。
另外,涉及消息中间件迁移的应用,根据消息中间件产品(如MQ)软件版本的具体差异,梳理升级版本后需要变更的相关参数。随后结合测试结果,配置好与应用程序相关的接口(如消息连接工厂)即可。
在以往的经验中,遇到多次因未及时更新应用连接数据库的新版本驱动程序,导致上线后出现许多奇怪的问题。因此,将这个步骤作为应用下移过程中的必要检查项。驱动文件的拷贝建议从新版本数据库的安装目录中Java目录下下载,保证与当前数据库版本兼容。
小技巧:检查Db2数据库驱动程序版本
在UNIX下,可以进入Db2驱动程序目录后,运行以下命令来获取当前db2jcc驱动程序文件的版本信息,从而可以判断当前应用程序使用的驱动版本是否与当前数据库匹配。
<JAVA_HOME>/java -cp db2jcc.jar com.ibm.db2.jcc.DB2Jcc -version
所有应用相关配置完善后,如果采用前面提及的WAS数据源连接数据库,则可以通过“测试连接”来测试与数据库的连接是否正常。随后,可以对应用的配置文件相关参数进行检查,查看是否满足新应用的需要。至此,所有应用相关的迁移前准备都已经就绪了。
总之,应用程序层无状态,因此通过提前在虚拟机部署,实现平滑迁移。再通过智能DNS辅助来应对系统整体回退,如涉及应用的回退,只需要将DNS指向至原小型计算机应用集群即可。而所有在途的交易,需要后续进行手工处理,整体来看应用的“平滑”方案相对数据库来讲相对容易。
3.6.2 C/C++程序迁移
针对C/C++语言,通过以下步骤简述其迁移过程。
1.确认程序是否当前线上版本
确定源代码是否和线上版本一致可采用以下方法。可执行程序通常取决于编译器版本、链接器版本、编译时间(如果使用了__DATE__、__TIME__编译器内置的宏)、编译路径(如果使用__FILE__)等。如果是静态编译,还和所链接库的版本有关。
(1)编译器版本信息,通常也保存在可执行程序中。如果使用Strings命令查看,一般可以看到编译此二进制可执行程序的编译器的版本。
(2)如果能找到当前线上二进制版本的构建环境,则可以尝试将代码重新构建,一般来说,如果没有和时间相关的宏,二进制版本应当保持一致。
(3)如果已经无法找到当前线上二进制版本的构建环境,很难确认源代码和线上版本的一致性。虽然可以使用Objdump -S生成汇编指令,配合Diff等工具比较汇编指令差异,但很难分析,目前可以认为在这种情况下,是无法确认版本的。
2.编译构建
使用源码包中的构建方法即可,通常是Make或者直接执行构建脚本。
本书建议在Linux构建时使用-Wall编译。目前的GCC编译器已经很强大,对于编译时给出的警告,需要逐一分析确认,避免如因原型缺失导致运行时指针处理为INT使程序崩溃等问题。
另外,建议同时编译出一个非优化的、带调试信息的版本(-O0 -g),目的是故障发生后,便于调试分析问题所在。
注意:
AIX中编译动态库用xlc或xlC的参数与Linux平台用gcc/g++的参数不同,Makefile或编译脚本需要修改。又如在AIX上的程序如果使用了多线程,程序一定要在编译时加上-D_THREAD_SAFE或者-D_THREAD_SAFE_ERRNO,Linux则不需要加此定义。另外,注意默认编译为32位还是64位版本的目标,关注64位数据模式对Long和指针类型数据的影响。
3.内存检查
建议对程序进行检查,从原则上来说,如果一个程序运行时发生了内存踩踏,则该程序的运行行为是不可预期的。
通常有以下三类问题。
(1)Double Free问题。这类问题一般不需要特别关心,Linux下会导致程序崩溃。
(2)内存越界访问(主要是写),Linux下主要有Valgrind和Malloc的内置调试工具。
(3)内存泄漏。可以通过PS工具观察程序的内存占用情况。程序运行一段时间后,如果内存稳定在一个水平,则可以认为没有发生内存泄漏。
Valgrind是沙盒运行模式,通常来说性能较差,对于偶发的内存越界或者泄漏,可能需要长时间运行才能侦测到;Malloc内置的调试工具通常来说性能会好些,但由于项目可能会采用第三方的Tcmalloc等代替系统的Malloc,因此不一定全部适用,需要核实程序的具体情况。通常系统的Malloc性能已经足够好,使用第三方内存管理的项目应该很少。另外,Malloc调试工具不能检查非Malloc的数组越界。
Malloc的检测方法:设置MALLOC_CHECK_环境变量为1(打印诊断)或者2(制造崩溃)。一般来说,在检测阶段使用1,可以得到更多的错误点;在解决阶段使用2,避免累积效应难以分析定位问题。
4.已识别的重要差别
结合表3-8,对应用程序进行分析。除非确认不存在该问题或者已经处理过;否则,该问题是全局性影响的,需要全面测试。
表3-8 C/C++语言迁移注意事项
5.测试后上线
针对C/C++应用程序的测试,可以采用前面介绍的机器人流程自动化工具(RPA)方式辅助测试其本地程序的执行结果,可以达到回归测试的目的。针对涉及Socket报文通信处理的部分,可以通过高仿真测试。
3.6.3 数据库离线迁移
每套方案都有它存在的必要性。前面一再强调的所谓“平滑”数据迁移方案,无须停机即可达到跨平台迁移的目的。如果综合考虑成本,是否有数据库离线迁移存在的场景呢?
主要考虑如下几个条件。
(1)可以申请停机时间窗口的系统,采用停机迁移数据。
(2)在有充足的停机时间窗口的前提下,数据库数据量较小,足以在有限的停机时间内完成所有的迁移步骤。
(3)因为数据量较小,如果发生数据库级回退,只需要将有限的数据追回到小型机所在的数据库,即可对外提供服务。
可以考虑在如上所述条件都满足时,采用数据库离线迁移方案。那么在小型机下移x86服务器的项目中,是否有类似系统呢?答案是肯定的。所以,我们设定一套方案选择入口条件,凡数据库数据量小于300GB,且在系统定义的停机时间窗口内可以完成数据传输的系统,且对回退时间没有“平滑”要求的系统,即可考虑使用离线方案进行迁移。具体采用的方法也很简单。
如图3-6所示,db2move采用Db2原生工具实现跨平台数据迁移,也是最常用的一种方法。其优势是操作简单易用性高,整个方案比较实用,它解决了不能通过数据库备份与恢复方式做跨平台数据迁移的问题。但劣势也很明显,就是整个操作过程需要停止对外服务。数据库级无法做到平滑回退,且回退时间相对较长。
图3-6 db2move数据离线迁移逻辑图
db2move工具封装了Export、Load和Import方法,使用比较灵活。通过Export命令可以将待迁移的数据库全量表对象从源端依次导出。而Load和Import命令可以在目标环境依次将数据文件导入。当目标端采用HADR高可用架构部署,将首推采用db2move结合Import方法装载数据,这样可以在一定程度上减少操作步骤。除非需要提高数据导入性能,则可以使用Load命令进行导入,但对于HADR备机需要重新搭建,因为默认Load不记日志会导致HADR备库所有做过Load的表不可用。对于存在外键的数据库,在Load结束后还需要再进行数据完整性校验,确保外键约束正常。
注意:Import和Load工具的区别
db2move中的Import和Load功能直接封装了Import和Load工具。Import会将读取的记录转换为SQL Insert语句,随后通过语法解析、查询优化器、写日志等操作装载到数据库中。Load与Import实现有较大不同,是目前Db2数据装载最实用的利器。Load可以将读取的数据文件记录以数据页的方式直接装载到表空间中,而无须通过DML语句方式记录到数据库中,更不用记录日志,所以Load工具执行速度比Import快得多。
下面介绍db2move工具跨平台迁移的方案。
1.梳理数据库相关对象
该方案中,将首选db2move+Import的方法进行数据加载,前面已提及原因,这里不再赘述。采用Import加载数据,对于目标端数据库有很多限制,例如:标识列、外键、大对象、触发器等,都会对Import方式的数据加载有所影响。为了避免这种问题的发生,需要提前理清源端(即小型机环境)数据库相关对象。随后在系统下移割接当日,将相关对象从目标环境提前删除,待数据装载后,再将已删除的对象重新创建。
可以通过如下SQL语句提前对标识列进行梳理。
db2 "select varchar(tabschema,10) schema,varchar(tabname,30) tabname, varchar (colname,10) colname,nextcachefirstvalue from syscat.colidentattributes with ur"
上面的SQL执行结果中,除了模式名和表名可以轻易识别以外,colname是创建标识列的列名,nextcachefirstvalue代表:开启缓冲(Cache)后,缓冲段内的第一个值。如果没有缓冲,则为下一个已分配的值。
注意:Db2标识列分类
Db2的标识列分为两种:Identity Always和Identity By Default。针对已创建带有“Identity Always”的标识列,Import无法直接加载数据,必须将目标端的“Identity Always”属性去除。而对于“Identity By Default”,则可以直接将数据Import到目标数据库中。
通过如下SQL可以区分两种标识列属性:
db2 "select distinct varchar(tabschema,20) tabschema,varchar(tabname,50) tabname,generated from syscat.columns where tabschema not like 'SYS%' and generated='A' and identity='Y'"
其中,Generated字段代表标识列的类型。A代表“Identity Always”,D代表“Identity By Default”。
在准备方案时,我们只梳理“Identity Always”的标识列,需要提前在目标端数据库删除这个属性才能将数据Import进去。而“Identity By Default”无须提前在目标端删除。
在源端数据库服务器上制作删除“Identity Always”标识列的脚本:
db2 -x "select 'alter table ' || trim(tabschema) || '.' || trim(tabname) || ' alter column ' || trim(colname) || ' drop identity;' from syscat.columns where tabschema not like 'SYS%' and generated='A' and identity='Y'" > dropidenkeys.ddl
随后在目标端数据库上执行刚刚生成的脚本DropIdenkeys.ddl即可手工删除“Identity Always”标识列。
通过如下SQL语句对数据外键提前进行梳理。
db2 "select varchar(pktable_name,40) pktabname,varchar(pkcolumn_name,40) pkcolumn,varchar(fktable_name,40) fktabname,varchar(fkcolumn_name,40) fkcolumn from sysibm.sqlforeignkeys where fktable_name not like 'EXPLAIN%'"
如上SQL语句可以罗列出涉及外键的父表及外键名称,可以通过该SQL了解当前数据库的外键约束情况。如果在数据迁移时,目标端数据库外键约束已存在,则必须按顺序导入相关父子表,否则将可能违反外键约束。为了避免该问题发生,也需要在迁移数据前,将目标端数据库的外键约束删除才能正常装载数据。批量生成删除外键的脚本如下。
db2 -x "select 'alter table ' || trim(fktable_schem) || '.' || trim(fktable_name) || ' drop constraint ' || trim(fk_name) || ';' from sysibm.sqlforeignkeys where fktable_name not like 'EXPLAIN%'" > delForeigKeys.ddl
数据迁移完成后,还需要重建外键约束。因此,可以在源端数据库提前梳理外键对象,生成外键创建脚本,待数据迁移后再实施。具体创建外键的生成脚本如下。
以上SQL语句将自动生成批量创建外键的DDL脚本。这与标识列不同,外键不涉及计数,因此在停止应用前就可以对外键进行梳理。而对于标识列,为了保证数据一致性,只能在停止应用后再生成创建标识列的DDL。
许多下移前的老旧系统物理设计并不科学,大对象与在线业务表混杂在相同的业务表空间中,这可能会导致性能下降。为了更好地优化大对象读写性能,需要将大对象迁移至独立的表空间中,并开启文件系统缓冲(File System Caching)。针对存在大对象的表,需要提前创建大对象表空间,将其指向新表空间。
对于触发器,需要在目标端数据库中提前删除该类对象,防止在目标端数据导入的过程中,触发器启动后,造成源和目标数据不一致的问题。可以通过如下SQL语句提前在源端数据库中梳理触发器对象。
db2 "select varchar(schema,40) tabschema,varchar(tbname,50) tabname, varchar (text,500) tritext from sysibm.systriggers where schema not like 'SYS%' and tbname not like 'ADVIS%' and tbname not like 'EXPLAIN%'"
其中,text字段是创建触发器的具体DDL,可以提前整理好批量删除(DropTrigger.ddl)及创建触发器(CrtTrigger.ddl)的脚本备用。
2.停止服务,导出数据
截至目前,可以将如上介绍的内容形成自动化脚本,便于后续使用。停止应用程序之前,需要再次检查应用及数据库的相关参数,确保x86服务器环境的数据库参数与源端数据库一致。
一切准备就绪后,即可停止应用程序服务,此时正式进入停机时间窗口。后续可以进行数据导出,首先进行数据库全量对象导出。
db2look -d <dbname> -l -o db2look_struct.ddl db2look -d <dbname> -a -e -x -ct -o db2look_<dbname>.ddl
db2look工具可以将数据库内全量数据对象DDL导出。这时针对序列、“Identity By Default”标识列等对象会将重置数值(Restart With)打印至DDL脚本中。在目标端执行这些脚本时即可将数值写入数据字典中,做到“无缝衔接”。而对于前面提及的外键、“Identity Always”标识列、触发器等对象,在目标端创建后,需要通过第一步创建的删除脚本(DropIdenKeys.ddl)依次将其删除,并确保数据导入条件就绪。
随后,对于前面提及的“Identity Always”标识列,需要在源端应用真正停下来后,再生成新建标识列的命令语句。这个步骤不能提前准备的原因主要是由于nextcachefirstvalue字段值有随时变化的可能性,所以必须停机后导出该值,来保证数据一致性,否则会造成数据迁移后出现标识列数值重叠问题。通过如下SQL拼接生成创建“Identity Always”标示列的语句。
准备好生成“Identity Always”标识列的自建脚本后,即可进行全量数据导出工作。
cd /<足以容纳整个DB的文件系统>/lobsout/<dbname> db2move <dbname> export -l /<足以容纳整个DB的文件系统>/lobsout/<dbname>
执行数据导出命令前,需要准备可以容纳整个数据库的文件系统目录,随后执行db2move+Export命令,Db2将表对象一张张串行导出至该目录中。其中,“-l”关键字针对大对象,如果在之前检查大对象的步骤中发现有相关数据存在时,需要在这个步骤中增加这个选项,便于大对象的导出。
3.数据导入并修改数据源
将以上打包后的迁移数据通过网络传输至目标数据库服务器中,随后通过如下命令进行数据全量导入。
装载数据前,需要根据源端数据库配置来创建目标端数据库及相关数据库对象,并删除必要的数据库对象。请注意以上执行顺序,其中,db2move命令可以将当前目录的数据文件装载到目标数据库中。
数据导入时,db2move分别给出两种数据装载方式:Import和Load。其中,“-io”是Import的参数,而“-lo”是Load方法特有的参数,都代表装载。后面的“-l”指定之前大对象导出打包的目录位置。
前面已经介绍推荐使用db2move + Import的原因,这样后续无须再重新配置目标端数据库的HADR高可用。如果迁移大表(如数据量达到上亿条记录)时间较长,可以使用db2move+Load进行数据装载,但针对该表在HADR备机切换为主机后将无法继续访问。对于这点必须提前梳理好表的数据量,提前选择数据装载方法。
注意:使用db2move + Load针对外键的注意事项
如果数据库存在外键,使用db2move + Load装载数据前,无需删除外键约束。装载数据后,只需要执行完整性校验即可恢复数据访问。下面的语句可以批量生成需要完整性校验的修复命令。
db2 -x "select 'set integrity for ' || trim(tabschema) || '.' || trim(tabname) || 'immediate checked;' from syscat.tables where status='C'"
利用数据装载的这段时间,可以对应用程序数据源进行修改。对于应用程序数据源配置,可以将数据源地址直接改为数据库对外服务域名地址即可,随后需要重启应用服务器使其生效。
4.数据初始化
数据导入完毕后,许多读者可能会问,为了保证迁移后的数据一致性,是否需要检查源和目标两个数据库环境中相关表对象的记录条数?其实,这个问题在db2move对每张表Export和Import输出日志中找到答案,不用单独再重新验证所有表对象记录。数据库工具可以保证数据的一致性,除非看到相关数据对象装载报错,或由于某种约束产生数据Reject。
随后的数据初始化步骤是将前面梳理拆分后的已删除对象,再重新添加至目标数据库内。主要包括前面提及的外键、标识列(Identity Always)、触发器三类对象。
db2 -tvf crtForeignkey.ddl #手工创建外键 db2 -tvf crtIdentAlways.ddl #手工创建标识列 db2 -tvf crtTrigger.ddl #手工创建触发器
所有对象在x86服务器的数据库中初始化完成后,即可对全量数据库做统计信息收集(runstats)。
db2 "runstats on table <schema>.<tabname> with distribution and detailed indexes all"
如果目标数据库存在存储过程或SQC、SQLJ等嵌入式程序,则待统计信息收集完成后,需要对程序包进行重新绑定。这里一定注意统计信息收集和重新绑定程序包(db2rbind)的先后顺序。必须保证统计信息收集在先。
db2rbind <dbname> -l <logfile> all
其中,<dbname>为数据库名,<logfile>为产生的程序包绑定报告。
注意:重新绑定程序包的意义
重新绑定程序包,对于存储过程及嵌入式程序很有意义。统计信息更新后,必须通过重新绑定来重新生成程序包内的执行计划,这样能保证包内静态SQL执行计划与实际无偏差。防止存在包内执行计划失真的问题。
通常建议在停止相关应用程序后,再重新绑定程序包(db2rbind)。因为绑定动作与相关程序运行时互斥,会造成不必要的锁冲突,直至锁超时。
5.更换驱动程序,开始业务验证
在启动新应用程序前,正确更新驱动程序至关重要。为了保证驱动程序的准确性,应从数据库安装目录或数据库实例目录获取db2jcc.jar驱动文件,随后将其复制到应用服务器的相应目录中。
数据库大版本升级后,推荐一定要更新驱动程序。但对于多个应用程序共用一个驱动程序的情况需要格外注意,不能贸然进行驱动替换,否则可能会带来无法预估的问题隐患。例如,多个应用程序是待升级应用的上游系统,如果下游系统数据库升级后,本身应用需要更新驱动程序外,其余上游系统也要通过测试验证后再考虑更新驱动程序,这无形中也增加了测试工作量。
以WAS配置驱动程序为例,使用WAS默认的数据源连接数据库时,更新驱动程序后,需要重启应用服务器。随后,登录WAS控制台→资源→JDBC→数据源→选择相应的数据源→单击“测试连接”验证连通性。
注意:db2jcc.jar与db2jcc4.jar的区别
数据库驱动程序文件默认存在如下目录中。
<实例目录>sqllib/java
如果应用程序使用JDBC 3.0或以前的功能开发,则应复制db2jcc.jar到应用驱动目录。
如果应用程序使用JDBC 4.0或以后的功能开发,请使用db2jcc4.jar。但应用驱动程序目录不能既包含db2jcc.jar又包含db2jcc4.jar,只能存在一个驱动文件。
驱动程序更新就绪后,就可以准备内部和外部业务验证。内部验证主要包括系统下移前选择的固定交易场景,又称为内部模拟交易,采用模拟用户在新下移的环境中运行,用于验证各交易组件是否正常。通过内部验证后,可以开启对外业务访问。通常这个时候,需要通过监控来实时观察交易成功率和平均交易响应时间的变化,用于判断系统各类健康指标是否正常。
6.数据库离线迁移方案的回退方法
由于离线迁移方案的技术特点,其回退方案不太灵活,回退耗时也比较长。发生变更回退时,理想情况下,需要将x86服务器产生的增量数据迁移回AIX服务器才能完成回退。
(1)增量数据反向同步:该方案在数据对象梳理时,需要花费更多的时间。往往需要提前分析主业务表产生的增量数据能否通过标识字段(如时间戳)甄别其增量数据。对于系统的主业务表间关系简单,且有明确标识字段可以表示增量数据时,则通过写增量数据反向同步SQL的方法来保证数据回退。
(2)全量数据反向同步:针对全量数据量小于300GB,且梳理主业务表的开销非常高时,可以考虑用全量数据反向同步的方式实现数据回退。全量数据反向同步,顾名思义,就是在发生回退时,将x86服务器数据库内的全量数据通过db2move工具反向装载回AIX数据库服务器内,并覆盖所有数据的方案。从逻辑上很好理解,但全量数据的传输往往耗时比较长。
基于离线迁移技术都无法做到真正的“平滑”数据迁移。如果待迁移的系统停机时间窗口十分有限,无法采用离线方式下移,则可以考虑在线平滑迁移方案。
3.6.4 数据库平滑迁移
前面提及的离线迁移方案主要特点是体量轻、操作简单,但必须在源端应用停止后才能进行数据迁移动作,这也正是离线迁移方案耗时长的主要原因。那能否在不停机时,做到数据迁移呢?
在数据库平滑迁移实施中,源端是AIX平台数据库,目标端是x86平台数据库,那么CDC创建的从源端到目标端的预订,称为“正向预订”;反之,当源端和目标端对调时,则称为“反向预订”。
正向预订负责源端到目标端的数据复制。在系统正式割接后,这时就可以启用反向预订,对部分重要业务表或全量表进行反向同步。即系统割接后可以将x86服务器高版本数据库作为源端,而小型机环境的数据库作为目标端的方式将增量数据同步回数据库中。这时,一旦发生不可修复的问题,根据事发当时的决策点来选择是否需要启动系统回退动作。无论是系统割接还是回退,都不会再涉及两端数据的流动,从而在满足数据一致性的前提下,达到缩短停机时间的目的。
本节将首先介绍IBM CDC的安装配置,随后以商业汇票系统为例讲述如何新建正向预订和反向预订。
在数据迁移原理中,曾对数据库日志复制有过简单介绍。业界内大家熟知的数据库日志复制工具是Oracle Golden Gate(OGG),该工具可以支持多种数据库跨平台的数据复制。OGG与Oracle数据库本身适配比较好,但对Db2最低版本只支持V9.7。考虑到待下移系统数据库版本的多样性,最终选定IBM Change Date Capture(CDC)工具作为本次小型机下移中数据库平滑迁移工具。
下面简单介绍CDC工具的架构。
图3-7展示了CDC工具的几个重要组件:Management Console、Access Server、Apply Agent、源和目标DataStore、元数据(Metadata)、源端和目标端转换引擎等。
(1)Management Console:管理端控制台,用于配置、监视和管理CDC工具源和目标的复制。
(2)Access Server:用于控制对复制环境的所有非命令行访问。可以通过控制台连接Access Server,来管理源和目标数据库。
(3)Apply Agent:目标端代理程序,用于接收来自源端的更改动作。
(4)源和目标DataStore:每个DataStore代表一个要连接的数据库,并充当表对象的容器。通常用于复制的表都存放在DataStore中。
(5)元数据(Metadata):用于相关表的映射、预订、通知、事件和其他详细信息。
(6)源端转换引擎(Source Transformation Engine):源端数据转换引擎,在源端解析数据库事务日志来捕获数据变化,并将变化数据编码后通过网络发送给目标端。
(7)目标端转换引擎(Target Transformation Engine):目标端数据转换引擎,通过网络收到源端的数据变化后,在目标端进行重放。
图3-7 CDC软件架构图
在安装CDC各组件前,需要提前规划CDC各组件的安装位置,以数据库跨平台迁移至x86服务器为例,建议以如下方式安装各组件,如表3-9所示。
表3-9 CDC安装计划
1.安装CDC前的注意事项
安装前要对源和目标的数据库当前架构做好调研工作。小型机下移x86服务器前,这些系统多数采用传统的主备HA架构或HADR架构。针对这种架构,CDC需要注意的配置项如表3-10所示。
表3-10 HADR架构CDC配置注意事项
对于源端是HADR架构的系统,目标端推荐设置为单分区数据库,暂时不要开启HADR,待与源端完成同步割接系统后,再通过备份目标库(新版本)到目标HADR备机环境,与此同时再建立HADR连接。
对于割接切换后新环境需要反向同步至老环境时,需要先将老环境HADR相关属性关闭(BLOCKNONLOGGED=NO)随后再开启反向同步即可,否则反向预订同步将失败。
注意:手工同步源和目标数据库配置参数
数据库驱动程序文件默认存在如下目录中:
<实例目录>sqllib/java
(1)利用db2set -all命令对比源和目标的环境变量是否一致。
(2)利用db2pd -dbmcfg命令对比源和目标的数据库管理器参数是否一致。
(3)利用db2pd -db <dbname> -dbcfg命令对比源和目标数据库级参数配置是否一致。
(4)检查不一致参数,需要更新目标端参数:
db2 "update db cfg for <dbname> using <参数名> <参数值>"
了解CDC安装前的注意事项后,接下来要明确CDC的使用限制,做到知己知彼,才能百战不殆。
要允许CDC复制DDL语句,必须满足如下先决条件。
(1)源和目标的CDC Agent必须是V10.2.1以上版本。
(2)源和目标的Db2必须是V10.1以上版本。
(3)创建源和目标CDC实例时,指定的Db2用户必须相同。
(4)源和目标必须是不同的库,不支持源和目标同一库。
(5)必须确保源库开启Dft_Schemas_Dcc=yes。
(6)源和目标Db2参数Log_Ddl_Stmts必须为Yes。
(7)源和目标数据库的代码必须相同。
目前CDC支持的在线DDL种类有限,具体请见表3-11。
表3-11 CDC支持的在线DDL操作
另外,CDC支持源到目标的数据转码,但对于部分编码需要提前考虑扩位。例如,GBK到UTF-8时,由于中文一个汉字需要占用4B,因此最好在相关字段上扩容1倍,保证数据不被截断,因为CDC在同步时不会提示目标端数据被截断。
当然,CDC也有许多不支持的内容。其中特别注意事项,见表3-12。
表3-12 CDC不支持复制的对象和操作
了解CDC工具的使用限制后,下面安装和配置CDC。
2.安装Access Server
在操作系统上创建用户和组,如表3-13所示。
表3-13 CDC用户与组
Access Server安装步骤如下。
3.安装CDC agent for Db2
Access Server安装成功后,在源和目标都需要安装CDC agent for Db2,具体步骤如下。
4.配置CDC agent for Db2
安装CDC agent for Db2后,即可直接进入配置菜单。可以先暂时退出配置菜单,给CDC用户授予合适的权限,CDC工具主要通过这个用户来管理源和目标数据库对象及表数据。
1、连接源与目标的数据库 su - <实例用户> #如db2inst1 db2 connect to <dbname> 2、对cdcadm授权 db2 grant dbadm on database to user <cdc用户名> #这里是cdcadm db2 terminate
在源和目标安装CDC agent(Replication)for Db2 for LUW,为了实现跨平台迁移与数据库版本升级,往往源和目标的数据库版本相差较大,对于CDC Agent来说也可以选择不同的版本,均可兼容。
5.安装CDC管理控制台
CDC Management Console必须安装在一台Windows主机上,要求Management Console要与源和目标网络保持畅通。
在Windows上安装CDC管理控制台十分简单,双击iidrmc-11.3.3-4288-setup(以V11.3.3为例)可执行文件,等待安装向导弹出后,一直单击“下一步”按钮即可完成安装。在这里就不详述安装步骤了。
6.配置管理控制台与源和目标存储器
图3-8是CDC管理控制台的登录界面。
图3-8 CDC管理控制台的登录界面
(1)登录CDC管理控制台(CDC MC)。
第一次登录CDC MC时,会提示更新密码,需要按要求重置6位密码。
(2)配置存储器:需要在源和目标端创建存储器。
如图3-9所示,选择Access Manager并单击添加新的存储器。
图3-9 在CDC MC中添加新数据存储器
(3)填写源和目标数据库相关配置信息。
源和目标存储器的名称要具有可识别性。例如,AIX_Source代表源端,LINUX_Target代表目标端。随后,填好IP地址和端口即可完成配置。
(4)将数据存储器分配给CDC管理台用户。
选择“文件”→Access Server→“分配”→“数据存储器”,如图3-10所示。
图3-10 分配CDC管理台用户
可在“连接参数”中配置连接数据库的用户和密码。
(5)连接存储器。
选择“配置”选项卡,如图3-11所示,选择存储器后单击“连接”按钮进行存储器连接。
图3-11 选择存储器进行连接
以上是系统割接前安装并配置CDC的过程。接下来,数据同步完成后,介绍割接当日的主要工序。
第一步,停止应用程序对外服务。利用提前准备的应用自动化启停脚本,对AIX端应用进行全量停止,随后通过验证脚本确认应用离线状态是否正常。
第二步,停止CDC正向预订复制。这里一定要选择正常停止,保证在途复制事务落地,从而保证数据一致性。
第三步,使用前期编排的脚本,将创建正向预订前已删除的对象在目标端数据库中重新创建。例如,外键(CrtForeignKey.ddl)、触发器(CrtTrigger.ddl)、标识列(CrtIdentAlways.ddl)、随后重置序列(RestartSeqValue.ddl)和标识列(RestartIdenColbyD.sql)等对象。至此,目标端的所有对象才与源端保持同步。
第四步,进行全量数据验证。CDC工具本身无法保证源和目标端数据库表对象记录数的一致性。可以提前准备好对比脚本,基本策略是:首先在AIX源端和x86目标端进行全量表记录数检核;其次,将两个平台产生的数据检核报告(表名+记录数),在其中任意一个主机上进行Diff核验,找出存在数据量差异的表对象,经过判断后再确定是否需要重新刷新该表。
小技巧:跨平台数据核验应注意的事项
可以通过select * from <tabname>方式进行全量数据查询。如果数据库比较大,这将花费大量的时间,同时增加了停机时间窗口。这就需要提前梳理这些表的数据量,对于大表且有时间戳字段的,可以做增量验证方案。也就是在停止CDC正向预订前,先验证90%的数据,停机后再验证剩余的数据增量即可。
另外,在并发量上可以将大表拆分为多张表同时查询结果集,主要目的也是为了提速。
第五步,如果数据库存在外键、标识列(By Always)和触发器,在开启反向预订前,同样需要在AIX端数据库中利用脚本删除它们。例如:外键(DelForeignKeys.ddl)、标识列(DropIdentKeys.ddl)和触发器(DropTrigger.ddl)删除脚本。用于确保反向预订能正常复制,保证反向数据一致性。
第六步,数据一致性检查与AIX端相关对象处理结束后,在开启反向预订前,需要对所有反向预订内的表对象进行“标记用于制作镜像的表捕获点”。打标记的时机很重要,一定要在AIX应用停止后,目标端相关对象创建后,且在x86应用启动前开启才行。差之毫厘,谬之千里。随后,再开启反向预订,这才能保证该方案的核心思想:“平滑”回退。
第七步,开启x86服务器端应用程序。与此同时,开始对目标端数据库进行全量的统计信息收集(Runstats),这部分请参考数据库离线迁移方案中统计信息部分的介绍。如果涉及存储过程或SQC嵌入式语言开发,则还需要在统计信息后实施Db2rbind重新绑定程序包。最后,可以修改应用程序相关配置,测试数据库连接,开启x86应用服务器,开始对外提供服务。
第八步,截至目前,x86服务器已对外提供服务。此时需要利用提前准备好的应用验证预案,进行内部和外部的业务验证。
第九步,数据迁移已经完成。接下来还需要重新搭建x86端的HADR。因为选择这时搭建同城和异地灾备数据库的原因是:在CDC全量刷新时会对目标端使用Load,如果提前搭建HADR,那么所有的备机已同步的表对象数据都不能正常访问(原因是Load不记日志,备机无法接收通过主机日志传输过来的Load事务)。
7.针对平滑回退的决策点
当迁移过程中或迁移后发生不可修复或数据一致性问题时,根据事发当时的决策点来选择是否需要启动系统回退动作,具体决策点包括以下内容。
(1)小型机(源端)与x86服务器(目标端)存在数据不一致问题,且数据量巨大,无法在时间窗口内完成数据同步时。
(2)数据迁移过程中,发现小型机(源端)与x86服务器(目标端)迁移的数据对象不匹配,并存在数据对象个数争议时。
(3)系统迁移步骤完成,启动应用程序后,做内部业务验证时,出现影响业务使用的不可预知的问题,且在时间窗口内无法解决时。
(4)由于某种外部不可抗力因素影响系统整体下移变更进度,从而导致时间窗口内无法完成变更时。
(5)系统出现严重性能问题,对业务影响程度较大、范围较广,且无法通过调优手段解决问题时。
(6)系统出现功能性问题,并未在迁移完成当天业务验证中发现,经判断该业务相关功能无法通过其他解决手段恢复时。
8.系统整体回退方案
CDC通过创建反向预订保证在x86数据库产生的增量数据能够准实时复制回小型机数据库中。当需要系统整体回退时,需要按如下步骤执行。
第一步,停止应用程序对外服务。利用提前准备的应用自动化启停脚本,对x86端应用进行全量停止,随后通过验证脚本确认应用离线状态是否正常。
第二步,在CDC管理控制台正常停止所有反向预订,保证在途复制事务落地,从而保证数据一致性。
第三步,将开启向预订前,在AIX端数据库中已删除的对象重新创建一遍。例如:外键(CrtForeignKey.ddl)、触发器(CrtTrigger.ddl)、标识列(CrtIdentAlways.ddl),随后重置序列(RestartSeqValue.ddl)和标识列(RestartIdentColbyD.sql)等对象。
第四步,利用数据一致性验证脚本,对x86端和AIX端进行数据一致性校验。
第五步,重新启动AIX端应用程序集群。采用智能DNS将服务请求指向AIX端应用程序集群中,即可完成整体系统回退。
9.系统迁移后的工作
在系统正式割接后,需要继续观察系统的各项指标健康度。这些指标可以借助商业银行常规的监控手段,实时监控交易层和系统层指标变化,如果指标出现异动,需要进一步分析确认其影响,从而做出下一步优化动作。
当连续三天(业务高峰期)系统健康度表现优秀,各项指标不能低于系统下移前的最优值。随后,即可关闭CDC反向预订,并停止AIX小型机数据库对外服务。
至此,整个数据库平滑迁移顺利完工。
3.6.5 数据库迁移方案的选择策略
前面先后浓墨重彩地介绍了两种跨平台的数据迁移方案,结合小型机下移x86服务器项目。下面对以上介绍的数据迁移方法进行简要对比,见表3-14。
表3-14 数据库跨平台迁移方法对比
针对方案选择基本策略考虑如下。
(1)如停机时间窗口充足,数据量在300GB以内,首选数据库离线迁移方案(db2move)。
(2)如停机时间窗口不足,无法在规定时间内完成数据传输,则首选数据库平滑迁移方案(CDC)。
3.6.6 商业汇票系统数据库平滑迁移步骤
至此,利用CDC进行数据库平滑迁移的主要逻辑都已介绍完毕。接下来可以利用上述方案对商业汇票系统进行平滑迁移,在配置CDC实时复制前,需要做如下准备工作。
1.梳理源端数据库对象,准备对象迁移脚本
这个步骤的目的与数据库离线迁移方案如出一辙,但在CDC的平滑迁移方案中,在配置前需要考虑更多内容。
db2look -d <dbname> -l -o /tmp/db.tbsbps.ddl #单独导出数据库缓冲池和表空间配置 db2look -d <dbname> -x -o /tmp/addGrant.ddl #分割用于用户授权的脚本 db2look -d <dbname> -a -e -ct -o /tmp/addTabs.ddl #分割数据库表对象的脚本
V9.7版本以后,请增加-ct选项,按对象创建时序导出。这个功能比较实用,可以解决目标环境对存在依赖关系的数据库对象无法正常创建的问题。例如,a视图依赖b表,如果先创建a视图就会报b对象不存在的错误。
注意:AIX操作系统字符集
AIX操作系统如没有安装UTF-8 ZH_CN/GB18030中文字符集,则db2look导出的建库脚本中,中文将显示为乱码。需要提前安装相关字符集。
通过db2look工具生成三个脚本,“/tmp/db.tbsbps.ddl”脚本可以提前在目标端数据库中导入,保证源端数据库表空间及缓冲池对象的同步。“/tmp/addGrant.ddl”脚本单独用于相关对象的授权。“/tmp/addTabs.ddl”脚本是该数据库内所有对象的集合,这正是需要提前梳理的内容。针对该方案,可以利用该脚本梳理如下内容。
1)梳理外键关系
结合数据库离线迁移方案中介绍的外键删除脚本DelForeignKeys.ddl和外键创建脚本CrtForeignkey.ddl。
2)梳理标识列
具体方法请参考数据库离线迁移方案中删除标识列脚本DropIdentKeys.ddl和创建标识列脚本CrtIdentAlways.ddl。与离线方案不同的是:针对CDC平滑迁移方案还要考虑“Identity By Default”类型的标识列。主要因为CDC平滑迁移方案中,目标端对象是提前创建的。而离线方案中,目标端对象是停机后创建的。对于“Identity By Default”的值可以被CDC复制到目标端对应的表中,但标识列的起始值并不能通过CDC同步复制。所以需要在正式应用割接后,启动应用程序前,需要再重置“Identity By Default”的起始值,保证标识列的数据连续性,从而避免目标端标识列数据重复。
db2 "select distinct varchar(tabschema,20) tabschema,varchar(tabname,50) tabname,generated from syscat.columns where tabschema not like 'SYS%' and generated='D' and identity='Y'" > /tmp/idenColbyD.out
手工生成/tmp/idenColbyD.out,并分析“Identity By Default”,检查/tmp/idenColbyD.out,即使确实存在这些列,也无须像“Identity Always”那样在x86中那样提前删除它们。
对于“Identity By Default”在重建目标端对象时,“Restart With”不能是默认值“1”或者“+1”,必须停止源端应用后,用源端MaxValue + 1方式重置目标端。因为数据虽然同步至x86,但编目元数据还是初始值。
停止应用程序后,在目标端数据库可以通过如下SQL语句生成自动重置“Identity By Default”标识列的初始值。
db2 -x "select 'select ''' || 'alter table ' || trim(tabschema) || '.' || trim(tabname) || ' alter column ' || trim(colname) || ' restart with ''' || '|| char(coalesce(max(' || trim(colname) || ') ,0) +1) from ' || trim(tabschema) || '.' || trim(tabname) || ';' from syscat.columns where tabschema not like 'SYS%' and generated='D' and identity='Y'" > IdenColbyD.sql
随后再通过如下方法重置“Identity By Default”标识列。
db2 -tvf IdenColbyD.sql > restartIdenColbyD.sql db2 -tvf restartIdenColbyD.sql
小技巧:标识列在平滑迁移中的注意事项
读者不难发现,针对“Identity Always”标识列,目标端对象必须在数据传输前删除,而“Identity By Default”标识列无须删除。系统割接后,对外提供服务前,“Identity Always”标识列可以在源端数据库通过脚本生成,随后在目标端创建。而“Identity By Default”标识列需要在目标端数据库重置初始值。
3)序列梳理
数据平滑迁移方案中需要考虑序列值的同步。目标端的序列对象在建立CDC正向复制预订前就已经创建了,所以原因和标识列相同,也需要考虑序列下一键值的连续性。这里要特别注意,应用使用数据库序列(Sequence)一般是为确保唯一性,序列值单调递增。但不排除个别应用系统将序列作为交易流水的值,这样表的相关字段值不但要唯一,而且要连续,不能出现空洞。这就要求在系统割接后,启动应用程序前,重置序列值保证源和目标数据库的数据连续性,将序列值完美地衔接上。
db2 -x "select 'alter sequence ' || trim(seqschema) || '.' || trim(seqname) || ' restart with ' || char(nextcachefirstvalue + <value>) || ';' from syscat.sequences where seqschema not like 'SYS%' and seqtype<>'I'" > RestartSeqValue.ddl
以上SQL语句中有个变量<value>,在这里设计变量的目的主要源于以下两个需求。
需求一:如果应用允许序列值出现空洞,可以在系统割接后,将序列当前值加上序列Cache值(这个Value变量),保证序列值的唯一性。
需求二:如果应用要求序列必须连续不能有空洞,则无须增加这个value变量。
在数据平滑迁移方案中考虑序列值,开始创建目标数据库时无须删除序列,只需在系统割接时,应用程序启动前,按需将序列值重置后即可。
4)触发器对象梳理
触发器对象的创建(CrtTrigger.ddl)和删除脚本(DropTrigger.ddl)可以提前准备。这两个脚本都可通过“/tmp/addTabs.ddl”脚本直接生成,通过sed命令可以截取其中所需部分。因为触发器会触发数据的级联变更,数据通过CDC复制到目标端后,触发器可能会带来不必要的数据级变动,存在数据一致性风险,所以需要在源和目标开启复制前删除触发器。
小技巧:利用sed制作触发器脚本
利用sed分割db2look导出脚本:
sed –n '9,3061p' /tmp/addTabs.ddl > /tmp/crtTriggers.ddl
其中,9代表从第9行开始,到第3061行结束。截取这段脚本存储到“/tmp/crtTriggers.ddl”文件中。
2.配置CDC复制前的注意事项
1)检查字符编码
许多系统在做系统下移x86的同时,也有修改字符编码的需求,例如,许多库采用GBK编码,迁移后的数据库采用UTF-8编码,这样将带来新的工作:字段扩位。
从GBK、GB2312到UTF-8需要扩位,因为GBK和GB2312一个汉字占2B,而UTF-8占3B,超长字符会占用4B。而GB18030基本与Unicode、UTF-8一致,有1B、2B和4B。因此,需要将目标端的字符类型的字段统一扩位至少1.5倍,但对于本身数据量较大的库(例如几十个TB),需要利用导入导出数据判断字符是否被截断来判断具体需要扩位的字段。
CDC工具本身支持源和目标字符编码不同的复制。因此,无须对CDC工具进行额外的配置。
2)分区表检查
CDC支持分区表数据的复制,这需要在源和目标端CDC实例中设置如下参数。
db2 connect to <dbname> db2 "select tabname from syscat.tables where tbspace is null and type='T'"
如果如上语句有输出,则证明该数据库有分区表,需要手工在源和目标设置CDC分区表支持。
./dmset -I cdcrep range_partitioned_table_support=true #分别在CDC agent的源和目标设置该参数
随后重启CDC。
cd <CDC_INSTALLATION_PATH>/bin ./dmshutdown -I <CDC_INSTANCE_NAME> #停止CDC实例 ./dmts64 -I <CDC_INSTANCE_NAME>& #启动CDC实例
接下来,可以通过CDC管理控制台来创建复制预订,用于负责源和目标的表对象级别复制。
3)创建CDC预订的建议
可以在系统正式割接前7日开始准备安装CDC并配置双向预订,随后开启“正向预订”同步数据,直至割接时点前可以一直保持“正向预订”的数据准实时同步。待系统割接后,新应用启动前再启动“反向预订”,这样即可满足数据库“平滑”回退的需求。因为,在x86服务器的数据库产生的增量数据文件可以轻松通过CDC工具反向同步至AIX环境数据库中。
CDC是以表对象为单位来创建预订并同步数据的。那么每个预订内应该存放多少表对象,表对象数据量大小如何考虑是有具体部署策略的。在创建“正向预订”前,先来了解创建CDC预订的策略,如下。
(1)百万至5千万的大表分配到不同的CDC预订中,目的是提速。至于分配多少个预订,要根据源端系统的可用资源来定。可以先按每个预订3~10个大表计算,最终来计算分配多少个预订,如果预订超出10个,可以在日终业务低峰期开启10个预订,观察源端数据库服务器的CPU及I/O资源使用,保证的原则是CDC在刷新阶段不能影响源端数据库服务器20%的资源占比,如果没有达到这个阈值,可以再开启更多的预订。
(2)保证要在日终业务低峰期进行预订的刷新阶段,在日间期间能够顺利进入“镜像刷新”状态,这样即可保证对源端的压力降到最低。
(3)如果前面评估的外键是简单的父子一层关系,即可将所有的父子表单独放到一个预订中,并按照先父表再子表的顺序刷新,如果遇到复杂外键关系,可直接利用前面的脚本删除所有外键,割接后再重建外键。
(4)为了做到平滑回退,要提前梳理那些需要反向同步的表。这些表要单独放到一个项目的预订中,并按目标到源的反向关系创建反向预订,并设置冲突检测机制保证平滑回退。
(5)5千万(含)以上的大表需要手工借助Load工具全量灌入目标端,然后增量部分可以利用CDC进行追平。将源端不可避免Load的表单独放到一个预订中。
注意:CDC预订个数与源端数据库性能
CDC创建正向预订后,数据复制分为两个阶段:第一阶段叫全量刷新;第二阶段叫镜像复制。在全量刷新阶段,源端每个预订内的表复制是串行执行的,每张表都类似于全表扫描查询,随后将结果集通过Load方式装载到目标端数据库映射的表对象中。那么开启CDC复制后,源端数据库的最大性能压力取决于同时运行的CDC预订个数和当时业务活动并发连接数。因此要仔细权衡预订个数和数据库活动并发数。第一阶段结束后,进入第二阶段镜像时,对于源端的压力就变得非常小了。
3.开始配置CDC正向预订
了解了创建CDC预订的策略后,下面介绍如何创建CDC正向预订。
承接上文,安装配置CDC后,可以新建正向预订。如图3-12所示,CDC正向预订以表为粒度定义了源和目标表对象的映射关系。正向是指数据流向从小型机到x86服务器。在新建CDC预订前,需要利用之前编排好的目标数据库删除对象脚本,将外键(DelForeignKeys.ddl)、标识列(DropIdentKeys.ddl)、触发器(DelTrigger.ddl)等对象手工删除,保证正向预订复制能够正常运行。
(1)首先登录CDC管理控制台,随后选择“配置”选项卡,单击“新建预订”按钮,如图3-13所示。
图3-12 CDC正向预订
图3-13 新建CDC预订
(2)为正向预订起名后,选择正确的源和目标存储器,切忌方向性错误。
(3)如图3-14所示,选择“多个一对一映射”单选按钮,开始映射表对象。
图3-14 “一对一”映射表对象
如图3-15所示,选择一张表开始映射。或者可以批量勾选需要同步的表对象,CDC会自动建立每张表的映射关系。
图3-15 选择表对象开始映射
(4)选择“创建新的目标表”单选按钮,因为在创建测试预订时,并未在目标端创建表对象,所以可以通过CDC创建,如图3-16所示。
图3-16 创建新的目标表
(5)先选择目标端的Schema Name,然后选择目标端的表空间,如图3-17所示。
图3-17 选择表空间
选择“与源表名称相同”单选按钮,如图3-18所示。
图3-18 在目标端创建与原表相同的表名
(6)选择“镜像”方法同步数据,并勾选“防止递归”复选框,如图3-19所示。
图3-19 开启镜像复制方法并防递归复制
随后,选择“监控”选项卡,观察镜像复制的进度和状态。
4.开始配置CDC反向预订
根据CDC预订创建规则,创建CDC正向预订后,即可开启正向预订复制。随后,可创建反向预订,但不能开启反向预订复制,一定要等割接日当天,启动x86服务器应用之前开启即可。
如图3-20所示,为了能够做到“平滑”回退,必须提前创建CDC反向预订。它的数据传输方向是从x86数据库到AIX数据库。创建反向预订前,首先应梳理出哪些表需要反向同步,随后将这些表对象统一规划入单独预订内。
图3-20 CDC正向预订和反向预订
(1)登录CDC管理控制台,新建反向预订,过程与正向预订一致,如图3-21所示。
图3-21 新建反向预订
(2)在新建的反向预订中,建立x86数据库到AIX数据库的表级别映射。这个过程与正向预订建立表映射类似,其中不同的是,需要选择“映射到现有目标表”。然后根据提示一一映射每一张需要反向同步增量数据的表对象。
5.接当日的主要操作
当正向预订将全量数据复制完成,且所有正向预订处于“镜像刷新”状态时,即可正式进入系统割接环节。
根据3.6.4节中介绍的主要步骤。其中第一~五步都是利用前期准备的自动化脚本,在系统进入停机时间窗口后的自动化操作,在此就不详细介绍了,从方案中第六步开始。
(1)最关键的步骤是“标记用于制作镜像的表捕获点”。这听起来很难理解,其实这个步骤主要目的类似于一些网络下载软件的“断点续传”功能。小型机下移x86服务器系统割接当日,应用程序停止后,CDC正向预订已将数据追平。随后需要将在x86服务器数据库内产生的新写入类事务再同步回AIX数据库中,而无须再全量同步,只需要增量同步数据即可。实现这个目标的方法就叫作“标记用于制作镜像的表捕获点”,类似于书签,待下次阅读时,从上次书签处继续阅读即可。
注意:制作镜像的表捕获点的时机
CDC反向预订可以提前创建,但一定要注意制作捕获点的时机。针对系统下移,要在停止正向预订后,在x86数据库(目标端)所有初始化动作结束后,且应用程序启动前才能制作捕获点。
例如,图3-22中可以右击预订中的一张表,对其打标记(书签)。
图3-22 为表映射关系标记用于制作镜像的表捕获点
其状态由刷新变为活动。
(2)开启反向预订连续镜像,如图3-23所示。
图3-23 开启反向预订的连续刷新镜像复制
单击“确定”按钮后,反向预订状态会直接进入“制作连续镜像”,跳过全量刷新阶段。
(3)启动应用程序,并完成统计信息收集与程序包绑定。
此时,商业汇票系统数据库已成功切换至x86服务器,可以直接启动新应用程序集群,开始业务验证。这时,在x86数据库产生的增量事务可以通过CDC反向预订复制回AIX数据库中。
然后,对相关业务表做统计信息收集。
手工重新绑定工具程序包。
db2rbind bms_dev -l /tmp/rebindlogfile.out all
以上针对商业汇票系统的主要迁移过程都已介绍完毕。在数据库平滑迁移方案中,针对CDC的应用,在本章介绍内容有限,限于篇幅的原因,读者可以在实际使用过程中查看IBM官方文档。
https://www.ibm.com/support/knowledgecenter/en/SSTRGZ_11.4.0/com.ibm.idr. frontend.doc/pv_welcome.html