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

OpenTenBase应用落地实践:从MySQL到OpenTenBase的平滑迁移

OpenTenBase应用落地实践:从MySQL到OpenTenBase的平滑迁移

  • 项目背景
  • 应用落地
    • maven配置
    • 数据源配置
    • 初始化数据库
    • 导入数据
  • 启动项目
  • 后续优化
  • 文末总结

项目背景

随着企业核心业务(例如:电子商务平台、用户增长分析系统或实时交易系统等)的迅猛发展,数据量呈现指数级增长,业务场景也日益复杂。然而当前项目所依赖的开源MySQL数据库,在初期阶段表现稳定,完全满足了基本的事务处理和数据存储需求。

但是,在应对海量数据(TB甚至PB级)、高并发读写以及大规模在线分析处理(OLAP)场景时,传统的单机MySQL架构逐渐暴露出其瓶颈。我们主要面临以下挑战:

  • 性能瓶颈:核心业务表的数据量已逼近单机MySQL的性能上限,复杂的查询操作响应时间变长,甚至在业务高峰时段出现慢查询堆积,直接影响前端用户体验和订单转化率。

  • 扩展性限制:业务增长要求数据库具备弹性扩展能力。MySQL本身虽然可以通过主从复制实现读扩展,但在写能力和海量数据存储方面进行水平扩展非常困难,且需要复杂的应用层分库分表方案,这带来了极高的运维成本和数据一致性风险。

  • 高可用与容灾需求:单一的MySQL实例存在单点故障风险。虽然可采用主从切换机制,但其在故障自动恢复、数据零丢失等方面的保障仍需进一步完善,以满足公司对系统可靠性越来越高的要求。

为了解决上述痛点,并支撑未来五到十年的业务发展,可以考虑对项目的数据库架构进行升级改造。这里就有一个好的推荐,腾讯开源的分布式数据库OpenTenBase。

OpenTenBase(其开源版本源于PostgreSQL-XL/X2)是一款具备强一致性、高可用性且支持HTAP(混合事务/分析处理)的分布式数据库系统。它不仅能很好地兼容PostgreSQL/MySQL的语法,降低了应用改造成本,更重要的是其原生的分布式架构可以为我们提供:

  • 透明的水平扩展:轻松通过增加节点来线性提升存储能力和处理性能。

  • 强大的并行计算:能高效处理即席查询和数据分析任务,满足OLAP场景。

  • 高可用和自动容灾:多副本机制保障了数据安全,自动故障切换确保了服务连续性。

在前面的两篇文章中,我们已经掌握了OpenTenBase 从源码下载到安装部署的全流程操作以及sql语法的基础操作,那么这里我们将介绍如何将我们现有的基于开源MySQL 数据库的项目切换到 OpenTenBase。为了验证并实现将现有基于MySQL的应用平滑、安全、高效地迁移至OpenTenBase分布式集群,并在迁移后确保所有核心业务的正常运行,最终达成提升系统整体性能、可扩展性及可靠性的战略目标。

应用落地

对于OpenTenBase 分布式数据库的操作,我们可以理解为我们的操作是针对单机一样简单。下面我们就来讲述如何将我们现有项目的 MySQL 数据库切换为 OpenTenBase 数据库。 这里我们采用的项目是若依开源项目,源码项目可以直接在百度搜索下载,下面我们直接开始今天的操作吧。

maven配置

大家都知道,当需要更换数据源的话,那么肯定先要获取适配当前数据源的jar 包,对于若依开源项目,默认是maven方式管理jar 包的依赖和引入,这里我们直接到网址 https://jdbc.postgresql.org/download/ 获取 jdbc jar 包地址。不同的项目有不同的jar包引入方式,对于 maven 项目来说,可以直接通过引入 pom.xml 配置的方式实现

<dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.7.7</version>
</dependency>

对于非maven项目,则可以直接下载 jdbc jar 包
在这里插入图片描述
这里我的项目是maven 项目,那么我可以直接在 pom.xml 中引入 opentenbase jdbc jar 包配置并刷新maven 仓库
在这里插入图片描述

数据源配置

在完成了maven 引入 jdbc 依赖包之后,下面我们就可以更改我们原来的MySQL 数据库驱动及数据库连接,这里的数据库链接地址我们需要使用我们腾讯云服务器部署的OpenTenBase 数据库的公网地址,登录 轻量应用服务器 控制台,获取公网IP地址
在这里插入图片描述
这里需要说明的是,OpenTenBase 数据库默认通过 30004 端口链接数据库,那么需要我们点击服务器名称,进入服务器详情页面,放开 30004 端口
在这里插入图片描述
其他端口对应GTM 、CN1、DN1 、DN2 等节点端口,这里我也直接开启了,防止后面用到的时候还要过来再设置一次。下面我们就可以来配置应用的数据源信息了。更改数据库驱动为 org.postgresql.Driver ,更改数据源链接为 jdbc:postgresql://101.43.245.198:30004/postgres?currentSchema=public&binaryTransfer=false 更改用户名&密码为 opentenbase ,其他配置暂时默认不变
在这里插入图片描述

初始化数据库

由于我们的项目过去是MySQL 开源数据库,那么使用的建表语句自然也是 MySQL 版本的,自然是不适用于 OpenTenBase 数据库,那么这里我们就可以借助我们的CodeBuddy 来帮助我们将我们的 MySQL 版本的sql 初始化数据库语句替换为适配 OpenTenBase 版本的初始化sql 语句。

选中我们需要处理的 sql 语句脚本文件,给出我们的需求【将 ry_20240601.sql 文件中的建表语句,表注释,插入数据语句全部替换成适配 opentenbase 的sql 语句,输出新的sql 文件】
在这里插入图片描述
CodeBuddy Craft 在收到我们提供的sql 脚本文件以及替换需求之后,会自动读取我们的sql 脚本文件内容,并根据对sql 文件的分析以及 (OpenTenBase 是基于 PostgreSQL 的分布式数据库,因此需要调整 SQL 语法以适配 PostgreSQL 的特性)来对我们的sql脚本文件进行改写,并输出新的sql 脚本文件
在这里插入图片描述
这里需要说明的是,由于初始化sql 脚本文件内容比较多,改写会比较费时,耐心等待。考虑到这里,为了提高改写效率,大家在进行项目数据库切换时也可以考虑逐个对表结构及初始化数据进行改写,这样,更少的内容改写更快。等待sql 都改写完成后,则可以直接导入 OpenTenBase 数据库。改写后的sql 脚本语句就像这样

-- ----------------------------
-- 字典数据表
-- ----------------------------DO $$
BEGINIF EXISTS (SELECT FROM pg_tables WHERE schemaname = current_schema() AND tablename = 'sys_dict_data') THENEXECUTE 'DROP TABLE sys_dict_data';END IF;
END
$$;create table sys_dict_data
(dict_code        BIGSERIAL      not null,dict_sort        integer        default 0,dict_label       varchar(100)   default '',dict_value       varchar(100)   default '',dict_type        varchar(100)   default '',css_class        varchar(100)   default null,list_class       varchar(100)   default null,is_default       char(1)        default 'N',status           char(1)        default '0',create_by        varchar(64)    default '',create_time      timestamp,update_by        varchar(64)    default '',update_time      timestamp,remark           varchar(500)   default null,primary key (dict_code)
);COMMENT ON TABLE sys_dict_data IS '字典数据表';
COMMENT ON COLUMN sys_dict_data.dict_code IS '字典编码';
COMMENT ON COLUMN sys_dict_data.dict_sort IS '字典排序';COMMENT ON COLUMN sys_dict_data.dict_label IS '字典标签';
COMMENT ON COLUMN sys_dict_data.dict_value IS '字典键值';
COMMENT ON COLUMN sys_dict_data.dict_type IS '字典类型';
COMMENT ON COLUMN sys_dict_data.css_class IS '样式属性(其他样式扩展)';
COMMENT ON COLUMN sys_dict_data.list_class IS '表格回显样式';
COMMENT ON COLUMN sys_dict_data.is_default IS '是否默认(Y是 N否)';COMMENT ON COLUMN sys_dict_data.status IS '状态(0正常 1停用)';
COMMENT ON COLUMN sys_dict_data.create_by IS '创建者';
COMMENT ON COLUMN sys_dict_data.create_time IS '创建时间';COMMENT ON COLUMN sys_dict_data.update_by IS '更新者';
COMMENT ON COLUMN sys_dict_data.update_time IS '更新时间';
COMMENT ON COLUMN sys_dict_data.remark IS '备注';-- 设置序列起始值
ALTER SEQUENCE sys_dict_data_dict_code_seq RESTART WITH 100;-- 插入数据
insert into sys_dict_data values(1,  1,  '男',       '0',       'sys_user_sex',        '',   '',        'Y', '0', 'admin', CURRENT_TIMESTAMP, '', null, '性别男');
insert into sys_dict_data values(2,  2,  '女',       '1',       'sys_user_sex',        '',   '',        'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '性别女');insert into sys_dict_data values(3,  3,  '未知',     '2',       'sys_user_sex',        '',   '',        'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '性别未知');
insert into sys_dict_data values(4,  1,  '显示',     '0',       'sys_show_hide',       '',   'primary', 'Y', '0', 'admin', CURRENT_TIMESTAMP, '', null, '显示菜单');
insert into sys_dict_data values(5,  2,  '隐藏',     '1',       'sys_show_hide',       '',   'danger',  'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '隐藏菜单');insert into sys_dict_data values(6,  1,  '正常',     '0',       'sys_normal_disable',  '',   'primary', 'Y', '0', 'admin', CURRENT_TIMESTAMP, '', null, '正常状态');
insert into sys_dict_data values(7,  2,  '停用',     '1',       'sys_normal_disable',  '',   'danger',  'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '停用状态');
insert into sys_dict_data values(8,  1,  '正常',     '0',       'sys_job_status',      '',   'primary', 'Y', '0', 'admin', CURRENT_TIMESTAMP, '', null, '正常状态');
insert into sys_dict_data values(9,  2,  '暂停',     '1',       'sys_job_status',      '',   'danger',  'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '停用状态');
insert into sys_dict_data values(10, 1,  '默认',     'DEFAULT', 'sys_job_group',       '',   '',        'Y', '0', 'admin', CURRENT_TIMESTAMP, '', null, '默认分组');insert into sys_dict_data values(11, 2,  '系统',     'SYSTEM',  'sys_job_group',       '',   '',        'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '系统分组');
insert into sys_dict_data values(12, 1,  '是',       'Y',       'sys_yes_no',          '',   'primary', 'Y', '0', 'admin', CURRENT_TIMESTAMP, '', null, '系统默认是');
insert into sys_dict_data values(13, 2,  '否',       'N',       'sys_yes_no',          '',   'danger',  'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '系统默认否');insert into sys_dict_data values(14, 1,  '通知',     '1',       'sys_notice_type',     '',   'warning', 'Y', '0', 'admin', CURRENT_TIMESTAMP, '', null, '通知');
insert into sys_dict_data values(15, 2,  '公告',     '2',       'sys_notice_type',     '',   'success', 'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '公告');
insert into sys_dict_data values(16, 1,  '正常',     '0',       'sys_notice_status',   '',   'primary', 'Y', '0', 'admin', CURRENT_TIMESTAMP, '', null, '正常状态');
insert into sys_dict_data values(17, 2,  '关闭',     '1',       'sys_notice_status',   '',   'danger',  'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '关闭状态');
insert into sys_dict_data values(18, 99, '其他',     '0',       'sys_oper_type',       '',   'info',    'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '其他操作');
insert into sys_dict_data values(19, 1,  '新增',     '1',       'sys_oper_type',       '',   'info',    'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '新增操作');
insert into sys_dict_data values(20, 2,  '修改',     '2',       'sys_oper_type',       '',   'info',    'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '修改操作');
insert into sys_dict_data values(21, 3,  '删除',     '3',       'sys_oper_type',       '',   'danger',  'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '删除操作');
insert into sys_dict_data values(22, 4,  '授权',     '4',       'sys_oper_type',       '',   'primary', 'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '授权操作');
insert into sys_dict_data values(23, 5,  '导出',     '5',       'sys_oper_type',       '',   'warning', 'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '导出操作');
insert into sys_dict_data values(24, 6,  '导入',     '6',       'sys_oper_type',       '',   'warning', 'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '导入操作');
insert into sys_dict_data values(25, 7,  '强退',     '7',       'sys_oper_type',       '',   'danger',  'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '强退操作');
insert into sys_dict_data values(26, 8,  '生成代码', '8',       'sys_oper_type',       '',   'warning', 'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '生成操作');insert into sys_dict_data values(27, 9,  '清空数据', '9',       'sys_oper_type',       '',   'danger',  'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '清空操作');
insert into sys_dict_data values(28, 1,  '成功',     '0',       'sys_common_status',   '',   'primary', 'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '正常状态');
insert into sys_dict_data values(29, 2,  '失败',     '1',       'sys_common_status',   '',   'danger',  'N', '0', 'admin', CURRENT_TIMESTAMP, '', null, '停用状态');

其中,sql 语句则是为了避免下面导入数据时的错误提示信息 NOTICE: table “sys_dict_data” does not exist, skipping

DO $$BEGINIF EXISTS (SELECT FROM pg_tables WHERE schemaname = current_schema() AND tablename = 'sys_dict_data') THENEXECUTE 'DROP TABLE sys_dict_data';END IF;
END
$$;

导入数据

这里我们使用 psql 命令通过 sql 脚本导入数据,psql是一个基于终端的 OpenTenBase 客户端工具,类似Oracle中的命令行工具sqlplus,但比sqlplus强大多了。它让你能交互式地键入查询,把它们发送给 OpenTenBase ,并且查看查询结果。或者,输入可以来自于一个文件或者命令行参数。此外,psql还提供一些元命令和多种类似 shell 的特性来为编写脚本和自动化多种任务提供便利。psql还支持命令补全,历史命令回找。

psql语句通过 sql 脚本导入数据分为在外部执行和在内部执行两种形式,我们首先需要将我们的sql 文件上传至轻量应用服务器
在这里插入图片描述
上传完成后通过命令来导入 sql 脚本数据

# 在外部执行psql -h 10.2.24.16 -p 30004 -d postgres -U opentenbase -f /data/opentenbase/ry_opentenbase_20240601.sql
# 在内部执行psql -h 10.2.24.16 -p 30004 -d postgres -U opentenbase
postgres=# \i  /data/opentenbase/ry_opentenbase_20240601.sql 

执行结果如图,其中红框选中的不是报错信息,这个提示信息 NOTICE: table “sys_config” does not exist, skipping 是在执行 DROP TABLE IF EXISTS 语句时产生的,这是一个正常的通知,不是错误。在 PostgreSQL 中,当尝试删除不存在的表时,会产生这个通知
在这里插入图片描述

启动项目

在上面我们为我们的本地项目切换 MySQL 数据源到 OpenTenBase 数据源,同时借助CodeBuddy 将 MySQL 初始化数据 sql 脚本替换为 适配 OpenTenBase sql 语句脚本的数据库后执行数据初始化。下面我们就可以来尝试启动我们的项目了。等待项目启动成功
在这里插入图片描述
启动成功后我们可以在浏览器中输入访问地址来访问我们的项目了
在这里插入图片描述
到这里,可以说我们的项目已经从 MySQL 数据源切换到了 OpenTenBase,整个操作过程实际上并不复杂,比较简单容易实现。

后续优化

当然,不是说我们的项目到这里就算完成了,这只是完成了启动项目的第一步,后面则需要在此基础上进行功能的拓展开发。比如这里我们先尝试登录项目,结果报错了
在这里插入图片描述
这不是说我们的项目有问题,而是在项目切换为 OpenTenBase 数据源之后,原来项目代码中的 MySQL sql 语句还需要进行一个简单的转化才可以用,比如这里我们看到 sql 语句 插入用户登录日志时报错了,那么我们可以将错误信息以及sql 语句都复制到 CodeBuddy AI 对话框,让CodeBuddy 来帮助我们处理
在这里插入图片描述
经过CodeBuddy 对报错信息的分析处理之后,考虑到来使用 sysdate() 函数的 mapper.xml 文件比较多,为了让整个项目从 MySQL 过渡到 OpenTenBase 过渡的更加丝滑,CodeBuddy 为我们查找所有 mapper.xml 文件中 sysdate() 函数 并替换为 now() ,方便快捷
在这里插入图片描述
替换完成后我们重启项目再次尝试登录,这次虽然登录成功了,但是又出现了其他的sql 语法兼容问题,比如这样
在这里插入图片描述
同样的办法,我们将错误信息直接复制到 CodeBuddy AI 对话框,让我们的Craft 来帮助我们分析处理ifnull 函数不存在的问题。后面遇到类似的sql 语法不兼容情况,同样处理即可。这里我就不再逐个处理每一个报错信息了。

文末总结

在前面讲述了通过下载OpenTenBase 数据库源码并编译、部署以及基础 sql 语句操作功能,今天我们带来的是 OpenTenBase 数据库在实际项目中的应用。通过若依开源项目来详细介绍了项目 jdbc 数据库连接jar 包的接入,项目数据源切换为 OpenTenBase 的操作,以及将项目原来的 MySQL sql 初始化脚本替换为适配 OpenTenBase 数据库初始化的 sql 脚本,最后导入OpenTenBase 数据库。随后又通过在实际项目中排查 从 MySQL 切换到 OpenTenBase 数据源之后的 sql 语法不兼容问题。从OpenTenBase 部署到项目落地,整个操作过程对于一个技术人员来说,没什么卡壳的地方,落地实际应用项目圆满完成。


文章转载自:

http://gc0K6eR5.fmysr.cn
http://g3NFRchs.fmysr.cn
http://1YZ2g4Jf.fmysr.cn
http://3XqOWdUE.fmysr.cn
http://R6PVR29m.fmysr.cn
http://z8GMFgHX.fmysr.cn
http://6faLuFlB.fmysr.cn
http://hG1nJJ4u.fmysr.cn
http://yBDZaZRt.fmysr.cn
http://N30plPtw.fmysr.cn
http://NO0gSsoI.fmysr.cn
http://DksBuLoj.fmysr.cn
http://8CxxmSae.fmysr.cn
http://67yN6EBC.fmysr.cn
http://KhGSF5vu.fmysr.cn
http://xHyFktw3.fmysr.cn
http://nbTciJlA.fmysr.cn
http://pmOvF8yb.fmysr.cn
http://mbZ40IDo.fmysr.cn
http://FyqbJzQo.fmysr.cn
http://WQFzjwih.fmysr.cn
http://jQO3tPmw.fmysr.cn
http://fFJZ8wcS.fmysr.cn
http://HAwlCZEG.fmysr.cn
http://x9w9HVsx.fmysr.cn
http://K41a4LMF.fmysr.cn
http://BBvlMjOv.fmysr.cn
http://Hbokrq6m.fmysr.cn
http://J5iVSkAl.fmysr.cn
http://TLgr9L9V.fmysr.cn
http://www.dtcms.com/a/381948.html

相关文章:

  • Redis常用数据结构及其底层实现
  • 深度卷积生成对抗网络
  • 打造精简高效的 uni-app 网络请求工具
  • 基于ZIGBEE的智能太阳能路灯系统设计(论文+源码)
  • Linux 磁盘I/O高占用进程排查指南:从定位到分析的完整流程
  • 20250913-02: Langchain概念:表达式语言(LCEL)
  • 【YOLO目标检测】获取COCO指标
  • React 18 过渡更新:并发渲染的艺术
  • node.js卸载并重新安装(超详细图文步骤)
  • 【CSS学习笔记3】css特性
  • k8s-Sidecar容器学习
  • 坦克大战的学习
  • 如何进行WEB安全性测试
  • 使用UV工具安装和管理Python环境
  • WPS中接入DeepSeek:方法与实践
  • hexo文章
  • Armonia Mall超级数字生态WEB3商城的引领者
  • Python核心技术开发指南(063)——析构方法
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(32):文法運用第9回4+(考え方12)
  • 漫谈《数字图像处理》之形状数的原理与计算方法
  • go-commons GitHub 开源项目
  • 飞算Java AI一天从零到项目生成的Java开发加速器
  • Transformer实战(18)——微调Transformer语言模型进行回归分析
  • 通过语法推导树快速求短语,简单短语和句柄
  • 考研择校考虑因素和备考流程
  • Django全栈班v1.04 Python基础语法 20250913 早上
  • 界面规范10-树
  • 计算机组成原理:存储系统概述
  • 《Vuejs设计与实现》第 15 章(编译器核心技术)下
  • Android自定义View-圆形渐变多点的加载框