需求背景
ip | os&cpu | 数据库 版本 | 数据库 端口 | 数据库和 用户名 | |
源端 | 172.21.142.39 172.21.140.40 172.21.140.41
| Kylin-Server-V10-SP3 Kunpeng-920 | KES V8R6 集群 兼容oracle 区分大小写 | 54321 | 数据库:topicisnew 用户名密码:topicis/topnet 模式名:topicis |
目标端 | 172.21.140.66 172.21.140.53 172.21.140.54 | Kylin-Server-V10-SP3 Kunpeng-920 | KES V8R6 集群 兼容oracle 区分大小写 | 54321 | 数据库:hzknew 用户名密码:topicis/topicis 模式名:topicis |
KDTS | 172.21.142.39 | Kylin-Server-V10-SP3 Kunpeng-920 | 账号密码:kingbase/Kb_DI@2019 | ||
KFS | 172.21.140.34 | Kylin-Server-V10-SP3 Kunpeng-920 | HA | 源端同步服务名称:source_ywtohz_5112 目标端同步服务名称:target_ywtohz_5114 | 元信息库:console 比对库:compare 用户名密码:system/12345678ab |
拓扑图

实现过程
存量数据迁移
确保KFS源端同步服务配置文件参数
源端flysync.ini中务必配置以下参数:
property=replicator.extractor.dbms.autoIdentity=full如果没有,建议offline服务,增加参数后再online服务
--offline源端服务
fsrepctl -service source_ywtohz_5112 offline
--更新flysync.ini配置
cd /home/kfs/replicator/releases/KingbaseFlySync-V002R002C004PS002-replicator_pid1402320/tools/fspm
./fspm update
--online源端服务
fsrepctl -service source_ywtohz_5112 online确保KFS源端同步服务online
定位到源端同步服务名称
查看KFS服务器上的所有同步服务,定位到源端同步服务名称
--查看KFS服务器上的所有同步服务,定位到源端同步服务名称
[kfs@01 ~]$ fsrepctl services
Processing services command...
NAME VALUE
---- -----
appliedLastSeqno: 30917
appliedLatency : 0.0
role : master
serviceName : m_syjk
serviceType : local
started : true
state : ONLINE
NAME VALUE
---- -----
appliedLastSeqno: 30917
appliedLatency : 0.0
role : slave
serviceName : s_syjk
serviceType : local
started : true
state : ONLINE
NAME VALUE
---- -----
appliedLastSeqno: -1
appliedLatency : -1.0
role : master
serviceName : source_ywtohz_5112 --源端同步服务名称
serviceType : unknown
started : true
state : ONLINE
NAME VALUE
---- -----
appliedLastSeqno: -1
appliedLatency : -1.0
role : slave
serviceName : target_ywtohz_5114 --目标端同步服务名称
serviceType : unknown
started : true
state : ONLINE
Finished services command...确保KFS源端同步服务online
一定要执行,并且只启动源端,如果已经是online则省略该步骤
fsrepctl -service source_ywtohz_5112 online检查KFS日志
检查kfs日志,不再出现alter table xx replicate identity full为止。
cd /home/kfs/replicator/flysync/flysync-replicator/log
tail -300f fsrepsvc-source_ywtohz_5112.log查询数据库中已创建的复制槽
查询数据库中创建的复制槽,并记录数据库中创建好的复制槽名称。
su - kingbase
ksql -Utopicis topicisnew
select slot_name,plugin,database from sys_replication_slots;输出如下:
topicisnew=# select slot_name,plugin,database from sys_replication_slots;
slot_name | plugin | database
-------------------------------------+-------------+------------
repmgr_slot_2 | |
repmgr_slot_3 | |
source_ywtohz_5112_kfs_logical_slot | decoderbufs | hzknew
(3 rows)扩展:
--删除一个指定的复制槽
select * from sys_drop_replication_slot('source_ywtohz_5112_kfs_logical_slot');
--创建一个指定的复制槽
select sys_create_physical_replication_slot('source_ywtohz_5112_kfs_logical_slot');离线KFS源端和目标端同步服务
离线KFS源端同步服务
--离线KFS源端同步服务
fsrepctl -service source_ywtohz_5112 offline
--查看KFS源端同步服务状态
fsrepctl -service source_ywtohz_5112 status离线KFS目标端同步服务
--离线KFS源端同步服务
fsrepctl -service target_ywtohz_5114 offline
--查看KFS源端同步服务状态
fsrepctl -service target_ywtohz_5114 statusKFS源端和目标端服务执行重置命令
将源端 KFS 离线(offline),源端和目标端 KFS 同时执行 reset 命令,确认中间表、kufl 文件、复制槽等被删除。
reset命令会删除复制槽和中间表的kufl,不要手动删除复制槽。
KFS源端同步服务执行重置命令
fsrepctl -service source_ywtohz_5112 reset -all -yKFS目标端同步服务执行重置命令
fsrepctl -service target_ywtohz_5114 reset -all -y源端kes数据库创建复制槽和快照
源端kes数据库加上创建复制槽,复制槽名称为上面的查询的复制槽名;
不支持创建快照的KES版本有:V8R3和不支持CSN的V8R6(KingbaseES V008R006C005B0023以下版本)
连接数据库
注意:连接的数据库必须是要迁移的逻辑库,此处使用了一种特殊的连接数据库方式
ksql -d "host=172.21.140.39 user=topicis password=topnet replication=database dbname=topicisnew port=54321"手动创建复制槽并生成对应的快照
select sys_create_physical_replication_slot(source_ywtohz_5112_kfs_logical_slot) logical decoderbufs;开启事务
topicisnew=# begin;
BEGIN设置事务隔离级别
topicisnew=# set transaction_isolation to "repeatable read";
SET手动创建复制槽和快照
手动创建复制槽,导出快照。两个语句在同一行执行,用分号隔开。
注意:
1、此处的复制槽名称为查询源库已创建记录的复制槽名称。此处有风险,如果在create复制槽的同时有数据生成,可能会有丢失
2、记录查出来的快照名称
3、不要关闭事务,也不要退出ksql连接,一旦退出快照就没了。如果xshell自动断开则后台创建快照。
场景1:会话不存在不定时自动断开
select sys_create_logical_replication_slot('source_ywtohz_5112_kfs_logical_slot', 'decoderbufs');select sys_export_snapshot();场景2:会话存在不定时自动断开
对通过VPN+堡垒机访问服务器的服务器来讲,有些存在长时间不操作,xshell或其他工具访问服务器操作存在不定时断开的情况。
在kes源端创建保持会话活动的存储过程
```bash
su - kingbase
ksql -Usystem topicisnew
-- 创建保持活跃的存储过程
CREATE OR REPLACE PROCEDURE keep_session_alive(
interval_seconds INT DEFAULT 60, -- 间隔时间(默认60秒)
max_loops INT DEFAULT 0 -- 循环次数(0表示无限循环)
)
AS $$
DECLARE
loop_count INT := 0;
BEGIN
RAISE NOTICE '会话保活程序已启动,间隔时间:%秒,循环次数:%',
interval_seconds,
CASE WHEN max_loops = 0 THEN '无限' ELSE max_loops::TEXT END;
-- 循环逻辑
LOOP
-- 执行轻量级查询保活
PERFORM 1; -- 等效于 SELECT 1,但无需返回结果
-- 更新计数器
loop_count := loop_count + 1;
-- 达到指定次数后退出(max_loops=0时无限循环)
IF max_loops > 0 AND loop_count >= max_loops THEN
RAISE NOTICE '已达到最大循环次数,退出。';
EXIT;
END IF;
-- 等待指定间隔
PERFORM pg_sleep(interval_seconds);
END LOOP;
END;
$$ LANGUAGE plpgsql;
```在KES数据库服务器上创建shell脚本,执行创建复制槽和快照
su - kingbase
vi kes_export_snapshot.sh
#添加以下内容
source ~/.bash_profile
echo "KES创建快照和复制槽"
ksql -Usystem topicisnew <<EOF
begin;
set transaction_isolation to "repeatable read";
select sys_create_logical_replication_slot('source_ywtohz_5112_kfs_logical_slot', 'decoderbufs');select sys_export_snapshot();
CALL keep_session_alive(60, 1000);--前面是间隔几秒循环一次,后面是循环次数,0是永远在循环,两者相乘就是这个会话可以保持多少时间。
end;
EOF
echo "已退出会话!"赋予脚本加上可执行权限
chmod +x kes_export_snapshot.sh后台执行脚本
特别注意:脚本执行必须在源端同步服务做完reset后
nohup ./kes_export_snapshot.sh &查看创建的快照号
在nohup.out文件中查看创建的快照号
cat nohup.out
KES创建快照和复制槽
BEGIN
SET
INFO: Exiting startup callback
sys_create_logical_replication_slot
-------------------------------------------
(m_kes_3114_kfs_logical_slot,25/B23E2030)
(1 row)
sys_export_snapshot
---------------------
00000006-0001231D-1
(1 row)KDTS工具使用 00000006-0001231D-1 这个快照号做不停机迁移。
使用KDTS指定快照进行迁移
注:不停机迁移过程中,不支持DDL变更;如果需要DDL变更,需要在不停机迁移前或不停机迁移完成后进行

增量数据同步
启动KFS源端同步服务
这一步可以在迁移存量数据时同时进行。KFS源端服务online时不需要指定快照名,因为上面手动创建的复制槽已经包括指定快照了。
fsrepctl -service source_ywtohz_5112 online启动KFS目标端同步服务
等上面KDTS迁移完存量数据,再启动KFS目标端服务
fsrepctl -service target_ywtohz_5114 online手工数据核对
为了以列表式查看源端和目标端每个表记录数,可使用以下脚本进行统计。
配置数据库免密访问
sys_encpwd -H \* -P \* -D \* -U topicis -W topnet
--参数说明
-H: \* 所有主机名或ip
-P: \* 所有端口
-D: \* 所有数据库
-U: 用户名
-W: 密码更改数据统计脚本
更改内容如下:
- DB_NAME="hzknew" --数据库名
- DB_USER="topicis" --用户名
- TABLES=( ) --括号中的表名需要改,表名用双引号括上。如果表归属在默认的public模式下,可省略模式名只写表名;不然需在表名前加上模式前缀。
- ksql -d hzknew -U topicis --更改数据库名和用户名
vi kfscount.sh
#!/bin/bash
# 需要统计的表名数组
TABLES=(
"topicis.A"
"topicis.A_ORGAN"
"topicis.A_USER"
"topicis.CODE_BLICTYPECODE"
"topicis.CODE_CAUTITEM"
"topicis.CODE_IDEN_TYPE"
"topicis.DD2_AJ_AJXX"
"topicis.ECPS_CUSTOM_TAXRELIEFGOODS"
"topicis.ECPS_ENTYEAREXAMALTINFO"
"topicis.ECPS_ENTYEAREXAMINFO"
"topicis.ECPS_INTELLECTUALRIGHTS"
"topicis.ECPS_LATEPAYMENT_HIST"
"topicis.ECPS_REGISTRATION_HIST"
"topicis.ECPS_UPDATEINFO_2013"
"topicis.ECPS_WEBSIT"
"topicis.ICIS_EASY_LOGOUT_RESULT"
"topicis.LAW_SENDCER"
"topicis.LOG_REMOTEPUSH"
"topicis.LS_DGDYW"
"topicis.PUB_CLYQUALI"
"topicis.REG_ALTENTTYPEAUDITINFO"
"topicis.REG_BATJOIEXCAUD"
"topicis.REG_BUSLICENCE"
"topicis.REG_CUSTOMAGEREGCERTUNITE"
"topicis.REG_CUSTOMPUSHINFO"
"topicis.REG_ENTACTINFOXML"
"topicis.REG_ENTACTINFOXML_INV"
"topicis.REG_ENTADDR"
"topicis.REG_EXCPARTNER"
"topicis.REG_FORCECANCELNOTICEINFO"
"topicis.REG_FORINVENTBUSRECMEM"
"topicis.REG_FORINVENTBUSRECPRO"
"topicis.REG_IMITATENAMERECINFO"
"topicis.REG_INDSIMCANREVOKEINFO"
"topicis.REG_INTPLACTINF"
"topicis.REG_LEGREPRE_HIST"
"topicis.REG_LICENSEISSUEINFO"
"topicis.REG_LIQUIDATION"
"topicis.REG_MANAGER_HIST"
"topicis.REG_MARPRIPAUDITINFO"
"topicis.REG_MARPRIPCANAUDITINFO"
"topicis.REG_MARPRIPEXTINFO"
"topicis.REG_MARPRIPINFO"
"topicis.REG_MARPRIPINFO_EXT_INV"
"topicis.REG_MARPRIPINFO_HIST"
"topicis.REG_MARPRIPINFO_INV"
"topicis.REG_MOVEIN"
"topicis.REG_NAMEPREAPPR"
"topicis.REG_NETREGINFOACC"
"topicis.REG_PARENTENT"
"topicis.REG_PREPACKFOODINFOUNITE_TEMP"
"topicis.REG_PROJECTNO"
"topicis.REG_REDREGCAP"
"topicis.REG_REVISEACCITEM"
"topicis.REG_REVOCINFO"
"topicis.REG_THIRDCOLDSTORAGEINFO"
"topicis.SIS_ICAUTIOUSTORE_F"
"topicis.SIS_PUNPDFSBJL_QS"
"topicis.SMALL_MARPRIPINFO"
"topicis.SMALL_MARPRIPINFO_ITEM"
"topicis.STD_E_PUB_SPOTCHECK"
"topicis.SUP_APPLYREPAIRPUNINFO"
"topicis.SUP_BLACK"
"topicis.SUP_BRAND"
"topicis.SUP_BRANDIMAGE"
"topicis.SUP_DOMASS"
"topicis.SUP_ENTBLACK"
"topicis.SUP_NONPUBPARBUI_INV"
"topicis.SUP_OPERABNLISTCACEL"
"topicis.SUP_OPERABNORMALACC"
"topicis.SUP_OPERABNORMALLIST"
"topicis.SUP_REPCLA"
"topicis.SUP_TRADACTPER"
"topicis.SUP_TRADLAWINFO" # 支持带schema的表
)
# 遍历统计
for TABLE in "${TABLES[@]}"; do
# 执行查询并提取结果
COUNT=$(ksql -d hzknew -U topicis -c "SELECT COUNT(*) FROM $TABLE;" | awk '/^[[:space:]]*[0-9]+[[:space:]]*$/{print $1}')
# 结果格式化输出
echo "${TABLE}:" "$COUNT"
done执行数据统计脚本
分别在KFS源端和目标端库中执行。
sh kfscount.sh > result39.txt
sh kfscount.sh > result66.txt将结果文件result39.txt 、result66.txt 下载下来通过Notepad比对工具进行比对。
致谢
该案例特别感谢金仓技术人员郑金枢、包忠鑫老师的给力支持。




