前言
国产化替代的项目这些年一波接一波,源头是 SQL Server 的占了不小的比例------ERP、OA、财务,哪个单位都能数出几套。
外行看这活儿简单:数据倒出去,再倒进新库,连接串一改,齐活。真干过一次的人,第二次接这种项目会先叹口气。
因为搬数据恰恰是整套流程里最不值钱的一环,市面上工具一抓一大把。吃工期的从来是另一样东西:SQL Server 里那堆跑了七八年的 T-SQL。几百个存储过程,触发器一层摞一层,报表 SQL 满篇方言。写代码的人走得差不多了,文档就更别指望。这种底子,动一行要回归测试,动一百行,工期和预算一起告急。
后来大家慢慢会看一个信号:SQL Server数据库迁移顺不顺,起决定作用的就是老代码要改多少,别的都好商量。
金仓数据库 V9R4C019 是电科金仓的产品,这一版官方定位就叫"SQL Server 兼容版"。它把迁移这条路铺成了什么样,下面按实际顺序过一遍,先说语法,再说数据搬运,最后聊聊上线之后的保障。
@TOC
一、老代码才是真正的大头
没接触过 SQL Server 老系统的人,很难想象那些业务逻辑藏在哪。不在应用代码里,在数据库里。一个对账需求,开发顺手就写了个 MERGE 存储过程;要留操作痕迹,OUTPUT 子句伺候;月底交叉报表,PIVOT 一转完事;排名汇总,窗口函数包圆。日积月累,数据库里住进了几百个对象,谁也不敢轻举妄动。
这些写法在 SQL Server 里天经地义,挪到别家数据库就不一定买账了。不认 MERGE 怎么办?拆。UPDATE 一段,INSERT 一段,外面再包层事务防并发。改完还不算完,得有人逐条核对逻辑没跑偏------迁移工时里烧钱的大头就在这,报价单上最吓人的数字往往也出在这。
先看个 MERGE 的例子,库存对账:增量表跟库存表碰一下,对得上的累加数量,对不上的直接插入:
sql
MERGE INTO stock AS t
USING stock_delta AS s
ON t.sku = s.sku
WHEN MATCHED THEN
UPDATE SET t.qty = t.qty + s.qty
WHEN NOT MATCHED THEN
INSERT (sku, qty) VALUES (s.sku, s.qty);
一条 SQL 的事。可要是目标库不认这个语法,上面这些就得人肉拆开干,再乘上几百个存储过程的量级,滋味自己体会。
V9R4C019 补的特性里,要紧的这么几个:
| T-SQL 特性 | 什么时候用 | 支持情况 |
|---|---|---|
| MERGE 语句 | 对账:有就更新,没有就插入 | 本版补全 |
| OUTPUT 子句 | 改数据的同时把前后值抓出来 | 本版补全 |
| 并行 DML | 大表批量 UPDATE / DELETE 提速 | 本版补全 |
| 窗口函数 | 排名、累计、移动平均 | 全面支持 |
| PIVOT / UNPIVOT | 行列互换,交叉报表 | 全面支持 |
| LIKE 方括号通配符 | [0-9]、[^0-9] 这类匹配 |
全面支持 |
| 系统视图跨库访问 | 异构库直接查系统视图 | 支持,不用 ETL |
表里两个状态有讲究:"本版补全"是这一版重点补上的能力,"全面支持"是已经覆盖到位的。翻译过来就是,存量 T-SQL 大部分能原样跑,个别边角微调,业务逻辑犯不着推倒重写。当然,谁也不敢拍胸脯说一行不用动,好在哪些对象要人工介入,评估报告会提前列清楚,心里有数就不慌。
OUTPUT:改数据和留痕,一把干完
老系统爱做审计留痕,T-SQL 的拿手好戏就是 OUTPUT,UPDATE 顺手把变更前后的值捞出来扔进日志表:
sql
UPDATE orders
SET status = 'PAID'
OUTPUT deleted.order_no, deleted.status, inserted.status
INTO order_log (order_no, old_status, new_status)
WHERE status = 'WAIT_PAY'
AND pay_channel = 'WX';
inserted 取新值,deleted 取旧值。要是没这个子句,得先 SELECT 存旧值、再 UPDATE、再补 INSERT 日志,三个动作还得操心事务别断在半道。现在这种存储过程原样搬过来就能跑,一个字不用动。
报表 SQL,照旧写
报表是迁移里最磨人的部分,没有之一。好在窗口函数、PIVOT/UNPIVOT 都在全面支持的名单里,写法不用换:
sql
-- 部门内按薪资排名,顺便算个部门均值
SELECT dept_name, emp_name, salary,
ROW_NUMBER() OVER (PARTITION BY dept_name ORDER BY salary DESC) AS rn,
AVG(salary) OVER (PARTITION BY dept_name) AS dept_avg
FROM employee;
sql
-- 四个季度的销售额,拼成一行
SELECT product, Q1, Q2, Q3, Q4
FROM (SELECT product, quarter, amount FROM sales) AS src
PIVOT (SUM(amount) FOR quarter IN ([Q1], [Q2], [Q3], [Q4])) AS pvt;
以前碰上不认 PIVOT 的库,一张宽表报表得改成一长串 CASE WHEN,改到后半程对着屏幕发呆的经历,写过报表的人应该都有。现在这类代码直接平移,格式都不用动。
并行 DML
这个严格说不算新语法,是执行层面的能力:大表的批量 UPDATE、DELETE 能多核一起上。月底跑批、按年清历史数据这些活儿,迁过来不用担心数据越攒越多、跑得越来越久。
二、细节才见真章
大特性补齐只能算及格,兼容做得细不细,得看犄角旮旯。
举个小东西:LIKE 的方括号。
百分号和下划线谁家都认,麻烦的是 T-SQL 那套方括号玩法------[89] 匹配指定字符,[0-9] 匹配一段数字,[^0-9] 反着排除。筛手机号段、校验单据编号,全靠它们。偏偏这套写法,不少数据库压根不认识。
V9R4C019 认,原样跑:
sql
-- 挑出 138、139 号段的客户
SELECT cust_name, phone
FROM customer
WHERE phone LIKE '13[89]%';
-- test 开头、第三个字符不是数字的登录名
SELECT login_name
FROM account
WHERE login_name LIKE 'test[^0-9]%';
别觉得这是小事。方括号通配符一般埋在 WHERE 条件深处,扫描工具不一定标得出来,人工过一遍又容易漏。这种地方兼容到位,省下的不只是开发量,是上线前一遍遍翻 SQL 的糟心日子。
还有个更容易被忘掉的:运维脚本。DBA 手里谁没几个查系统视图的存货,看表结构、数对象、查锁,天天用。V9R4C019 支持跨库访问系统视图,Oracle、MySQL、金仓数据库之间互通,中间不用搭 ETL。库换了,手艺还能接着用,运维同学听到这个应该会松口气。
三、数据怎么搬
语法的事翻篇,接下来更现实:业务给的窗口就那么几个小时,数据怎么搬得完?
金仓这块的做法是流水线作业,一段一段来,各有各的工具:
| 环节 | 工具 | 干什么 |
|---|---|---|
| 迁移前评估 | KDMS | 扫源库对象,智能转换语法,出量化评估报告 |
| 对象迁移 | KDMS | 表、视图、存储过程、触发器自动建到目标库 |
| 全量搬迁 | KDTS | 存量数据一次搬完 |
| 增量同步 | KFS | 迁移期间新写入的数据实时追平 |
| 上线前验证 | 工具链 | 数据校验 + 真实流量回放 |
| 切流兜底 | 双轨运行 | 新老库并行,不对劲就一键回退 |
重点说说 KDMS。它管迁移评估和语法转换,SQL Server 就在支持名单上(一起的还有 DB2、Oracle、MySQL)。原理不玄乎:把源库 SQL 拆成语法树,再按金仓这边的语法规则和对等函数重新生成一遍。说白了就是雇了个不用睡觉的翻译,比人拿着语法对照表一行行啃快得多,还不容易出错。
几个细节值得一说。采集端只碰结构对象,不动业务数据,生产库压力小;工具在飞腾、银河麒麟这类国产环境上直接能跑;遇到疑难杂症,还能提工单找原厂 DBA。速度也有实测数字:每分钟处理 20 万行以上的 SQL 代码。
说明书里有个 OA 系统的实践记录,数字摆出来挺震撼:四万八千多行 SQL,51 个存储过程,705 个视图,541 个触发器,自动转换率干到 98%。原计划高级工程师 62 人天,实际一个初级工程师 13 人天收的尾,总工时缩了八成。这里得说句公道话,说明书里这些案例的源库不全是 SQL Server,但语法转换走的是同一条流水线,数字的参考意义不打折扣。
至于停不停机,关键看 KDTS 和 KFS 这两环。全量搬完,KFS 把迁移期间的增量实时追平,两边数据校验对上了再切流,业务那边基本无感,这就是所谓的准在线迁移。
切流前有道工序值得单独一提:真实流量回放。生产请求在目标库原样重放一遍,慢 SQL、隐式类型转换、边界数据捅出来的幺蛾子,这个阶段就炸完了,不至于攒到上线当晚集中爆发。真到切流那天,还有双轨运行和一键回退垫底,哪里不对随时退回老库。迁移的容错空间,就是这么一点点抠出来的。
四、迁完才是下半场
切流那天通常不是项目里最紧张的时刻,切换后的头一个月才是。新库接了真实业务,性能、备份、故障处理,哪样出岔子都得回炉重造。
性能是我最关心的一块,老项目翻车多半翻在这。V9R4C019 这回盯的场景挺具体:SQL 里带标量子查询、又做多表关联的分析语句,数据一多就慢。实测下来,100 并发的复杂查询 TPS 涨了 60%,响应时间压到原来的十分之一。这数字落到 BI 同学头上是另一种说法------以前泡杯咖啡等报表出数,现在咖啡还没端起来,结果已经刷出来了。
顺手提个功能,QueryMapping。它自动比对长得像的 SQL 之间的执行差异,哪个突然变慢就直接给改写建议,全程在数据库内部完成,应用代码一行不碰。迁移后的观察期里,这种工具能省掉不少人工盯梢。
备份的变化平时存在感不强,出事时才知道值钱。块级增量备份成了默认归档模式,全量、增量、归档日志三样配齐,PITR 恢复时自己算最优路径,哪条快走哪条。备份窗口从小时级压到分钟级,真出故障,丢的数据更少,恢复也更快。
最磨人的其实是故障定位。以前出了问题,DBA 人肉翻日志,拼图式找根因,一查半宿。现在内置的故障收集分析工具自动抓日志、出诊断报告,官方原话是"5 分钟找到根因"。HA 组件也放开了独立运维,切换逻辑企业自己说了算,不被黑盒方案攥着手腕。
五、动手前,几句提醒
真接了活儿,顺序别搞反。有的团队上来就建库导数据,跑到一半才发现某个存储过程死活改不动,进退两难。稳妥的起手式是先让 KDMS 把源库扫一遍,对象多少、自动转换率多高、哪些要人工介入,报告里全是白纸黑字的数字。拿这个去谈工期,比拍脑袋稳当,也免得中途四处抓人救火。
流量回放这步,预算再紧也别砍。自测用例跑通只算"能跑",生产上的流量分布、并发峰值、各种刁钻数据才是真考卷。这点投入跟上线当晚回滚比,便宜得不是一星半点。
老库也别急着下线。切完流多观察一阵,双轨期拉长点不丢人,回退通道一直开着,业务方踏实,自己也踏实。
一圈聊下来,SQL Server数据库迁移真正较劲的地方就那么几处:老代码动多少,窗口够不够用,出事有没有退路。存量 T-SQL 直接跑、数据准在线搬、故障有工具兜底,KES V9R4C019 把最难啃的几块都给了交代。先扫一份评估报告出来,心里有底了,再谈动手不迟。