去年我们内部做了一次不大不小的“搬家”,把一个跑了八年的 Oracle 业务主库,连同外围四十多个应用系统,整体迁到了 KingbaseES 上。过程没有想象中那么痛苦,但绝对不比想象中省事。这里的“痛苦”指的不是某条 SQL 改不动、某个存储过程编译不过去,而是整个链条上需要拍脑袋的决定太多:兼容性边界在哪、数据怎么搬、业务停多久、回退怎么做、上线后性能会不会崩。任何一个环节没想清楚,后面都要拿一倍的返工去填。
这篇就按我自己跑完一轮完整项目的顺序来聊,适合正在做数据库替代技术评估、或者已经立项准备动迁的 DBA、应用架构师和项目负责人参考。我会把关键判断逻辑、改造案例和踩过的坑都放进来,尽量做到看完可以直接拿去当工作清单用。
1. 先想清楚要解决什么问题,再谈替代迁移
1.1 我们当时为什么要动 Oracle 老库
很多团队在做国产数据库替代的时候,第一步就直接跳到“选型对比”和“迁移工具”,这是最容易翻车的地方。我们在立项前其实被问了三次同一个问题:到底要解决什么?
当时的老 Oracle 库有三座大山。
第一是硬件维保和软件授权成本。这套系统在线运行多年,底层硬件已经过了原厂维保期,每次扩容都要走“买整机还是换备件”的纠结流程;软件授权成本也在逐年上涨,管理层已经明确不希望再往这套老架构里追加太多预算。
第二是技术栈分裂。公司其他新业务基本都跑在基于 PostgreSQL 生态的数据库上,团队对新生态的运维、排障、监控都比较熟,只有这一套核心库是 Oracle 体系。每次出问题都得临时找外部专家支持,响应链路长,内部 DBA 也疲于应付两种差异很大的数据库运维习惯。
第三是架构演进的诉求。老库承担的负载一直在增长,分区表、归档清理、读写分离这些需求在 Oracle 上做起来成本偏高,而团队更希望把数据库底座往开源生态统一。
这种情况下,KingbaseES 进入视野就顺理成章了。它提供 Oracle 兼容模式,意味着我们最担心的“应用改动量爆炸”问题,在选型评估阶段就有可能被控制在可控范围。这里我要强调一句:替代迁移最怕的不是“工作量很大”,而是“工作量无法估计”。选“兼容模式做得深”的产品,本质上是在降低不确定性,而不是在偷懒。
1.2 别让迁移变成 DBA 一个人的苦役
项目组构成是我在复盘时认为最被低估的环节。很多公司把数据库替代直接扔给 DBA 团队,这是不明智的。因为整个迁移链条里,数据搬运只是其中一段,应用改造、测试验证、上线切换、回退演练四个环节如果没有人牵头,最后一定会变成“DBA 在前线救火,开发在看热闹”。
我们当时的虚拟项目组大概是这样的:
- DBA 团队负责环境搭建、数据迁移、数据校验和性能基线对比;
- 应用开发团队负责 SQL 采集、存储过程改造、连接方式调整;
- 测试团队负责功能回归、兼容性用例设计和性能验证;
- 运维团队负责监控接入、备份恢复演练和应用发布窗口协调。
项目组里还有一个很重要但容易被忽略的角色:商务接口人。数据库替换不只是技术动作,授权范围、服务支持、故障响应等级这些商务条款没谈好,项目中期可能停工。我们当时吃过这个亏,后来才补上,这里提醒一句:动工之前,把厂商技术支持的服务级别和响应时间写清楚。
1.3 现状盘点清单:越细,后续坑越少
正式动迁之前,我们花了两周做现状盘点。这一步看起来费时间,实际上是在给后面的所有决定提供依据。盘点清单我建议至少包含以下内容:
- 数据库实例数量、部署形态(单机、RAC、DataGuard 等);
- 应用系统数量、连接方式、连接池配置;
- 对象清单:表、索引、分区、视图、物化视图、序列、同义词;
- 存储过程、函数、包、触发器的数量和代码行级规模;
- 日增数据量、最大表、TOP 20 大表的行数和存储;
- 定时任务清单(Job、调度平台依赖的 SQL);
- 第三方工具依赖:ETL、报表、BI、消息中间件是否直接连库;
- 慢 SQL、高频 SQL 的大致类别和占比。
这套盘点结果最终会导向一个问题:迁移工作量的上限在哪里。如果一个系统 80% 的 SQL 都能在兼容模式下直接跑通,剩下的 20% 是可以分批改完的;如果连基础数据类型都要大面积手工处理,那就要重新评估替代的必要性。我们在盘点后得出的结论是:主库对象规模中等,存储过程数量较多,但绝大多数是标准的数据读写逻辑,属于“可以改造但需要时间”的类别。
2. 兼容性摸底:Oracle 与 KingbaseES 的边界在哪里
2.1 数据类型与内建函数:绝大多数能自动对应,少数要手动处理
兼容性摸底不能只看厂商的“兼容列表”,因为真实业务里总会出现一些边缘情况。我们的做法是拿一个完整业务库做小范围试迁,然后对着报错信息逐个处理。下面这几类是我们遇到过、或者说建议重点检查的:
- NUMBER:Oracle 的 NUMBER 在 KingbaseES 的 Oracle 兼容模式下有对应类型,数值精度和范围基本能对上。要注意的是 NUMBER 不指定精度时,两边对超长数值的处理策略可能不同,建议在测试阶段故意插入大数值验证。
- VARCHAR2:Oracle 里 VARCHAR2 的长度单位是字节,和数据库字符集相关,这一点在工具里可能直观表现不出来。字符集和长度语义不一致时,索引和字段定义可能整体偏移,要提前确认。
- DATE:Oracle 的 DATE 包含时间部分,到新环境后默认行为可能更接近时间戳。对于只存日期的字段问题不大,但如果应用层用 DATE 做精确比较,要特别小心。
- CLOB/BLOB:大字段基本可以迁移,但要注意初始化、写入、读取的驱动方式差异。Java 应用里对 CLOB 的处理 API 在两边表现不完全一样,建议把涉及大字段的用例单独列出。
内建函数方面,常用函数基本都能对应,比如 NVL、DECODE、TO_DATE、SYSDATE、TRUNC、SUBSTR 这些都没问题。真正容易出问题的是那些在应用中分散使用、但不会出现在建表脚本里的“偏门函数”。我们有两条经验:第一,从应用源码里全文搜索函数名,和官方兼容列表做交集;第二,把测试阶段发现的运行期报错函数统一收进一张“函数兼容台账”,逐条确认处理方式。
2.2 SQL 语法层面:分页、层次查询、空串语义是高频检查点
数据类型是静态的,SQL 语法是动态的。我们这次收集到的改造点主要集中在几类典型语法上。
第一个是分页查询。很多老系统用的是ROWNUM两层嵌套写法,这和 PostgreSQL 系数据库的习惯写法差异很大。虽然兼容模式下部分写法能跑,但建议统一改成标准的LIMIT/OFFSET或FETCH FIRST写法,因为改造后的 SQL 可读性和执行计划可控性都更好。
第二个是层次查询CONNECT BY。如果应用里有大量树形结构的递归查询,这一块要重点验证。KingbaseES 的 Oracle 兼容模式支持情况我不在这里做绝对结论,因为不同版本有差异。稳妥的做法是:先在测试环境跑典型递归语句,如果兼容性不够,尽早改成递归 CTE。不要押注所有CONNECT BY都能直接过,要给自己留改造空间。
第三个是空串与 NULL 语义。Oracle 有一个历史行为是''会被当成 NULL,而 PostgreSQL 内核默认不是这样。Oracle 兼容模式会尽量模拟这个语义,但应用里如果同时依赖''和NULL做不同判断,那就有隐性风险。我们的处理建议是:不要让应用依赖空串和 NULL 的区别,统一用IS NULL判断。
第四个是DUAL、序列、SYSDATE这类“Oracle 习惯”。这些在兼容模式下通常都没问题,但要注意部署时的兼容模式参数是否在实例、数据库、会话等不同层级保持一致。曾经出现过某个会话连接后没有正确进入 Oracle 兼容模式,导致DUAL查询行为异常的情况。
2.3 PL/SQL 与内置包改造空间
存储过程是这次迁移里工作量最集中的部分。我们库里大概有几百个存储过程,涉及日常批量对账、数据纠正、报表生成。Oracle 的 PL/SQL 语法体系在新数据库的 Oracle 兼容模式下能保留多少,直接决定了改造成本。
如果只是普通的过程、函数、包、触发器,结构上基本能平移。重点要留意四类问题:
- 游标相关:显式游标、游标 FOR 循环、游标变量(REF CURSOR)。REF CURSOR 作为参数传递时,两边驱动层的处理方式不同,应用层取数逻辑要调整。
- 异常处理:
OTHERS异常捕捉、自定义异常、SQLCODE/SQLERRM 的取值行为会有差异。生产库里很多存储过程靠异常编号做分支判断,这些编号不能假设两边一致。 - 自治事务:
PRAGMA AUTONOMOUS_TRANSACTION这类写法,兼容模式下支持程度要实测。如果大量使用,建议做专门的样例验证。 - 内置包:最常见的
DBMS_OUTPUT、DBMS_LOB、DBMS_SQL等包在官方兼容列表里通常能对上,但包内具体函数的行为细节仍可能和 Oracle 不一致。我们遇到过DBMS_LOB对空 LOB 的处理返回结果不同的问题,属于典型的长尾坑。
这里我特别建议:不要只做“编译通过”验证。编译过不代表运行行为一致。我们吃过这个亏:有一个存储过程在上百个批次里都跑得好好的,因为一个数值舍入函数的新旧行为差异,上线后某一天的汇总金额差了零点几分。金额差异不大,但对账系统立刻报警。所以存储过程改造后,一定要拿历史真实数据跑一遍典型输入,比对输出结果。
2.4 高可用、备份恢复和运维工具是另一个维度的“兼容题”
数据库替代的“兼容性”不只是 SQL 层面的。DBA 团队最关心的其实是高可用架构能不能对齐、备份恢复能不能兜底、监控告警能不能接入统一平台。
Oracle 常用的 RAC + DataGuard 组合,对应到 KingbaseES 上就是集群架构加备库同步机制。架构理念相似,但细节差异很大:比如故障切换的触发方式、VIP 漂移行为、备库只读能力、切换后连接串怎么变。这些都要在测试环境反复演练,特别是“主备切换后应用是否自动重连”这一项,是上线前必须验证通过的。
备份恢复方面,Oracle 系 DBA 习惯的 RMAN 脚本要完全换成新数据库的物理备份机制。我们当时把备份策略整体重新设计了一遍:全备周期、增量周期、备份窗口、恢复演练的目标时间点。这里有个比较容易忽略的点:备份集要支持跨版本恢复测试。我们每个月做一次恢复到演练库的操作,确保真到出问题时,不是一个摆设。
运维工具上,新数据库通常支持从外部监控系统采集状态指标,但采集方式和指标名称和 Oracle 不同。我们接入内部监控平台时,花了不少时间在连接数、活跃会话、SQL 延迟这些指标的映射上。这个过程不要留到上线后再做,观察期如果没有监控数据,出了问题就只能靠猜。
3. 迁移路径选择:全量、增量、双轨并行怎么搭配
3.1 三条主流路线对比
兼容性摸底做完之后,就要回答一个核心问题:数据怎么从老库到新库,业务停顿多久。
我们当时梳理出三条可执行路线。第一条是“停业务全量迁移”:把所有应用停掉,导出数据,导入新库,校验无误后切换连接。好处是步骤简单,回退容易;坏处是停机窗口必须足够长,数据量一大,窗口就不够用。
第二条是“全量加增量追平”:先在业务运行期做一次全量迁移,然后用数据同步工具持续把老库的新增变更同步到新库,最后在割接窗口内停写、追平、校验、切换。好处是对停机窗口要求短,坏处是链路更长,多了一个持续同步环节,同步延迟和冲突处理都需要额外设计。
第三条是“双轨并行”:新老库同时运行一段时间,应用逐步灰度切流。好处是业务风险最低,坏处是成本最高,两边数据要双向同步或做应用层双写,对团队的综合能力要求也最高。
我在这个阶段的体会是:不要在项目初期就追求“一步到位”。路线选择要考虑团队对工具的熟练程度。如果之前没用过数据同步工具,第一次上手就做非常复杂的增量链路,风险会很大。
3.2 窗口、数据量和网络带宽是三个硬约束
路线选择不是拍脑袋,是算出来的。我们当时的硬约束是:核心业务每周只有一次 4 小时的维护窗口,数据库总数据量约 2TB,网络环境是万兆内网。
按这个条件估算,如果走停业务全量迁移,即使迁移工具能跑到每小时 600GB 的速度,2TB 数据也要 3 个半小时以上,还没算校验、切换、应用重启时间。4 小时窗口根本不够,而且 600GB 每小时这种速度在跨机房的网络条件下未必能持续。所以第一条路线直接被否掉了。
那就只剩第二条和第三条。双轨并行看起来美好,但我们当时没有成熟的跨数据库双向同步方案做支撑,如果走应用层双写,所有涉及写入的接口都要改造,工作量不可控。最终我们选择了“全量加增量追平”方案,把停机窗口压缩到一个小时以内,具体后面会展开讲。
这里给一个通用建议:把“停机窗口允许值”“数据总量”“可接受的最大延迟”“团队对同步工具的熟悉程度”四个参数列出来,再选路线,就不会被厂商的“一键迁移”宣传带偏。
3.3 我们用的“全量 + 增量追平 + 应用开关切换”方案
具体设计是这样的:提前两周启动全量迁移,把表结构、种子数据、历史数据先搬过去,再用官方数据迁移工具做全量校验。全量完成后,部署数据同步组件,把老库的在线变更持续同步到新库。这里同步的对象包括 DML 操作,也包括序列的当前值和部分定时任务状态。
到割接日,动作顺序是:先停应用写入,让老库进入静止状态,等待同步延迟归零;然后做最后一轮增量追平,再用校验工具对账;对账通过后,把应用连接串从老库切到新库;应用启动,功能回归。整个过程我们给自己定的目标是“数据库切换控制在 30 分钟内”,实际执行比预期顺利,主要归功于提前一周做了两次完整的割接演练。
这个方案的回退设计也比较清晰:老库环境在观察期内原样保留,同步链路先不拆。如果上线后发现重大问题,应用连接切回老库即可,新库那边再做差异回灌。因为我们用的是增量同步,切换回去之后老库的数据也是完整的。
4. 实施阶段真正的硬仗:SQL 改造、校验与割接演练
4.1 全量 SQL 采集:别只扫业务代码,运行时 SQL 才是大头
很多人做兼容性评估时只去扫应用源码里的 SQL,这是不够的。实际生产库里,运行时产生的动态 SQL、报表系统临时拼接的查询、后台批量任务的存储过程逻辑,很难通过源码检索覆盖全。
我们当时做了三层采集。
第一层是应用源码扫描。把所有 Java、存储过程里的 SQL 文本提取出来,去重、归类。第二层是数据库日志采集,从老库的慢查询日志、审计日志和统计信息里捞出真实运行的高频 SQL。第三层是运行时抓取,用一个轻量化的代理方式,把测试环境里跑业务回归时产生的所有 SQL 记录下来。
三层数据合并之后,我们得到了一个几千条 SQL 的样本集。把这些样本拿到新库上批量执行,按“完全兼容”“需要改写”“不支持”三档分类,改造工作量才变得清晰。
这个环节我最大的教训是:SQL 样本集要先做“参数化清洗”,把 WHERE 条件里的具体值替换成变量,否则同样一条 SQL 会因为数字不同被算成几十条,后面整理的工作量会翻倍。
4.2 高频改写案例:ROWNUM、CONNECT BY、DECODE 和空串
下面这几个改写案例是我们项目里真实处理过的,都比较典型。
第一个是 ROWNUM 分页。老代码里常见这种写法:
SELECT * FROM (SELECT t.* FROM orders t ORDER BY create_time DESC) WHERE ROWNUM <= 20;在兼容模式下如果直接跑不报错,也不建议保留。建议统一改成:
SELECT * FROM orders t ORDER BY create_time DESC LIMIT 20;如果应用里还有ROWNUM = 1这种取首行写法,也要顺带处理,改成LIMIT 1或FETCH FIRST 1 ROW ONLY。
第二个是层次查询。一个常见场景是组织架构树:
SELECT emp_id, emp_name, level FROM employees START WITH manager_id IS NULL CONNECT BY PRIOR emp_id = manager_id;我们在测试环境验证过,部分版本能直接兼容,但为了保险,项目统一要求改成递归 CTE:
WITH RECURSIVE emp_tree AS ( SELECT emp_id, emp_name, 1 AS level FROM employees WHERE manager_id IS NULL UNION ALL SELECT e.emp_id, e.emp_name, t.level + 1 FROM employees e JOIN emp_tree t ON e.manager_id = t.emp_id ) SELECT * FROM emp_tree;改写后执行计划更容易控制,也避免踩层次查询的兼容性边界。
第三个是 DECODE 和 NVL。DECODE 属于 Oracle 系很常用的写法,兼容模式下基本能处理,但长链 DECODE 的可读性太差。我们遇到过一个十层嵌套的 DECODE,直接改写成了 CASE WHEN,既能保证行为一致,又方便后续维护。NVL 则统一改成 COALESCE,这两个函数在多数场景下等价。
第四个是空串判断。老代码里可能大量出现WHERE col = ''这类条件,Oracle 里它等价于WHERE col IS NULL,到新库可能行为不同。我们的处理原则是把所有col = ''修改为col IS NULL,从源头消除语义差异。
4.3 存储过程改造与批量编译验证
存储过程是这次工作量的重头,我们采用了一个“三批次”验证节奏,这里分享下。
第一批次是清单摸排。把所有存储过程、函数、包按模块归属分类,标记出调用频次高、依赖表多、逻辑复杂的对象,优先处理。
第二批次是静态改造。把源码从老库导出,逐个做语法差异修正,改完后在新库执行创建脚本,目标是“能编译通过”。这个批次不能追求自动化率太高,因为很多差异是语义层面的,只能靠人工判断。
第三批次是运行验证。针对每个对象准备一套典型输入,包括正常数据、边界数据、异常数据三种类型。正常数据验证主流程,边界数据验证数值精度和空值处理,异常数据验证错误分支。这三套输入跑完,存储过程的行为才算真正验证过。
我们踩过一个具体的坑:某个批量处理包内部用了动态 SQL,把表名拼进字符串再执行。静态检查时完全看不出问题,但在新库上跑批时,因为表名大小写策略不同,导致动态 SQL 找不到表。这个问题的修复方式是把动态 SQL 里的表名统一处理成小写。所以如果你们的存储过程里有大量动态 SQL,一定要额外关注对象名的大小写解析规则。
4.4 数据校验三板斧:行数、校验和、业务抽样
数据迁移不是“搬过去”就算完,要“搬得对”。我们当时的数据校验分了三个层次。
第一层是行数对比。每个表两边分别COUNT(*),快速排查漏搬、重搬的问题。2TB 数据做全量行数统计有开销,我们是按表大小分批跑,大表单独处理,小表并行统计。
第二层是校验和对比。对关键表用整行拼接的方式算哈希,两边对比结果。这一层能发现“行数一样但内容不一致”的问题,比如某些字段被同步工具截断或者字符集转换出错。我们用的是逐表拼接常量字符串再取哈希的方式,不要只比对单列,那样发现不了整体错位。
第三层是业务抽样。这是最贴近真实使用的方式。挑几条真实的业务链路,比如“创建一个订单—更新库存—生成对账单—按条件查询”,在新库完整执行一遍,比对老库的输出。抽样要覆盖超高频场景和罕见场景,比如跨月的边界数据、含 NULL 的数据、超长字符串数据。
三层做完,还有一个不能省略的动作:老大难字段的人工抽查。我们当时发现过一个字段类型为 VARCHAR2 但实际存了非常规字符的情况,两个库之间虽然行数、哈希都一致,但应用读出来展示乱码。这种问题只有通过业务侧人肉确认才能发现。
4.5 割接当天的动作序列与回退预案
割接当天看起来时间不长,但节奏必须非常清楚。我们把当天切分成若干带检查点的阶段,每个阶段有负责人、有超时信号。
第一阶段是停写。通知所有应用暂停写操作,关闭定时任务和消息消费端,数据库侧断开长事务。这里要注意:不要只靠应用配合“不写了”,保险起见在数据库层把写权限收紧。
第二阶段是增量追平和最终校验。等同步延迟归零,做最后一轮行数对比和业务抽样,全部通过才允许进入下一步。
第三阶段是切换连接。应用连接池切换到新库,这里有个容易忽略的细节:连接池里可能有老连接残留,需要一并重启应用节点,否则部分请求还落在老库上。
第四阶段是功能回归。我们准备了一张冒烟用例清单,覆盖登录、主流程查询、批量任务触发、报表导出。回归通过后,向项目组宣布“切换成功”,但此时不宣布“项目完成”。
回退预案方面,我们规定:如果切换后 2 小时内出现严重阻断问题,直接切回老库。回退过程不需要重跑数据迁移,因为老库在观察期仍完整保留,增量同步链路也能反向工作。这里特别建议所有回退动作都要提前演练两遍,不要等到紧急情况下才翻文档。
5. 上线不是终点:稳定性观察、性能调优和运维模式切换
5.1 换库后最容易冒头的三类性能问题
上线只是开始,真正考验在后面一周到一个月。我们观察期内处理最多的问题,集中在三类。
第一类:执行计划变差。老库上跑得好好的 SQL,到新库因为统计信息还没收集全,或者优化器策略差异,选择了不合适的执行计划。解决手段是先收集统计信息,再对少量核心 SQL 做人工调优。注意:不要在观察期前三天就大规模加索引,容易掩盖真实问题。先让负载跑一段时间,用慢日志定位最突出的 SQL 再动手。
第二类:绑定变量和参数风格的差异。有些应用框架在连接参数里配置了和 Oracle 兼容的取数方式,新库下表现不一致,导致界面查询偶发超时。这类问题排查难度高,因为现象是间歇性的。我们的经验是上线前统一检查所有连接池和驱动的参数配置,别只改一个连接串就以为万事大吉。
第三类:大事务和锁行为。虽然都是行锁机制,但某些批量更新场景下的锁等待表现不同。我们有一个夜间批处理任务,老库上跑 20 分钟,新库上跑了 1 小时也不结束,后来发现是某个表缺了索引,导致批量更新走了全表扫描,锁范围变大。这个问题的教训是:不能拿老库的索引清单直接照搬,要做一轮“基于新库执行计划的索引复核”。
5.2 监控、备份与容灾需求的新对齐
数据库换了,监控体系也得跟着换。Oracle 时代我们习惯的等待事件、会话分析思路要切换到新数据库的指标体系上。我建议重点项目都配置以下几类监控:
- 连接数和会话状态;
- 慢 SQL 和错误日志;
- 数据同步延迟(如果还保留增量链路);
- 主备复制延迟和切换状态;
- 磁盘空间和备份任务状态。
备份方面,新数据库的物理备份机制和 Oracle 完全不同。我们上线前做了三次恢复演练,其中一次故意在全量备份后追加一个误删操作,然后从备份恢复到误删前时间点。这个演练非常值得做,能暴露恢复手册里含糊不清的地方。
容灾切换演练也要纳入常规运营。新数据库的主备切换和 Oracle 的 DataGuard 切换在操作细节上差别很大,尤其涉及 VIP 漂移、应用侧自动重连。我们后来把切换演练定义为季度例行项目,而不是只在项目上线前做一次。
5.3 长尾兼容问题如何用“迭代清扫”沉淀
数据库替代上线后,不代表所有兼容性问题都消失了。总有一些低频逻辑,要等特定业务场景触发才会暴露。我们在观察期建立了一个“兼容性问题台账”,所有 DBA 和应用团队发现的问题都记录在案,包括现象、根因、处理方式、涉及对象四列。
每周例会过一遍台账,已经关闭的问题打上标签,未关闭的排优先级。这种做法让长尾问题不会因为“没人提就忘了”,也让团队积累了新数据库的使用经验。我后来把这套台账也用在其他项目的数据库运维上,效果很好。
还有一个容易被忽略的环节:把改造后的 SQL 和存储过程纳入代码规范。我们要求开发团队新提交的 SQL 必须按新库的语法规范编写,不允许写出只能在兼容模式下碰巧运行的语句。否则过两年团队换人,接手的人看到一堆“看起来像 Oracle 又不是 Oracle”的代码,会非常痛苦。我们在内部文档里写了一条原则:兼容模式是降低迁移成本的缓冲垫,不是长期编码风格。
最后想说一点个人体会
整个项目做完,我最大的感受是:替代迁移里真正决定成败的,不是数据库产品的“兼容性有多强”,而是团队有没有把存量资产盘清楚的工程纪律。兼容性再好的数据库,也架不住“边迁边拍脑袋”。把评估、迁移、校验、回退这几件事做扎实,KingbaseES 这类 Oracle 兼容库完全可以承担生产负载。
如果你手头也在评估类似的替代项目,我建议把第一个月完全留给现状盘点和兼容性验证,不要急着写迁移脚本。这份清单可以直接拿去用,希望你们少踩我们踩过的坑。