当前位置: 首页 > news >正文

10年Oracle运维转战国产数据库:迁移路上的“坑”与“光”

文章目录

    • 一、国产数据库Oracle兼容模式真的能无缝迁移吗?
    • 二、我是谁,为什么要做这个迁移
    • 三、开局暴击:KES连接报“OCI-21500”错误
      • 踩坑现场
      • 错误代码示例
      • 解决过程
      • 正确配置
    • 四、PL/SQL匿名块执行失败:差点让我丢了饭碗
      • 踩坑现场
      • 错误代码示例
      • 解决过程
      • 正确代码示例
    • 五、JSON函数返回NULL:差点让我怀疑人生
      • 踩坑现场
      • 错误代码示例
      • 解决过程
      • 正确代码示例
      • 另一种正确写法
    • 六、物化视图刷新异常:加班到凌晨三点的噩梦
      • 踩坑现场
      • 错误代码示例
      • 解决过程
      • 正确代码示例
    • 七、存储过程迁移中的其他坑
      • 触发器迁移的烦恼
        • 错误代码示例
        • 正确代码示例
      • 自定义函数迁移的坑
        • 错误代码示例
        • 正确代码示例
    • 八、性能优化的那些事
      • 索引优化的坑
        • 错误代码示例
        • 正确代码示例
      • 查询优化的坑
        • 优化前的查询
        • 优化后的查询
    • 九、关于迁移的一些思考
      • 兼容模式的陷阱
      • 文档的不足
      • 社区的重要性
    • 十、未来的展望
    • 十一、金仓社区欢迎您


兼容
是对前人努力的尊重
是确保业务平稳过渡的基石
然而
这仅仅是故事的起点

一、国产数据库Oracle兼容模式真的能无缝迁移吗?

最近这几年,国产数据库发展得挺快的,尤其是金仓、达梦这些大厂,都推出了Oracle兼容模式,号称可以无缝迁移。但我在实际迁移过程中发现,根本不是这么回事啊。

早期的研究(2018-2020)更多关注语法兼容,比如能不能支持Oracle的SQL语句、PL/SQL块这些。当时很多学者都觉得,只要语法兼容了,迁移就不是问题。但后来的研究(2021-2022)发现,光语法兼容还不够,性能也是个大问题。比如同样一个查询语句,在Oracle中运行很快,在金仓中可能就很慢。而且这些研究的样本量都比较小,大多是实验室环境下的测试,和实际生产环境差距挺大的。

到了2023-2024年,越来越多的研究开始关注实际迁移中的问题,比如存储过程迁移、触发器迁移、JSON函数兼容这些。但我发现,这些研究都忽略了一个重要的问题:兼容模式的定义。有些学者认为“兼容模式”就是语法兼容,只要能运行Oracle的SQL语句就行;有些学者认为是功能兼容,除了语法兼容,还要支持Oracle的所有功能;还有些学者认为是性能兼容,要保证迁移后的性能和Oracle相当。

我觉得功能兼容才是最重要的,因为如果只是语法兼容,但是不支持Oracle的某些功能,比如物化视图快速刷新、函数索引这些,那迁移之后还是要花很多时间去改代码,根本谈不上无缝迁移。而且这个选择对我的研究影响很大,因为我需要迁移的是核心业务系统,必须保证所有功能都能正常运行。

还有一个学术争鸣的地方,就是有些学者认为国产数据库的Oracle兼容模式已经足够成熟,可以无缝迁移;而另一些学者认为还有很多问题需要解决。我发现这两种观点的核心假设不一样,前者假设用户的应用是标准的Oracle语法,没有太多自定义函数和存储过程;而后者考虑了用户的实际情况,比如很多用户的应用都有大量的自定义函数和存储过程,这些在兼容模式下可能会有问题。

二、我是谁,为什么要做这个迁移

我是一名干了快10年的数据库老运维,在一个传统制造业大厂做技术支持。去年公司为了响应国产化号召,决定把核心业务从Oracle迁移到金仓数据库(KES)。我当时一听头都大了,之前都是用Oracle,金仓完全没碰过啊。但是没办法,领导点名让我牵头干,只能硬着头皮上。

三、开局暴击:KES连接报“OCI-21500”错误

踩坑现场

刚开始连数据库就给我整懵了,用OCI连接的时候直接报“OCI-21500”错误。我当时就傻了,这啥意思啊?然后开始查文档,金仓的官方文档写得还挺详细的,哪只道我看了半天还是没明白。后来去论坛问,才知道是金仓的Oracle模式和原生Oracle的初始化参数不一样。

错误代码示例

-- 错误的连接方式sqlplus sys/kingbase@127.0.0.1:54321/orclassysdba

解决过程

后来在论坛大佬的指点下,才知道要修改金仓的初始化参数ora_compatibleON。我赶紧去改,改完之后重启数据库,再连接就成功了。不过我当时犯了个低级错误,修改参数的时候没在postgresql.conf里改,而是直接在命令行改的,结果重启之后又回到原来的设置了,白忙活半天。

正确配置

-- 打开金仓的Oracle兼容模式altersystemsetora_compatible=on;-- 重启数据库生效

四、PL/SQL匿名块执行失败:差点让我丢了饭碗

踩坑现场

连接成功之后,我就开始迁移存储过程了。第一个PL/SQL匿名块就执行失败了,提示“ORA-06550: 第1行, 第7列: PLS-00103: 出现符号 "PROMPT"在需要下列之一时”。我当时就慌了,这可咋整啊,这可是核心业务的存储过程啊。

错误代码示例

set serveroutput on; declare v_num number := 100; begin dbms_output.put_line('v_num = ' || v_num); end; /

解决过程

我仔细对比了Oracle和金仓的PL/SQL语法,才发现金仓不支持set serveroutput on;这种SQL*Plus命令。后来我改成用金仓的方式来启用服务器输出:

正确代码示例

-- 金仓中启用服务器输出 show serveroutput; set serveroutput on; declare v_num number := 100; begin dbms_output.put_line('v_num = ' || v_num); end; /

还有一个大坑,就是金仓的PL/SQL中变量声明的位置和Oracle有点不一样。在Oracle中,变量可以在declare块的任何位置声明,但是在金仓中,变量必须在declare块的开头声明。我当时改了好几个小时才把这个问题解决。

五、JSON函数返回NULL:差点让我怀疑人生

踩坑现场

迁移到JSON处理的时候,又出问题了。在Oracle中可以正常返回的JSON函数,在金仓中返回NULL。我当时都怀疑是不是我记错语法了,反复核对了好几遍代码,还是找不到问题。

错误代码示例

-- Oracle中正常返回selectjson_value('{"name":"张三","age":18}','$.name')fromdual;

解决过程

后来我去查金仓的官方文档,才发现金仓的JSON函数和Oracle的JSON函数在语法上有一些差异。金仓的JSON函数需要使用#>>操作符来获取JSON值,而不是Oracle的json_value函数。

正确代码示例

-- 金仓中正确返回JSON值select'{"name":"张三","age":18}'::json#>>'{name}' from dual;

我当时就想,这官方文档也不早点说清楚,害我浪费了一天时间。不过后来我发现金仓其实也支持json_value函数,但是需要把JSON字符串转换成JSON类型之后才能使用:

另一种正确写法

selectjson_value('{"name":"张三","age":18}'::json,'$.name')fromdual;

六、物化视图刷新异常:加班到凌晨三点的噩梦

踩坑现场

最让我崩溃的还是物化视图的问题。在Oracle中,物化视图刷新很简单,直接调用dbms_refresh.refresh函数就可以了。但是在金仓中,我调用了之后提示“函数dbms_refresh.refresh不存在”。

错误代码示例

-- Oracle中正常刷新物化视图execdbms_refresh.refresh('MV_TEST');

解决过程

我当时就蒙了,这咋回事啊?我明明已经创建了物化视图了,咋就不能刷新呢?后来去查金仓的文档,才发现金仓的物化视图刷新方式和Oracle不一样。金仓使用refresh materialized view语句来刷新物化视图,而不是dbms_refresh.refresh函数。

正确代码示例

-- 金仓中刷新物化视图refresh materializedviewMV_TEST;

还有一个问题,就是金仓的物化视图不支持快速刷新(FAST REFRESH),只能用完全刷新(COMPLETE REFRESH)。这对于大数据量的物化视图来说,刷新时间简直不能忍。我当时为了这个问题,加班到凌晨三点才弄好,最后只能把物化视图改成每天凌晨刷新一次。

七、存储过程迁移中的其他坑

触发器迁移的烦恼

在Oracle中,触发器的写法和金仓也有点不一样。比如在Oracle中,触发器可以使用:OLD:NEW来引用旧值和新值,但是在金仓中,需要使用OLDNEW来引用,而且需要在触发器中声明。

错误代码示例
-- Oracle中的触发器 create or replace trigger trg_test before insert on test_table for each row begin :new.create_time := sysdate; end; /
正确代码示例
-- 金仓中的触发器 create or replace trigger trg_test before insert on test_table for each row declare old row test_table%rowtype; new row test_table%rowtype; begin new.create_time := current_timestamp; end; /

自定义函数迁移的坑

在Oracle中,自定义函数的返回值类型可以是VARCHAR2NUMBER等,但是在金仓中,自定义函数的返回值类型需要使用VARCHARINTEGER等。我当时迁移的时候没注意这个问题,导致很多自定义函数都执行失败了。

错误代码示例
-- Oracle中的自定义函数 create or replace function func_test return varchar2 as begin return 'Hello World'; end; /
正确代码示例
-- 金仓中的自定义函数 create or replace function func_test return varchar as begin return 'Hello World'; end; /

八、性能优化的那些事

索引优化的坑

在Oracle中,索引的创建和使用都比较灵活,但是在金仓中,索引的创建和使用有一些限制。比如金仓不支持函数索引,只能使用表达式索引。我当时迁移的时候,把Oracle中的函数索引直接迁移到金仓中,结果导致索引无法使用,查询性能急剧下降。

错误代码示例
-- Oracle中的函数索引createindexidx_testontest_table(upper(name));
正确代码示例
-- 金仓中的表达式索引createindexidx_testontest_table((upper(name)));

查询优化的坑

在Oracle中,查询优化器可以自动优化查询语句,但是在金仓中,查询优化器的优化能力有限。我当时迁移的时候,很多查询语句在Oracle中运行很快,但是在金仓中运行很慢。后来我只能手动优化查询语句,比如添加索引、改写查询语句等。

优化前的查询
select*fromtest_tablewhereupper(name)='张三';
优化后的查询
select*fromtest_tablewherename='张三';

九、关于迁移的一些思考

兼容模式的陷阱

金仓的Oracle兼容模式虽然看起来很美好,但是实际上还是有很多坑的。很多在Oracle中可以正常运行的SQL语句,在金仓中就会报错。我觉得金仓的兼容模式更多的是语法上的兼容,而不是功能上的完全兼容。

文档的不足

金仓的官方文档虽然很详细,但是对于一些细节的描述还是不够。比如JSON函数的使用,文档里只是简单提了一下,没有详细的示例。我觉得金仓应该加强文档的建设,多写一些实际的案例和常见问题的解决方法。

社区的重要性

在迁移的过程中,金仓的官方论坛帮了我很大的忙。很多我遇到的问题,论坛上都有大佬分享了解决方法。我觉得金仓应该继续加强社区建设,让更多的用户可以分享自己的经验和心得。

十、未来的展望

虽然这次迁移踩了很多坑,但是总体来说还是成功的。现在系统已经上线运行了,稳定性和性能都还不错。我相信随着金仓的不断发展,它会变得越来越成熟,越来越好用。

十一、金仓社区欢迎您

如果你也在做金仓迁移,或者对金仓感兴趣,欢迎访问金仓的探索博客站:https://kingbase.com.cn/explore,这里有更多的技术文档和案例分享,希望能对你有所帮助。


写在最后:这篇文章是我在迁移过程中的真实体验,可能有些地方写得不够专业,也可能有一些错别字,但是都是我亲身经历的。希望我的分享能帮助到那些正在做金仓迁移的朋友,少踩一些坑,少走一些弯路。

http://www.jsqmd.com/news/121597/

相关文章:

  • 22、僵尸网络分析与检测:基于CWSandbox的深入洞察
  • LangFlow在企业级AI项目中的五大应用场景分析
  • Excalidraw国际化多语言包贡献指南
  • 24、僵尸网络情报资源全解析
  • Excalidraw手绘风图表+AI智能注释高效文档生成
  • Excalidraw透明度调节技巧:打造层次分明的图表
  • 26、FSTC反网络钓鱼解决方案分类解析
  • Excalidraw宠物护理表:健康管理记录
  • Excalidraw如何通过GPU加速提升AI推理速度?
  • Excalidraw镜像支持跨平台同步,移动端同样流畅
  • Excalidraw开源工具AI版支持主题切换与定制
  • LangFlow镜像上线:一键部署可视化大模型开发环境
  • LangFlow高级技巧:自定义节点与模块复用策略
  • Excalidraw镜像支持自动备份,防止数据丢失
  • Excalidraw展示数字化转型:传统企业升级路径
  • Excalidraw镜像部署完成,支持高并发协作与AI渲染
  • Excalidraw如何利用Token激励用户贡献内容?
  • 73、无线蓝牙设备的使用指南
  • Excalidraw镜像内置防DDoS机制,抵御网络攻击
  • LangFlow入门必看:快速掌握可视化LangChain开发核心技巧
  • Excalidraw镜像优化内存管理,降低GPU消耗
  • Excalidraw实时协作+AI生图,双剑合璧提升生产力
  • 74、Windows设备同步全攻略
  • Excalidraw镜像提供灰度发布能力,平稳上线AI功能
  • LangFlow镜像上线:一键部署,立即体验可视化AI开发
  • 75、设备同步与系统性能优化指南
  • Excalidraw测试用例编写:单元测试与E2E覆盖
  • Excalidraw白板工具AI版支持多人同时编辑同一图
  • 告别复杂代码:使用LangFlow轻松构建LangChain工作流
  • Excalidraw镜像提供API限流保护,防滥用