我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

SQL Server数据迁移不只是把数据搬过去

SQL Server数据迁移不只是把数据搬过去 SQL Server数据迁移不只是把数据搬过去文章目录SQL Server数据迁移不只是把数据搬过去一、迁移前最该问的问题业务到底慢在哪里二、为什么复杂查询更能检验迁移质量三、SQL Server 数据迁移的实施步骤一次压测应该记录什么四、迁移后性能调优我最关注四件事五、怎样客观看待“迁移后性能提升”复杂查询的改写对照很多人一听 SQL Server 数据迁移脑子里冒出来的第一个念头往往是“迁完之后性能会不会变差啊”这个担心其实特别实在。为什么呢因为你要切换的数据库往往都是在线上跑了好些年的老系统了。里头堆着历史数据呢还有那种特别复杂的报表定时的任务也是一堆。甚至有些业务习惯压根就没写过什么设计文档。新的数据库能让你把数据导进去这只能算干了一半的活儿。剩下的一半是什么呢得等业务查询稳当了报表能按时出数了运维那边也能接得住了这事儿才算完。我个人的习惯呢是把迁移当成给系统做一次全身体检。特别是在 BI 报表还有那种要多表关联分析的场景里面。用户其实根本不关心你底层换成了什么数据库。用户只关心一点那就是一个报表从上面一直转圈“还在计算”变成一下子就能“直接查看”了。在 KES V9R4C019 的那次实测给我留下了一个挺有代表性的印象。在那种带标量子查询的多表关联场景里头100 个并发同时上的时候复杂查询的 TPS 居然能往上提 60%。响应时间呢直接给压到了原来的十分之一。不过大家得注意这个数字是跟着特定的测试环境和特定的查询来的。你不能拿这个去套觉得所有业务都能跑出这个结果。但它起码说明了一个问题就是你搞国产数据库迁移验收标准绝对不能仅仅只是“能跑起来”就完事了。一、迁移前最该问的问题业务到底慢在哪里还没开始迁移呢很多团队就先凑一块儿聊服务器怎么配了CPU 给几核啊存储用什么介质啊。其实业务上的问题还没搞明白呢。某个 BI 报表跑得慢这是一个问题。那为什么会这样呢原因可能有很多。是因为它扫的数据量实在太大了还是说写的连接条件不太对是因为统计口径算起来太复杂还是说一并发起来大家都在抢资源又或者是数据库自己生成的执行计划不太稳再或者是抽数据的那个链路本身就在那儿卡着这些不同的原因你对应的解决办法是完全不一样的。通常来说我会把慢查询归拢成三类来处理。第一类呢就是单表或者就拉两三张表的明细查询。这种你重点盯什么呢盯过滤条件写得对不对索引有没有还有它到底返回了多少行。第二类是多表关联还要做聚合的。这种就得看它连接的顺序是怎么排的统计信息准不准数据有没有倾斜还有中间跑出来的结果集有多大。第三类就是报表类的查询了。这种往往更烦人里面经常夹杂着标量子查询啊窗口函数啊还有各种日期的计算套了好几层。这种你就得盯着整个执行计划看了还得看它并发的时候资源是怎么被吃掉的。在迁移之前你得留下一批真实的 SQL。千万别那种随便手写几个简单的例子来凑数。为什么呢因为真实的 SQL 里面往往藏着业务最常见的那些边界条件。而且它也能把兼容性上的那些差别给暴露出来。那你采集的时候要记些什么呢SQL 的文本得记吧参数的范围得记吧。还有返回了多少行跑了多少时间逻辑读是多少物理读是多少并发量有多大当然还有执行计划。这些东西没有的话你迁完之后说“感觉变快了”或者“感觉变慢了”这就太主观了没法说理。对于迁移项目的验收我一般是拆成四条线来看的验收线关注问题典型证据兼容性对象、语法、事务语义是否一致对象清单、失败 SQL、结果集对比正确性数据是否完整报表口径是否变化行数、抽样哈希、业务汇总性能并发下是否满足窗口和延迟TPS、P95、资源曲线可运维性出问题能否发现、恢复和回退告警、备份恢复、切换记录否是SQL Server生产基线对象与SQL分类样本迁移结果集校验单用户计划对比并发压测四条验收线通过?调整映射/索引/SQL/资源隔离灰度切换观察与回退窗口二、为什么复杂查询更能检验迁移质量那种简简单单的SELECT语句通常来说都不是什么难点。真正能考验数据库的是那种多表关联、子查询、聚合再加上并发这些东西全堆在一块儿的时候。这时候就得看优化器了看它能不能找到一条稳定的执行路径出来。标量子查询就是一个很典型的例子。你光看它觉得它不就是在主查询里面多补了一个字段嘛。但是呢如果主查询一下子返回了几万行数据那个子查询可能就会被重复执行几万次。这个计算成本一下就飙上去了。这还没完如果再叠加上事实表、维度表还有明细表它们之间的关联。这个查询就绝对不是“多加一列”这么简单的事儿了。迁移之后的新数据库如果说它能看懂你这个查询的结构然后合理安排怎么连、怎么过滤。那它就有可能把中间结果集给降下来把那些重复计算给砍掉。下面这个呢是我平时用来建 SQL Server 基线的一个简化写法。大家看的时候注意一下这里的重点是记结果而不是让你把这段代码原封不动地搬到目标库去跑。SETSTATISTICSIOON;SETSTATISTICSTIMEON;DECLAREfromdatetime2DATEADD(day,-7,SYSUTCDATETIME());SELECTo.customer_id,SUM(o.amount)AStotal_amount,(SELECTMAX(p.paid_at)FROMpayments pWHEREp.order_ido.order_id)ASlast_paid_atFROMorders oJOINorder_items iONi.order_ido.order_idWHEREo.created_atfromGROUPBYo.customer_id,o.order_id;SETSTATISTICSTIMEOFF;SETSTATISTICSIOOFF;我呢会把这条 SQL 的文本啊参数啊返回了多少行啊还有逻辑读、CPU 时间以及执行计划全都给存下来。接着呢我会去目标环境的执行计划工具里头再跑一遍同样的测试。这里要提醒一句目标库的诊断命令还有它扩展的能力你得按你实际用的版本来确认。你不能看它命令长得跟原来差不多就直接照抄过来用那是不行的。不过话说回来优化器它也不是什么魔法。如果表的统计信息过期了或者索引选得不对再或者参数分布变化特别大的时候。你换成什么数据库它都有可能生成一个很烂的执行计划。所以说我在看 KES V9R4C019 的性能到底怎么样的时候我不会光看产品本身。我会把产品能力和工程操作这两件事搁在一块儿看。一方面呢我看它在复杂查询上的执行能力到底怎么样。另一方面呢我看做迁移的这个团队有没有把统计信息给维护好索引有没有整理典型的 SQL 有没有去做调优。三、SQL Server 数据迁移的实施步骤第一步呢得先把对象盘点清楚。除了那些表啊、视图啊、索引啊、存储过程啊这些常规的东西。你还得去盘一下作业、登录账号、权限还有同义对象、外部的接口甚至是报表工具的连接串。很多迁移搞砸了其实并不是说数据没搬过去。而是因为某个夜间的作业它还在傻乎乎地调着旧的连接串。又或者是报表平台那边还在用着以前的老驱动。第二步就是做兼容性的分类。你可以把对象分成这么三类。第一类是直接就能兼容的第二类是需要转一下的第三类是需要重构的。直接兼容的那就先迁过去接着做验证。需要转的你得建一个明确的映射关系出来。需要重构的那就别自己闷头搞了得拉上业务和开发一块儿确认。这里有个大忌就是你别把所有的问题都攒到切换前那一天再去解决。要不然的话你那个迁移窗口就会变成一个压力极大的调试现场谁也受不了。第三步搞一个样本库出来。这个样本库里面结构得有代表性吧数据量得有代表性吧查询也得有代表性吧。如果是报表系统的话你至少得把日常跑的报表、月末跑的报表、峰值时候的报表还有临时让人写出来的分析 SQL 都给备齐了。弄这个样本库图什么呢图的就是让你后面每一次做调整都能有个东西拿来对比。而不是说你只跑了一次测试就拍脑袋下结论了。第四步就是全量迁移加上增量同步了。全量那个阶段你盯紧点什么呢盯字段映射对不对字符集有没有问题时间精度够不够还有空值、主键和大字段这些容易出幺蛾子的地方。到了增量阶段呢你的注意力就得转到日志位点上了。还有会不会来重复的数据事件会不会乱序失败了怎么重试。迁移工具的话比如 KDMS确实能帮你把对象转换啊、数据搬运啊、任务管理啊这些活儿给自动化了。但是工具吐出来的东西你还是得拿去走业务校验这步省不了。第五步上并发压测。单用户在那儿跑感觉嗖嗖快这根本说明不了什么问题。你得看 100 个并发砸上去的时候它还能不能稳住。测试的时候你得尽量去模拟生产上读写比例是多少报表访问的节奏是怎么样的。然后盯着 CPU、内存、存储的 I/O还有锁等待和连接池的情况看。这个性能测试啊你至少得跑个好几轮。别刚好有一次缓存全命中了你就拿那个结果去说这就是它长期能力了那是不对的。第六步也就是最后一步了搞灰度切换。先别一上来就全量切。你先挑那种低风险的业务或者干脆就是只读的报表来验一验。没问题了再一点点把范围往外扩。在这个切换的过程里面旧系统的回退条件你一定要给它留着。你得提前说好谁来喊回退回退的话会丢哪个时间段的数据回退完了之后拿什么办法去补数据。你的迁移方案写得越细真出问题的时候大家就越不用去拼个人的经验。一次压测应该记录什么场景并发结果集行数TPS/吞吐P95 响应时间备注单用户冷缓存1实际记录实际记录实际记录观察首次访问代价单用户热缓存1实际记录实际记录实际记录观察缓存命中影响报表并发100实际记录对比基线对比基线重点关注标量子查询混合负载按生产比例实际记录对比基线对比基线同时包含写入与查询四、迁移后性能调优我最关注四件事第一个呢就是统计信息。数据迁完了目标库这边你得根据实际数据的分布情况把统计信息给建起来。数据量多大啊分布是怎么样的啊增长的速度有多快啊这些全都会影响执行计划。所以你不能偷懒直接把旧系统那套维护周期照搬过来用。第二个看索引的质量。索引这东西真不是越多就越好的。你加了一堆没用的索引写入的时候成本就上去了维护也费劲。但是如果你少了索引那报表查起来就得全表扫那更完蛋。所以你应该怎么搞呢围着那些高频的过滤条件、连接条件、排序条件还有分组条件去调索引。调完之后呢还得去执行计划里面看一眼确认它是不是真的被用到了。第三个看 SQL 的结构。迁移的时候没谁规定不让你改 SQL 的。遇到那种重复计算的啊排了序但其实没用的啊很早就把大字段给返回来了的啊还有那种压根就没加范围限制的查询。只要你不把业务的语义给改了你就可以去优化它。特别是那种标量子查询、套了好几层的嵌套还有多表关联。你得拿不同的写法去跑一跑比一比它们的执行计划和出来的结果集。第四个就是资源隔离。在线的交易啊报表的查询啊还有那种批量的任务如果大家都在同一拨资源里面混着用。那就很容易互相打架互相影响。怎么办呢你可以搞读写分离啊把连接池规划一下啊给报表定个时段啊或者让任务错开峰值跑。前面参考资料里头重点提的那个 KES 多集群架构其实也是这个思路。就是通过不同的部署方式去满足业务不能断啊、性能要能扩展啊还有成本得控制住这些需求。五、怎样客观看待“迁移后性能提升”性能提升这事儿它是有一个边界的。你换套硬件或者数据量不一样了SQL 写得不一样了参数变了并发模型也变了那测出来的结果肯定不一样啊。对于你做项目来说真正有意义的事情是什么呢是把你自己的基线和验收条件给建起来。我个人的建议是你至少得设四类指标。第一类叫功能一致性第二类叫性能达标第三类叫稳定性第四类叫运维可接管。功能一致性看什么呢看数据量对不对关键字段有没有丢报表结果一不一致还有事务的行为变没变。性能达标看什么呢看核心 SQL 的 P95 响应时间达没达标并发吞吐量够不够批处理能不能在规定窗口里跑完。稳定性看什么呢看它能不能连续跑不出错出了故障能不能恢复备份了能不能恢复回来。运维可接管看什么呢看监控有没有告警有没有权限怎么分审计怎么做还有以后升级的流程通不通。复杂查询的改写对照标量子查询这东西不是说你非得改它不可。但是呢你很值得拿一个改写出来的版本去跟它做个对照。下面这种写法就是先把每个订单最后一次支付的时间给聚合出来。接着呢再回头去跟主查询连起来。这么搞主要是为了方便你去比较。比较什么呢比较那种重复执行的方式和这种只聚合一次的方式它们走出来的路径到底差在哪。WITHlast_paymentAS(SELECTorder_id,MAX(paid_at)ASlast_paid_atFROMpaymentsGROUPBYorder_id)SELECTo.customer_id,SUM(o.amount)AStotal_amount,lp.last_paid_atFROMorders oJOINorder_items iONi.order_ido.order_idLEFTJOINlast_payment lpONlp.order_ido.order_idWHEREo.created_at:from_timeGROUPBYo.customer_id,o.order_id,lp.last_paid_at;这并不是说所有的查询都得照着这个改。它其实仅仅只是一种你可以拿去验证的调优办法。什么呢就是你保证业务跑出来的结果是一模一样的你只把里面那个可能重复计算的局部给换掉。然后呢你再去分别测一下它们的执行计划、逻辑读还有并发时候的延迟情况。你如果要去理解 KingbaseES 在迁移项目里面的优势我觉得可以从几个方面来看。兼容性啊迁移工具啊集群的能力啊还有复杂查询优化啊。它想干的事儿不是简单地把原来的数据库名字换掉。它是想在你业务不中断的情况下把迁移的阻力给降下来。而且呢让你以后做运维、做性能治理的时候能有一个更统一的基础。国产数据库想要真正进到核心业务里面去靠的绝对不是那种搞一次宣传就喊“替代了”的做法。靠的是什么靠的是一次又一次能验证的、能回退的、还能一直持续优化的这种工程实践。所以说到底做 SQL Server 数据迁移最重要的一条经验其实就是一句话。数据搬过去那仅仅只是一个动作而已。业务跑得稳不稳当报表出得快不快团队以后管不管得住这些才是你要的结果。只要你把基线啊、验证啊、压测啊、回退啊这几件事给做扎实了。那这个迁移它就不会变成一次赌运气的风险押注了。它反而可以变成一个机会一个让你的系统性能和数据治理一起往上走的机会。
返回列表