前言
做过替换项目的朋友,咱先对个暗号:切换那晚你睡了几个小时?
我猜没睡。多半盯着两边的对账脚本,一边盯一边念经,就怕屏幕上蹦红色。这种状态其实不对,说难听点,靠人肉熬出来的"平滑迁移",运气成分占一半。
工具选型那会儿多热闹啊,POC跑分、参数对比,谁都能上来聊两句。真到要动生产库,会议室立马没声。存量几个TB,业务7×24不让停,领导再补刀一句"出了问题要能退回去",三座山压下来,靠半夜写脚本搬数据?得了吧。
这篇就聊切换这一件事。主角还是电科金仓的KFS(Kingbase FlySync),数据集成软件里干实时同步的。它平时的同步原理之前写过了,这次口径收窄:数据怎么不停着业务追平、双轨并行怎么留后路、割接当晚该盯什么。都是实操层面的事。
换库这事,难的不是选库
方案评审能磨几个月,最后栽在哪?切换窗口上。
先说存量。TB级的历史数据摆在那,老一套导出导入,几个小时下不来,窗口根本申请不下来。业务方一句"影响营收",方案直接打回去重做。
业务停不停得起,是另一码事。医院、政务、金融这些行业,7×24不是写在PPT里的词,是真有人凌晨三点在刷卡挂号。你跟人家商量停机两小时,对面回一句"急诊怎么办",这话就没法接了。
最阴险的其实是第三件:切过去不稳怎么办。新库上线头一周抖两下,太正常了。可只要没退路,每个小毛病都会被上纲上线,最后背锅的还是实施团队。搁谁都虚。
三个坎,解法其实是同一个:让新老两套库在一段时间里数据实时一致,想切就切,想退就退。这话听着像口号,落到实处就是一根同步管道。金仓的迁移方案里,KFS干的就是这个,跟搬存量数据的迁移工具搭伙干活。
全量和增量,怎么接力
原理不讲透,后面照着文档点鼠标心里也是虚的。
先记一个词,SCN。Oracle这边这么叫,金仓数据库那边叫LSN。名字不用纠结,把它当数据流水的"书签号"就行,每来一笔变更,号就往前挪一格。迁移的全部秘密,就是围着这个书签号做接力。
头一步搬骨架。KDMS评估工具上场,表结构、约束这些先挪到金仓数据库。类型怎么映射、语法差异怎么消化,都在这一层处理掉,不然数据搬过去也住不进去。
骨架好了搬存量。KDTS从某个SCN快照点开始抄数据。有意思的来了:这一步不设时限,抄多久都行。为啥不怕抄着抄着数据变旧了?
因为还有股暗流在同时干活。全量刚一启动,KFS就在源端从同一个书签号往后解析日志,这期间业务新产生的增删改,全被它抓下来,存在自己节点上。存量抄十个钟头,它就记十个钟头,互不干扰,业务那边毫无感觉。
存量搬完,收网。KFS把攒着的增量灌进新库,两边的书签号一点点逼近,追平那一刻,才需要短暂停一下应用,把JDBC从老库改指新库,重启。完事。
品出味道没?真正要停机的就最后那一小截,追平加改连接。这段时长跟存量多大没关系,只看最后剩多少增量。所以TB级的项目,停机能压到小时级,甚至分钟级。北京一卡通清结算,12.3TB存量、日增500GB,全程不到3天迁完。嘉实基金的TA系统,60TB,业务切换30分钟搞定。
60TB啊,朋友。
先摸底,别急着装软件
稳的项目,第一步都是摸底。三个数:存量多大,表多少,多少表没主键。
sql
-- 存量数据量,决定全量搬迁要排多长的窗口
SELECT round(sum(bytes)/1024/1024/1024, 2) AS size_gb
FROM dba_segments
WHERE owner IN ('BIZ', 'BIZ_HIS');
-- 表数量与行数概览
SELECT count(*) AS tbl_cnt,
round(sum(num_rows)/10000, 1) AS rows_wan
FROM dba_tables
WHERE owner = 'BIZ';
-- 揪出没有主键的表,重点照顾对象
SELECT t.table_name
FROM dba_tables t
LEFT JOIN dba_constraints c
ON c.owner = t.owner AND c.table_name = t.table_name
AND c.constraint_type = 'P'
WHERE t.owner = 'BIZ' AND c.constraint_name IS NULL
ORDER BY t.table_name;
前两个数不用解释。第三个为啥要单独盯?
没主键的表,是同步链路里的钝刀子。Update和Delete过来,没主键可以定位行,只好全列匹配,慢。一张两张无所谓,几百张堆一块,整条链路的延迟就被拖得很难看。
KFS是能同步无主键表,功能有。但现场更稳的玩法是分流:带大对象的、日变更十万行往上的无主键表,单独拆出去,一天同步一次完事,其余照常实时。有个金融客户就这套打法,5000多张表里1200多张没主键,筛完真正走定时的就55张,剩下全实时,延迟趴在1秒以内不动。
55张。分流做不做,链路是两个物种。
归档和附加日志,两个硬前提
走日志解析这条路,源端有两个绕不过去的坎。缺一个,链路要么起不来;要么更吓人,起来了,数据在悄悄丢。
sql
-- 1. 归档模式必须是 ARCHIVELOG,NOARCHIVE 下日志循环覆盖,链路必断
SELECT log_mode FROM v$database;
-- 2. 开归档(要重启生效,放维护窗口做)
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;
-- 3. 库级附加日志
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
-- 4. 同步表补主键附加日志,Update/Delete 靠它定位行
ALTER TABLE biz.orders ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;
归档这事一句就能说明白。增量全在日志里待着,没开归档,日志一循环覆盖,源头就断了,神仙难救。
附加日志倒老有人忘。默认情况下,Oracle记Update只记变化的列,不带主键。同步到对端,一句"把余额改成500",改哪行?没人知道。这就是事故的种子。主键附加日志一补,每条变更自带定位,才谈得上对账。
这套检查建议直接钉死在迁移前置清单里,别指望记性。金仓有配套的评估工具,硬件、软件、网络、数据源一口气扫过去,自动出风险评估报告。嫌手动逐项核对麻烦的,先让工具跑一遍,对着报告补漏,踏实。
三套方案,看菜吃饭
落到实施,KFS的平滑迁移方案已经迭代到第三代。方向一脉相承,差别就一条:对源端打扰多不多。
| 方案 | 思路 | 源端要停机吗 | 加不加硬件 | 谁用合适 |
|---|---|---|---|---|
| 1.0 中间库 | 临时节点先备份还原,再全量加增量 | 短暂停一下 | 得加台临时服务器 | 环境紧、想省事的 |
| 2.0 半无感 | 按SCN全量搬,KFS直接追增量 | 分钟级,存量再大也这样 | 不用 | 大多数项目的主力 |
| 3.0 全无感 | 先攒增量再搬全量,水位线自动合拢 | 一秒都不停 | 不用 | 根本没窗口的核心系统 |
3.0的巧劲值得多唠两句。它把顺序倒过来了:先把增量解析攒着,回头再做全量,最后拿高低水位线自动校验合拢,冲突数据自动消化,连SCN都不用提前取,整体时间还能再省三成左右。临时节点、备份还原全省了,顺带省一笔硬件钱。
双轨并行,后悔药得备着
方案再顺,业务方心里那道坎还在:切过去万一不稳呢。
所以才需要双轨并行这味药。
| 阶段 | 谁扛业务 | 数据往哪流 | 出幺蛾子了 |
|---|---|---|---|
| 并线运行 | 老库 | 老库 → 新库,实时 | 灰度期嘛,随便看,新库还能搭把手跑查询 |
| 生产割接 | 新库接班 | 新库 → 老库,实时 | 切回去,业务基本无感 |
| 收尾下线 | 新库站稳了 | 反向链路看情况留 | 老库光荣退休 |
关键在第二阶段。割接完,同步方向掉个头,新库的每次变更实时流回老库,等于老库手里始终捏着一份完整又新鲜的数据。新库真抖起来,连接改回去就行,业务几乎没感觉。圈里管这叫后悔药,我觉得挺形象,谁吃谁知道。
药效有实物为证。某邮政银行的OA项目,5TB数据9小时搬完,折下来每分钟9.5GB,之后长期靠KFS反向同步兜底,切换窗口里连并发压测都照做。另外多说一句,多中心互相同步的场景有防回环机制,A流到B的数据不会被B再弹回A,几条链路各干各的,不打架。
还有个容易漏想的:双轨期间,同步链路自己就是生命线。链路一断,后悔药等于过期。KFS用KFS-HA做多实例热备,主同步节点趴了,备节点自动顶上,实测10秒内切完,跨网段检测也支持。两地三中心那种架子,搭得起来。
割接当晚,一笔对账加一张清单
先泼冷水。没演练过的割接方案不叫方案,叫抽奖。回退至少完整走一遍,走不通的回退比没有还坏,它会给你虚假的安全感。
割接前最后一道工序,对账。道理很朴素,两边各算一遍行数和内容摘要,对上就算齐:
sql
-- 两端各跑一遍,核对行数与内容摘要(Oracle 端示例,dbms_crypto 需授权)
SELECT count(*) AS row_cnt,
sum(dbms_crypto.hash(
utl_raw.cast_to_raw(order_id || '|' || status || '|' || amount),
2)) AS chk_sum
FROM biz.orders
WHERE create_time >= trunc(sysdate) - 1;
不过手工对账有个先天的坑:两边执行有先后,这中间数据还在动,最后对不上,你都不知道赖谁。生产环境我更建议直接用KFS内置的校验,它靠两端快照,先各自拍照,再拿照片对照片,时序问题从根上就没了。查出差异还能自动修,全程不停业务。
当晚的口头清单大致长这样:延迟追平没有?应用停写了没?最后一段增量落库了没?对账跑了吗?JDBC改了吗?应用起了吗?然后盯着延迟曲线半小时再撒手。每个动作旁边写好对应的回退动作,同一张纸,别搞两份。(真建议打印出来贴桌上,凌晨三点的人脑不可靠。)
最后一条经验,值钱的:别一把梭。能分批就分批。前面说的那个金融客户,六大业务模块四套环境,先切2个模块试试水,稳了再切4个,最后全量。每批都有双轨兜着,每批都能单独回退。项目做完,业务方愣是说不出哪天"正式切换"了。
这才叫平滑。别的都是宣传稿。
数据一致性的底气
做到这步,业务方最后一关永远是那句灵魂拷问:你怎么证明两边数据一样。
"应该一样"没人买账。要证据。
KFS把校验修复做成了内置功能,不用另外掏钱。对,国外有款同步工具的校验组件是单收费的,名字就不点了。
数字给几个。在线校验速率100MB/s上下,100GB的数据分钟级出结果;多线程比对能干到每秒25万行,2TB一小时比完。最讨巧的是增量校验,变化数据直接从KFS自己的KUFL中间文件里拿,根本不碰源库。校验这个动作对生产系统几乎零负担,业务高峰照样跑。
看两个真实例子。人民银行征信中心那个融资平台,存量4TB多,原来全表校验一次6个小时起步,改增量校验,10分钟收工。解放军总医院8个院区汇聚的项目,大表带着大对象照样校,98MB/s,校验期间业务库CPU涨了不到3%。
差异查出来怎么办?小问题开全自动修复,它自己补;金贵的表走人工,把差异记录挑出来手动修。告警走邮件、短信、钉钉都行,人不用盯屏。
结尾唠两句
数据库替换,技术含量最高的从来不是哪个单点,是把"切换"这个高危动作,拆成一串能验证、能回退的小步。
KFS这类数据集成软件在里面演什么角色?一根不停歇的水管。全量在抄的时候它在记增量,新库扛业务的时候它在往老库回流,你呼呼大睡的时候它在两头对账。水管之外的那些,摸底、分流、演练、分批割接,拼的还是工程习惯,工具替不了。
要行动建议?行。切之前,把无主键表和附加日志这两颗雷排了;切的时候,双轨留着,别心疼那一台机器;切完了,校验报告存档,那是你下个项目的底气。
换库睡得着觉的秘诀,从来不是胆子大。
是退路多。