随着应用系统的不断发展,我们对数据的依赖也与日俱增,无论银行机构,企事业单位还是政府机关,数据库蔓延在世界上的各个行业。但数据库具有分布存储的特点,这使得数据的同步问题加倍受到重视,这需要保证快速变化的信息可以在最短时间安全完整地传播。Q Replication 新特性 Rename Column 解决了对列重命名操作复制支持的问题,确保了交易的完整性以及效率,满足了在大数据时代对数据复制提出的新需求。
从 DB2 V9 版本起,Q Replication 增强了对源表 Rename column 的支持,该特性实现了对列名重命名 DDL 操作单向、双向的复制,其目标端包括复制到用户表,存储过程,CCD,支持对各种数据类型、主键/非主键列以及表达式的重命名。
该新特性可以通过对新参数 REPL_RENAMECOL 的设置,控制执行 rename column 的复制操作,实现按需求对列名重命名的同步。
在用户 sub 订阅完成后,Q CAPTURE 将会自动捕获在源表进行的重命名操作,Q APPLY 将会根据 REPL_RENAMECOL 响应请求。
在新业务需求中,Q 复制将能够利用 rename column 这一新特性完成对列名重命名的复制,可以解决实际业务中用户表列名不断变化的现实问题,扩大了数据复制的宏观意义。
应用表明,通过使用 rename column 新特性,可以满足用户不断更新列名的需求,简化了以往重建用户表以及映射关系的流程,避免了因业务的变化而造成数据复制的障碍,使数据复制可以以更简便的方式完成,在信息同步操作的应用中起到了重要的意义。
回页首
当执行 rename column 操作时,Q Replication 将会按下面的步骤进行:
首先,执行对 subscription 简单的验证,确认订阅的状态是活跃有效的,并且这个被重命名的 column 是一个被订阅的 sub 中的一列。如果验证失败,Q CAPTURE 将会忽略 rename column 操作,sub 的状态也不会更改。如果验证成功,Q CAPTURE 则会将根据重命名语句初始化该列。
然后会更新控制表 IBMQREP_SRC_COLS 的 SRC_COLNAME 列。
最后将 rename column 的信息发布到发送队列中。
根据不同的情景,Q APPLY 会对控制表以及目标表的列名进行不同的处理,见表一
表 1. Q Apply 处理请求情景分类
N.O.# | scenarios | IBMQREP_SRC_COLS column updated | IBMQREP_TRG_COLS column(s) updated | Target table column renamed |
---|---|---|---|---|
1. | Source and target 列名相同 | SRC_COLNAME | SOURCE_COLNAMETARGET_COLNAME | Yes |
2. | Source and target table 列名不相同 | SRC_COLNAME | SOURCE_COLNAME | No |
3. | 目标端 Stored Procedure target | SRC_COLNAME | SOURCE_COLNAME | No |
4. | 目标端具有 SQL expression | SRC_COLNAME | SOURCE_COLNAME 中所有包含源表原列名的值 | No |
5. | 目标端为 CCD 表 | SRC_COLNAME | SOURCE_COLNAME,TARGET_COLNAME (若与 SOURCE_COLNAME 相同),BEF_TARG_COLNAME (若与 SOURCE_COLNAME 相差一个前缀) | Yes, 仅当 TARGET_COLNAME 或者 BEF_TARG_COLNAME 列值更新后 |
当重命名操作在源表上执行之前,源表列名与目标表列名相同时:
重命名操作在源表上执行后,Q APPLY 会更新控制表 IBMQREP_TRG_COLS 的 SOURCE_COLNAME 列值。此时再验证控制表 IBMQREP_TRG_COLS 的原 SOURCE_COLNAME 列值与原 TARGET_COLNAME 列值一致,则会继续更新目标表的列名,变成重命名后的值,并更新控制表 IBMQREP_TRG_COLS 的 TARGET_COLNAME 列值为新列名。
当重命名操作在源表上执行之前,源表列名与目标表列名不同时:
重命名操作在源表上执行后,Q APPLY 仅会更新控制表 IBMQREP_TRG_COLS 的 SOURCE_COLNAME 列值,目标表的列名不会被重命名,控制表 IBMQREP_TRG_COLS 的 TARGET_COLNAME 列值也不会更新。
对于目标端是存储过程的复制,也同样仅更新控制表 IBMQREP_TRG_COLS 的 SOURCE_COLNAME 列值,控制表 IBMQREP_TRG_COLS 的 TARGET_COLNAME 列值也不会更新。
当包目标列中含表达式时,所有在 IBMQREP_TRG_COLS 的 SOURCE_COLNAME 中包含源表原列名的值将被更新。
对于 CCD 表,当原 SOURCE_COLNAME 值与 TARGET_COLNAME 值相同时,Q APPLY 会更新 SOURCE_COLNAME 列值以及 TARGET_COLNAME 列值;当原 SOURCE_COLNAME 值与 TARGET_COLNAME 值仅相差一个前缀,值的其他部分相同时,Q APPLY 会更新 SOURCE_COLNAME 列值以及 BEF_TARG_COLNAME 列值,同时目标表的列名也会被重命名。
为支持 Rename Column 新特性,将会在控制表 IBMQREP_TARGETS 中增加一个 sub 级的新列 REPL_RENAMECOL=Y/N,来控制 rename 操作是否被复制。
意为当源端与目标端的原列名都相同时,Q Apply 将会重命名目标端列名。其他情况可以根据表一的情景做相应处理。
表示 Q Apply 将不会重命名目标端列名。同时将产生一个警告消息,告知目标列没有重命名。
前提及操作:源表和目标表的原列名相同,重命名源表列名。
结果:相应的 sub 在控制表中的相关信息会更新,目标端列名也将会更新。
步骤 1. 建源表和目标表。
清单 1. 建源表和目标表
#SRC/TRG Table #basic table CREATE TABLE T1 ( C0_CHAR8 CHAR(8) NOT NULL WITH DEFAULT, C1_INTEGER INTEGER NOT NULL WITH DEFAULT, C2_CHARACTER CHARACTER(10) NOT NULL WITH DEFAULT, C3_DATE DATE NOT NULL, C4_SMALLINT SMALLINT NOT NULL WITH DEFAULT, C5_DECIMAL DECIMAL(10,1) NOT NULL WITH DEFAULT, PRIMARY KEY C0_CHAR8 );
步骤 2. 创建建 sub,并设置确认控制表 IBMQREP_TARGETS 中 REPL_RENAMECOL=Y。
步骤 3. 启动 Q Capture 和 Q Apply。
步骤 4. 运行一个简单 workload 验证复制可以正常进行。
清单 2. 验证 workload
INSERT INTO T1 VALUES('888', 888, 'CHARACTER','2014-01-01', 300, 100.1);
步骤 5. 重命名源表的列 C2_CHARACTER
清单 3. 重命名列 C2_CHARACTER
ALTER TABLE T1 RENAME COLUMN C2_CHARACTER TO RECOL1;
步骤 6. 验证控制表 IBMQREP_SRC_COLS 和 IBMQREP_TRG_COLS 都已经被更新。
清单 4. 验证控制表更新
SELECT * FROM IBMQREP_SRC_COLS WHERE SRC_COLNAME='RECOL1'; SELECT * FROM IBMQREP_TRG_COLS WHERE SOURCE_COLNAME='RECOL1'; SELECT * FROM IBMQREP_TRG_COLS WHERE TARGET_COLNAME='RECOL1';
步骤 7. 验证目标表列名跟更成新列名。
清单 5. 验证目标表列名
SELECT * FROM SYSIBM.SYSCOLUMNS WHERE TBNAME='T1' AND NAME='RECOL1'; SELECT RECOL1 FROM TRG.T1 ;
步骤 8. 再次运行一个 workload,验证复制可以在重命名后正常进行。
清单 6. 验证复制正常
INSERT INTO T1 VALUES('999', 888, 'CHARACTER','2014-01-01', 300, 100.1);
步骤 9. 验证 logASN 信息。
前提及操作:源表和目标表的原列名不同,重命名源表列名。
结果:控制表 IBMQREP_TRG_COLS 的 SOURCE_COLNAME 列值信息会更新,但 TARGET_COLNAME 值不会更新,目标端列名将不会更新。
步骤 1. 建源表和目标表,源表的列为 C2_SOURCE,目标表列为 C2_TARGET。
清单 7. 建源表
#SRC #basic table CREATE TABLE T1 ( C0_CHAR8 CHAR(8) NOT NULL WITH DEFAULT, C1_INTEGER INTEGER NOT NULL WITH DEFAULT, C2_SOURCE CHARACTER(10) NOT NULL WITH DEFAULT, C3_DATE DATE NOT NULL, C4_SMALLINT SMALLINT NOT NULL WITH DEFAULT, C5_DECIMAL DECIMAL(10,1) NOT NULL WITH DEFAULT, PRIMARY KEY C0_CHAR8 );
清单 8. 建目标表
#TRG Table #basic table CREATE TABLE T1 ( C0_CHAR8 CHAR(8) NOT NULL WITH DEFAULT, C1_INTEGER INTEGER NOT NULL WITH DEFAULT, C2_TARGET CHARACTER(10) NOT NULL WITH DEFAULT, C3_DATE DATE NOT NULL, C4_SMALLINT SMALLINT NOT NULL WITH DEFAULT, C5_DECIMAL DECIMAL(10,1) NOT NULL WITH DEFAULT, PRIMARY KEY C0_CHAR8 );
步骤 2. 创建建 sub,并设置确认控制表 IBMQREP_TARGETS 中 REPL_RENAMECOL=Y。启动 Q Capture 和 Q Apply 后,. 运行一个简单 workload 验证复制可以正常进行,同清单 2。
步骤 3. 重命名源表的列 C2_CHARACTER。
清单 9. 重命名源表 C2_SOURCE 列
ALTER TABLE T1 RENAME COLUMN C2_SOURCE TO RECOL1;
步骤 4. 验证控制表 IBMQREP_SRC_COLS 的 SRC_COLNAME 列和控制表 IBMQREP_TRG_COLS 的 SOURCE_COLNAME 列值都已经被更新成 RECOL1。
清单 10. 验证控制表更新
SELECT * FROM IBMQREP_SRC_COLS WHERE SRC_COLNAME='RECOL1'; SELECT * FROM IBMQREP_TRG_COLS WHERE SOURCE_COLNAME='RECOL1';
步骤 5. 验证控制表 IBMQREP_TRG_COLS 的 TARGET_COLNAME 列值未被更新,见清单 11。
清单 11. 列 TARGET_COLNAME 更新结果
SQL> SELECT TARGET_COLNAME FROM IBMQREP_TRG_COLS WHERE SOURCE_COLNAME='RECOL1'; TARGET_COLNAME --------------- C2_TARGET
步骤 6. 目标表列名结果验证,未更新成功。
清单 12. 验证目标表列名
db2 => SELECT * FROM SYSIBM.SYSCOLUMNS WHERE TBNAME='T1' AND NAME='RECOL1'; 0 record(s) selected.
步骤 7. 更新 sub 相应信息和目标表列名。
清单 13. 手动更新
UPDATE IBMQREP_TRG_COLS SET TARGET_COLNAME='RECOL1' WHERE SOURCE_COLNAME='RECOL1'; SELECT * FROM IBMQREP_TRG_COLS WHERE TARGET_COLNAME='RECOL1'; ALTER TABLE SCHEMA.T1 RENAME COLUMN C2_TARGET TO RECOL1; SELECT RECOL1 FROM SCHEMA.T1 ;
步骤 8. 再次运行一个 workload,验证复制可以在重命名后正常进行。
前提及操作:目标端为存储过程,重命名源表列名。
结果:控制表 IBMQREP_TRG_COLS 的 SOURCE_COLNAME 列值信息会更新,但 TARGET_COLNAME 值不会更新。
步骤 1. 创建源表
清单 14. 创建源表
#SRC Table CREATE TABLE T1 ( C1 INT NOT NULL, C2 INT NOT NULL, C3 INT, PRIMARY KEY(C1) )
步骤 2. 创建目标端存储过程
清单 15. 创建存储过程
CREATE PROCEDURE BASICSP ( INOUT operation INT, IN SUPPRESSION_IND VARCHAR(90), IN SRC_COMMIT_LSN VARCHAR(16) FOR BIT DATA, IN SRC_TRANS_TIME TIMESTAMP, IN XC1 INT, IN C1 INT) LANGUAGE SQL BEGIN NOT ATOMIC DECLARE count INT; DECLARE while_count INT default 0; DECLARE max_count INT default 0; SELECT max(C1) into max_count from OEUSR01.T1; if max_count is null then set max_count=0; end if; SET count = C1; WHILE (count > 0) DO SET while_count = while_count + 1; INSERT INTO OEUSR01.T1 VALUES (max_count+while_count,repeat('A',4),repeat(' A',4),repeat ('A',4),max_count+while_count); set count = count -1; if mod(max_count+while_count,1000) = 0 then commit; end if; END WHILE ; COMMIT; END%
步骤 3. 创建建 sub,并设置确认控制表 IBMQREP_TARGETS 中 REPL_RENAMECOL=Y。
清单 16. 创建 sub
点击查看代码清单
关闭 [x]
CREATE QSUB USING REPLQMAP QMAP1 ( SUBNAME QSUB1 OEUSR01.T1 EXIST TARGET NAME OEUSR01.BASICSP TYPE STOREDPROC);
步骤 4. 启动 Q Capture 和 Q Apply。
步骤 5. 对源表列进行 rename column。
清单 17. 重命名
ALTER TABLE OEUSR01.T1 RENAME COLUMN C2 TO RECOL;
步骤 6. 控制表值的验证
清单 18. 验证控制表更新
SELECT * FROM IBMQREP_SRC_COLS WHERE SRC_COLNAME='RECOL'; SELECT * FROM IBMQREP_TRG_COLS WHERE SOURCE_COLNAME='RECOL';
步骤 7. 验证控制表 IBMQREP_TRG_COLS 的 TARGET_COLNAME 列值未被更新,见清单 19。
清单 19. 列 TARGET_COLNAME 更新结果
SQL> SELECT TARGET_COLNAME FROM IBMQREP_TRG_COLS WHERE SOURCE_COLNAME='RECOL'; TARGET_COLNAME --------------- C2
前提及操作:目标端为 CCD 表,重命名源表列名。
结果:控制表 IBMQREP_TRG_COLS 的 SOURCE_COLNAME 列将更新,TARGET_COLNAME/ BEF_TARG_COLNAME 列值将根据不同情景进行不同处理。
步骤 1. 创建源表
清单 20. 创建源表
#SRC Table #basic table including all kinds of data type CREATE TABLE T1 ( "C0" CHAR(8) NOT NULL WITH DEFAULT, "C1" CHAR(6) NOT NULL WITH DEFAULT, "C2" CHARACTER(10) NOT NULL WITH DEFAULT, "C3 NOT NULL WITH DEFAULT, PRIMARY KEY C0 );
步骤 2. 创建建 sub,并设置确认控制表 IBMQREP_TARGETS 中 REPL_RENAMECOL=Y。
清单 21. 创建 sub
CREATE QSUB USING REPLQMAP QMAP1 (SUBNAME QSUB1 OEUSR01.T1 OPTIONS HAS LOAD PHASE I TARGET NAME OEUSR01.T2 IN DB DEFUSRDB T2 TYPE CCD CONDENSED ON COMPLETE ON WITH UOW COLS ALL TRGCOLS ALL BEFORE IMAGE COLUMNS PREFIX "X" ALL); QUIT;
步骤 3. 启动 Q Capture 和 Q Apply。
步骤 4. 对源表列进行 rename column。
清单 22. 重命名
ALTER TABLE OEUSR01.T1 RENAME COLUMN C3 TO RECOL;
步骤 5. 控制表值的验证,都已被更新成 RECOL。
清单 23. 验证控制表更新
SELECT * FROM IBMQREP_SRC_COLS WHERE SRC_COLNAME='RECOL'; SELECT * FROM IBMQREP_TRG_COLS WHERE SOURCE_COLNAME='RECOL'; SELECT * FROM IBMQREP_TRG_COLS WHERE BEF_TARG_COLNAME='XRECOL';
步骤 6. 验证目标表列已被更新成 RECOL。
清单 24. 目标端结果更新
SELECT * FROM SYSIBM.SYSCOLUMNS WHERE TBNAME='T2' AND NAME='RECOL'; SELECT RECOL1 FROM OEUSR01.T2 ;
前提及操作:目标端列由表达式组成,重命名源表列名。
结果:控制表 IBMQREP_TRG_COLS 中,所有包含 rename 列名的 SOURCE_COLNAME 列将被更新。
步骤 1. 创建源表
清单 25. 创建源表
#SRC Table #basic table including all kinds of data type CREATE TABLE T1 ( "C1" CHAR(8) NOT NULL WITH DEFAULT, "C2" CHAR(6) NOT NULL WITH DEFAULT, PRIMARY KEY C1 ); #TRG Table #basic table including all kinds of data type CREATE TABLE T1 ( "C1" CHAR(8) NOT NULL WITH DEFAULT, "C2" CHAR(6) NOT NULL WITH DEFAULT, "EXPC3" CHARACTER(10) NOT NULL WITH DEFAULT, PRIMARY KEY C1 );
步骤 2. 创建建 sub,并设置确认控制表 IBMQREP_TARGETS 中 REPL_RENAMECOL=Y。
清单 26. 创建 sub
CREATE QSUB USING REPLQMAP REPLQMAP1(SUBNAME QSUB1 SRC.T1 EXIST TARGET NAME TRG.T1 TRGCOLS INCLUDE (C1,C2) EXPRESSION ("CONCAT(:C1,:C2)" TARGET EXPC3));
步骤 3. 启动 Q Capture 和 Q Apply。
步骤 4. 对源表列进行 rename column。
清单 27. 重命名
ALTER TABLE OEUSR01.T1 RENAME COLUMN C2 TO RECOL;
步骤 5. 控制表值的验证,都已被更新成 RECOL。
清单 28. 验证控制表相关表达式值被更新
SELECT * FROM IBMQREP_SRC_COLS WHERE SRC_COLNAME='RECOL'; SELECT * FROM IBMQREP_TRG_COLS WHERE SOURCE_COLNAME LIKE '%RECOL%';
控制表 IBMQREP_TRG_COLS 的 source_colname 中不存在源表的原列名,Q APPLY 将会返回 SQLCODE: +100 的报错。LOG 中出现 ASN7829E 的报错。
清单 29.APPLY TRACE 查询
SELECT * FROM SCHEMA.IBMQREP_APPLYTRACE WHERE DESCRIPTION LIKE '%ASN7829E%';
回页首
到目前为止,Rename Column 新特性可以在 Q Replication V1021 上运行,但仅支持 Z 平台到 Z 平台,并要求 DB2 V9 数据库以及以上版本的复制操作。在订阅种类上,可以支持单项和双向复制,但不支持 P2P 复制。
回页首
Q Replication 这一新特性增加了对列名重命名的支持,使数据复制的内涵更为广泛更为丰富,不但可以对目标端的用户表列名进行重命,还可以拓展到能够以存储过程为目标端,以 CCD 表为目标表,以及订阅中有表达式的各种情景。
通过以上对 Rename Column 新特性的介绍,读者可以更深刻地理解新特性的机制原理以及使用方法。在实际应用中,它解决了一直困扰用户的无法对列名数据进行更新和同步的问题,扫除了复制的局限性,在信息复制和数据同步中具有里程碑的意义。
回页首