迁移篇 | MatrixOne与MySQL全面对比

Part 1 迁移背景

Skyable 自研了物联网私有云平台用于 IoT 设备的数据上报和协议解析,由于管理设备数量的增加导致设备上报的数据量越来越大,架构中原使用的 MySQL 数据库(分库分表)的部分业务在对设备上报信息进行相关的查询时,查询速度很慢,且会偶发出现查询不出来的情况,无法通过优化SQL来提升数据库性能,非常影响系统体验。为了尽可能少的调整业务,需要寻找一款高度兼容 MySQL 协议且能够支持大数据量查询的数据库进行切换,通过调研我们选择了 MatrixOne 数据库,选择的主要原因如下:

  • 兼容MySQL协议 :完全兼容MySQL协议,项目中使用了 MyBatis、MyBatis Plus 作为 ORM 框架,只需通过少量的改动即可进行数据源的切换。
  • 高可用 :MatrixOne 通过纠删码进行数据冗余校验,同步事务日志采用 Raft 协议,只有多数派写入成功,事务才能提交,这确保了数据的强一致性,即使少数副本发生故障也不影响数据的可用性,只需要 150% 的数据冗余即可实现高可用,更节省硬盘空间。
    此外,MatrixOne 支持 K8s 部署高可用架构的集群,后期也可以使用 IoT 平台的 K8s 底座进行统一管理。
  • HTAP支持 :MySQL 的 OLAP 特性基于新一代 MySQL Heatwave 服务。要实现 OLAP 特性,必须单独部署一套 MySQL Heatwave 服务集群,增加了运维难度和系统复杂度。
    MatrixOne 通过云原生化和存储、计算、事务分离的架构构建 HSTAP 超融合数据引擎,实现单一数据库系统支持 OLTP 与 OLAP,不需要额外的组件支持,降低了系统复杂度。

在调研前,我们模拟当前业务使用 MatrixOne 和 MySQL 进行了对比测试,测试发现 MatirxOne 的事务处理能力约为 MySQL 的 90%,但查询分析能力是 MySQL 的五倍以上,非常符合当前平台的业务需求。

Part 2 本地部署

IoT 私有云项目因为网络策略限制,不允许在Linux系统中使用外网,因此部署时使用 MatrixOne 提供的二进制包部署。MatrixOne的二进制包解压即用,部署非常简单,还提供了用于服务启停和运维的mo_ctl工具。以当前最新的 MatrixOne 1.1.0 为例,我们将所需的二进制包和 mo_ctl 工具上传至目标服务器,例如 /opt 目录:

[root@iot01 opt]# ll -h
total 51M
-rw-r--r-- 1 root root 6.8K Jan  1 21:44 install.sh
-rw-r--r-- 1 root root  72K Jan  1 21:44 mo_ctl.zip
-rw-r--r-- 1 root root  51M Dec 29 17:06 mo-v1.1.0-linux-x86_64.zip

下载地址分别为:

wget https://raw.githubusercontent.com/matrixorigin/mo_ctl_standalone/main/install.sh
wget https://github.com/matrixorigin/mo_ctl_standalone/archive/refs/heads/main.zip -O mo_ctl.zip
wget https://github.com/matrixorigin/matrixone/releases/download/v1.1.0/mo-v1.1.0-linux-x86_64.zip

解压 MatrixOne 安装包,并重命名解压后的目录:

[root@iot01 opt]# unzip mo-v1.1.0-linux-x86_64.zip
[root@iot01 opt]# mv mo-v1.1.0-linux-x86_64 matrixone

安装 mo_ctl 工具:

[root@iot01 opt]# bash +x ./install.sh mo_ctl.zip

为 mo_ctl 配置 matrixone 所在目录,例如:

mo_ctl set_conf MO_PATH="/opt"

MatrixOne 没有自带客户端,在本地需要使用 mysql client 来进行访问,若没有的需要提前准备,就绪后可直接通过 mo_ctl 工具启动MatrixOne 服务:

[root@node01 opt]# mo_ctl start
2024-01-01 21:58:09.606 UTC+0800    [INFO]    No mo-service is running
2024-01-01 21:58:09.651 UTC+0800    [INFO]    GO memory limit(Mi): 36050
2024-01-01 21:58:09.669 UTC+0800    [INFO]    Starting mo-service: cd /opt/matrixone/ && GOMEMLIMIT=36050MiB /opt/matrixone/mo-service -daemon -debug-http :9876 -launch /opt/matrixone/etc/launch/launch.toml >/opt/matrixone/logs/stdout-20240101_215809.log 2>/opt/matrixone/logs/stderr-20240101_215809.log
2024-01-01 21:58:09.748 UTC+0800    [INFO]    Wait for 2 seconds
2024-01-01 21:58:11.800 UTC+0800    [INFO]    At least one mo-service is running. Process info: 
root      10064      1 51 21:58 ?        00:00:01 /opt/matrixone/mo-service -daemon -debug-http :9876 -launch /opt/matrixone/etc/launch/launch.toml
2024-01-01 21:58:11.810 UTC+0800    [INFO]    List of pid(s): 
10064
2024-01-01 21:58:11.820 UTC+0800    [INFO]    Start succeeded

MatrixOne 首次启动到服务就绪会需要10秒左右的时间,稍作等待后即可通过 mo_ctl 进行访问:

[root@node01 opt]# mo_ctl connect
2024-01-01 22:00:02.685 UTC+0800    [INFO]    Checking connectivity
2024-01-01 22:00:02.708 UTC+0800    [INFO]    Ok, connecting for user ... 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 15021
Server version: 8.0.30-MatrixOne-v1.1.0 MatrixOne

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

MatrixOne 默认启用的用户名为 root,初始密码为 111,监听端口为 6001。使用 mo\_ctl 连接后即可进行后续的业务迁移和开发。

Part 3 迁移步骤

在 IoT 项目迁移初期,MatrixOne 版本刚迭代至 0.8 版本,验证迁移步骤有些许麻烦。后续反馈至 MatirxOne 社区后,社区的研发和支持同学也给予了大量的帮助,同时针对迁移过程中的问题及时合入了大量提升易用性的PR,以下为业务实际的迁移动作。

1. 创建数据库

首先根据项目,在MatrixOne中进行创建相关的数据库,这里针对cloud_server服务的数据库进行创建,建库示例如下:

# 原 MySQL建库语句
create database if NOT EXISTS `cloud_server` default character set utf8mb4 collate utf8mb4_unicode_ci;

# MatrixOne 建库语句
create database if NOT EXISTS `cloud_server`;

2. 表结构调整

对数据库建表语句进行调整,主要对MySQL的索引类型、表引擎、默认字符集等信息进行调整,下面针对cloud_server服务对MySQL数据表结构进行迁移,步骤如下:

Step 1 - 通过Navicat导出MySQL数据库相关表结构和数据:

Step 2 - MatrixOne 0.8 版本需要对 MySQL 中导出的建表语句进行调整,主要调整 MySQL 的索引类型、表引擎、默认字符集等信息。在反馈MatrixOne社区后,社区对关键字等进行了兼容,1.0+ 版本已不需要进行改写,可直接使用 MySQL 的建表在 MatrixOne 中进行建表,MatrixOne会自动忽视建表中MySQL独有的关键字。导出的MySQL语句示例如下:

-- MySQL语句
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for uds_service_info
-- ----------------------------
DROP TABLE IF EXISTS `uds_service_info`;
CREATE TABLE `uds_service_info`  (
  `service_id` bigint unsigned NOT NULL COMMENT '主键',
  `service_name` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '服务名称',
  `description` varchar(1024) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '描述',
  `domain_id` int(0) NOT NULL COMMENT '主域ID',
  `memory_bytes` int(0) NULL DEFAULT NULL COMMENT '内存大小',
  `instance_num` int(0) NULL DEFAULT 0 COMMENT '实例数',
  `log_level` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '日志级别',
  `access_key` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT 'ACCESS KEY',
  `access_secret` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT 'ACCESS SECRET',
  `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`service_id`) USING BTREE,
  UNIQUE INDEX `dev_proj_srv_idx`(`service_name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '服务信息表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of uds_service_info
-- ----------------------------
INSERT INTO `uds_service_info` VALUES (1, 'test-uds', '', 0, 536870912, 1, 'INFO', 'QtKMOYcQGMq8g3wnAAVAtQiG58GixniB', '9qq56Y0zmooOqQcTggSgq9lmqOOl13lrugq9Oy0gG9l05qOn6533qC6Q3VmfS6Gl', '2023-07-24 18:13:50', '2023-07-24 18:13:50');
INSERT INTO `uds_service_info` VALUES (2, 'uds-1', '', 81, 536870912, 1, 'INFO', 'TfMrNJ7porGaGf47NpkR43awlGrv9e8p', 'SkuWhvvBLWDODkLvh8zbLSOBfZWyXXLBL8SXLZb5ERX8kzLShhUNpXhuXpRuLLyp', '2023-08-09 14:44:16', '2023-08-09 14:44:16');

-- ----------------------------
-- Table structure for uds_service_version_info
-- ----------------------------
DROP TABLE IF EXISTS `uds_service_version_info`;
CREATE TABLE `uds_service_version_info`  (
  `version_id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '版本ID',
  `service_id` bigint(0) NOT NULL DEFAULT 0 COMMENT '服务ID',
  `domain_id` int(0) NOT NULL COMMENT '主域ID',
  `major_version` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '0' COMMENT '主版本号',
  `minor_version` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '0' COMMENT '副版本号',
  `patch_version` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '0' COMMENT '修订版本号',
  `description` varchar(1024) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '描述',
  `image_id` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '镜像ID',
  `image_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '镜像名称',
  `memory_bytes` bigint(0) NULL DEFAULT NULL,
  `instance_num` int(0) NULL DEFAULT NULL,
  `log_level` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  `docker_service_id` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT 'docker服务ID',
  `status` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '版本状态',
  `image_status` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '镜像状态',
  `md5` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '文件MD5值',
  `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`version_id`) USING BTREE,
  UNIQUE INDEX `serv_major_minor_patch_idx`(`service_id`, `major_version`, `minor_version`, `patch_version`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci COMMENT = '服务版本表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of uds_service_version_info
-- ----------------------------
INSERT INTO `uds_service_version_info` VALUES (1, 2, 81, '1', '0', '1', '测试', NULL, '192.168.110.244:5000/uds/81/uds-1:v1.0.1', 536870912, 1, 'INFO', NULL, 'init', 'downloadFail', NULL, '2023-08-10 13:49:40', '2023-08-10 13:49:40');

-- ----------------------------
-- Table structure for web_application
-- ----------------------------
DROP TABLE IF EXISTS `web_application`;
CREATE TABLE `web_application`  (
  `id` bigint unsigned NOT NULL COMMENT '主键',
  `domain_id` int(0) NOT NULL COMMENT '主域ID',
  `application_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '服务名称',
  `language_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '语言类型',
  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `web_application_name`(`application_name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for web_application_version
-- ----------------------------
DROP TABLE IF EXISTS `web_application_version`;
CREATE TABLE `web_application_version`  (
  `version_id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `domain_id` int(0) NOT NULL COMMENT '主域ID',
  `web_application_id` int(0) NOT NULL COMMENT 'web服务ID',
  `major_version` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '主版本',
  `minor_version` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '副版本',
  `patch_version` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '修订版本',
  `index_directory` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '首页位置',
  `status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '版本状态',
  `image_status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '镜像状态',
  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述',
  `image_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '镜像ID',
  `image_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '镜像名称',
  `docker_service_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '服务ID',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`version_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

修改后的MatrixOne语句如下:

-- MatrixOne语句
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for uds_service_info
-- ----------------------------
DROP TABLE IF EXISTS `uds_service_info`;
CREATE TABLE `uds_service_info`  (
  `service_id` bigint unsigned NOT NULL COMMENT '主键',
  `service_name` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '服务名称',
  `description` varchar(1024) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '描述',
  `domain_id` int(0) NOT NULL COMMENT '主域ID',
  `memory_bytes` int(0) NULL DEFAULT NULL COMMENT '内存大小',
  `instance_num` int(0) NULL DEFAULT 0 COMMENT '实例数',
  `log_level` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT '' COMMENT '日志级别',
  `access_key` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT 'ACCESS KEY',
  `access_secret` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT 'ACCESS SECRET',
  `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`service_id`) ,
  UNIQUE INDEX `dev_proj_srv_idx`(`service_name`) 
) COMMENT = '服务信息表';

-- ----------------------------
-- Records of uds_service_info
-- ----------------------------
INSERT INTO `uds_service_info` VALUES (1, 'test-uds', '', 0, 536870912, 1, 'INFO', 'QtKMOYcQGMq8g3wnAAVAtQiG58GixniB', '9qq56Y0zmooOqQcTggSgq9lmqOOl13lrugq9Oy0gG9l05qOn6533qC6Q3VmfS6Gl', '2023-07-24 18:13:50', '2023-07-24 18:13:50');
INSERT INTO `uds_service_info` VALUES (2, 'uds-1', '', 81, 536870912, 1, 'INFO', 'TfMrNJ7porGaGf47NpkR43awlGrv9e8p', 'SkuWhvvBLWDODkLvh8zbLSOBfZWyXXLBL8SXLZb5ERX8kzLShhUNpXhuXpRuLLyp', '2023-08-09 14:44:16', '2023-08-09 14:44:16');

-- ----------------------------
-- Table structure for uds_service_version_info
-- ----------------------------
DROP TABLE IF EXISTS `uds_service_version_info`;
CREATE TABLE `uds_service_version_info`  (
  `version_id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '版本ID',
  `service_id` bigint(0) NOT NULL DEFAULT 0 COMMENT '服务ID',
  `domain_id` int(0) NOT NULL COMMENT '主域ID',
  `major_version` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '0' COMMENT '主版本号',
  `minor_version` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '0' COMMENT '副版本号',
  `patch_version` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '0' COMMENT '修订版本号',
  `description` varchar(1024) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT '' COMMENT '描述',
  `image_id` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '镜像ID',
  `image_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '镜像名称',
  `memory_bytes` bigint(0) NULL DEFAULT NULL,
  `instance_num` int(0) NULL DEFAULT NULL,
  `log_level` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
  `docker_service_id` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT 'docker服务ID',
  `status` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '版本状态',
  `image_status` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '镜像状态',
  `md5` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL COMMENT '文件MD5值',
  `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`version_id`) ,
  UNIQUE INDEX `serv_major_minor_patch_idx`(`service_id`, `major_version`, `minor_version`, `patch_version`) 
) COMMENT = '服务版本表';

-- ----------------------------
-- Records of uds_service_version_info
-- ----------------------------
INSERT INTO `uds_service_version_info` VALUES (1, 2, 81, '1', '0', '1', '测试', NULL, '192.168.110.244:5000/uds/81/uds-1:v1.0.1', 536870912, 1, 'INFO', NULL, 'init', 'downloadFail', NULL, '2023-08-10 13:49:40', '2023-08-10 13:49:40');

-- ----------------------------
-- Table structure for web_application
-- ----------------------------
DROP TABLE IF EXISTS `web_application`;
CREATE TABLE `web_application`  (
  `id` bigint unsigned NOT NULL COMMENT '主键',
  `domain_id` int(0) NOT NULL COMMENT '主域ID',
  `application_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '服务名称',
  `language_type` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '语言类型',
  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `web_application_name`(`application_name`) 
) ;

-- ----------------------------
-- Table structure for web_application_version
-- ----------------------------
DROP TABLE IF EXISTS `web_application_version`;
CREATE TABLE `web_application_version`  (
  `version_id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `domain_id` int(0) NOT NULL COMMENT '主域ID',
  `web_application_id` int(0) NOT NULL COMMENT 'web服务ID',
  `major_version` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '主版本',
  `minor_version` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '副版本',
  `patch_version` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '修订版本',
  `index_directory` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '首页位置',
  `status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '版本状态',
  `image_status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '镜像状态',
  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述',
  `image_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '镜像ID',
  `image_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '镜像名称',
  `docker_service_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '服务ID',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`version_id`) 
) ;

SET FOREIGN_KEY_CHECKS = 1;

3. 表数据迁移

表结构调整完成后,执行调整后的SQL语句进行表的创建和表数据的导入,下面针对 cloud_server 服务对 MySQL 表结构数据进行迁移,执行调整后的sql文件,所有语句均可执行成功,执行完成后,查询相应的表数据是否已经成功导入,这里以 uds_service_info 演示表为例查看数据:

可以看到 MySQL 表中的数据已经成功导入到 MatrixOne 数据库中。

此外,1.0+ 版本的 MatrixOne 对各个数据库可视化工具进行了适配,数据迁移将更加便捷。我们选择以 Navicat 工具进行后续其他业务的迁移,仍以 cloud_server 服务相关的库表为例,操作步骤如下:

Step 1 - 首先,需要在MatrixOne中创建相应的数据库

create database if NOT EXISTS `cloud_server` default character set utf8mb4 collate utf8mb4_unicode_ci;

Step 2 - 借助Navicat中的 "工具" --> "数据传输" 功能对数据进行迁移

Step 3 - 选择需要迁移的源数据库和目标数据库后,点击"下一步"

Step 4 - 选择需要迁移源数据库中的哪些表,这里选择全部表,然后点击"开始"

Step 5 - 等待数据传输完成,传输完成后,查看MatrixOne数据库对应的表中数据是否正常迁移

可以看到数据已经正常迁移完成

4. 配置项目修改

数据迁移完成后,即可对项目中的数据源进行切换,只需对项目中的MySQL配置进行修改,修改数据库的IP、端口、用户名和密码即可,针对 cloud_server 中的配置修改如下:

#MySQL数据库配置
datasource:
  type: com.alibaba.druid.pool.DruidDataSource
  driver-class-name: com.mysql.cj.jdbc.Driver
  url: jdbc:mysql://127.0.0.1:3306/cloud_device?characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
  username: root
  password: *********
    
#MatrixOne数据库配置
datasource:
  type: com.alibaba.druid.pool.DruidDataSource
  driver-class-name: com.mysql.cj.jdbc.Driver
  url: jdbc:mysql://192.168.110.244:6001/cloud_device?characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
  username: root
  password: *********

5. 启动项目

配置修改完成后,即可启动项目,针对cloud_server服务启动结果如下:

2023-12-28 09:56:28,617 INFO (TomcatWebServer.java:108)- Tomcat initialized with port(s): 8085 (http)
2023-12-28 09:56:28,632 INFO (DirectJDKLog.java:173)- Initializing ProtocolHandler ["http-nio-8085"]
2023-12-28 09:56:28,632 INFO (DirectJDKLog.java:173)- Starting service [Tomcat]
2023-12-28 09:56:28,632 INFO (DirectJDKLog.java:173)- Starting Servlet engine: [Apache Tomcat/9.0.37]
…………
2023-12-28 09:56:29,251 INFO (DruidDataSource.java:991)- {dataSource-1} inited
 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.4.2 
2023-12-28 09:56:33,416 INFO (InetUtils.java:170)- Cannot determine local hostname
2023-12-28 09:56:33,554 INFO (EndpointLinksResolver.java:58)- Exposing 18 endpoint(s) beneath base path '/actuator'
2023-12-28 09:56:33,618 INFO (XxlJobConfig.java:46)- >>>>>>>>>>> xxl-job config init.
…………
2023-12-28 09:56:37,857 INFO (FrameworkServlet.java:525)- Initializing Servlet 'dispatcherServlet'
2023-12-28 09:56:37,865 INFO (FrameworkServlet.java:547)- Completed initialization in 8 ms

服务能够正常启动成功。

6. 项目展示

项目启动后,我们可以看到系统流畅的运行,部分截图如下:

首页

设备授权列表

产品物模型

租户管理

Part 4 迁移问题

但是针对某些场景,我们在迁移的过程中,MatrixOne也有少量不兼容的问题,下面列出了我们在迁移过程中遇到的一些问题以及相应的解决办法。

  • MatrixOne数据库规范,表名不能以数字开头,而在我们系统中,为了区分多租户,使用租户ID对不同租户的表进行区分,例如设备表:1_device_info(1表示租户ID为1的租户)需调整为device_info_1;所以需要对表名及代码中涉及到的相关表进行调整。
  • 项目中使用了xxl-job作为分布式定时任务服务,在执行XxlJobLogMapper.xml中 findFailJobLogIds 方法时,MatrixOne无法执行,需要对相应的SQL进行改造:
#xxl-job原SQL语句
<select id="findFailJobLogIds" resultType="long" >
   SELECT id FROM `xxl_job_log`
   WHERE !(
      (trigger_code in (0, 200) and handle_code = 0)
      OR
      (handle_code = 200)
   )
   AND `alarm_status` = 0
   ORDER BY id ASC
   LIMIT #{pagesize}
</select>

#改造后的SQL语句
<select id="findFailJobLogIds" resultType="long" >
   SELECT id FROM `xxl_job_log`
   WHERE (
      (trigger_code not in (0, 200) or handle_code != 0)
      AND
      (handle_code != 200)
      )
     AND `alarm_status` = 0
   ORDER BY id ASC
   LIMIT #{pagesize}
</select>
  • 项目中跟MyBatis Plus整合时,类中使用了 disable 关键字作为类字段,切换到MatrixOne后执行相关的SQL时,被识别为关键字导致SQL执行报错,需要对代码进行相关的处理

# 在@TableField注解中对字段进行处理:

#原项目配置
@ApiModelProperty(value = "设备启用:0;设备禁用:1")
private Boolean disable;

#切换MatrixOne后修改的配置
@ApiModelProperty(value = "设备启用:0;设备禁用:1")
@TableField(value = "`disable`")
private Boolean disable;

# 在SQL中对该字段进行处理:

#原SQL语句
@Select({
" SELECT d.name, d.physical_device_id, d.status, d.disable
FROM cloud_device.device_info_${domainId} d WHERE d.physical_device_id = #{physicalDeviceId} "
})
#修改后的SQL语句
@Select({
" SELECT d.name, d.physical_device_id, d.status, d.`disable`
FROM cloud_device.device_info_${domainId} d WHERE d.physical_device_id = #{physicalDeviceId} "
})
  • INSERT ... ON DUPLICATE KEY UPDATE 用于在向数据库表中插入数据时,如果数据已经存在,则更新该数据,否则插入新的数据
    用 Golang 语言连接 Matrixone 数据库时,驱动使用 http://github.com/go-sql-driver/mysql,执行该该类 SQL 语句时会报错:
_, err = db.Query("INSERT INTO m_user SET m_id=?, m_name=? ON DUPLICATE KEY UPDATE m_name=?;", 111, "aaaa", "bbbb")…………select failed: err[sql: expected 2 arguments, got 3]

目前先改造为通过先使用select查询有无数据,如果数据已经存在则使用update语句,否则使用insert插入新数 据。

  • 用 Golang 语言连接 Matrixone 数据库,使用驱动 http://github.com/go-sql-driver/mysql ,执行带 limit 的语句时报错:
_, err = db.Query("select * from device_info_2 limit ?,?", 0, 100)…………SQL syntax error: only int64 support in limit/offset clause

Part 5 迁移结果

针对项目的迁移,主要从便捷性和性能两方面进行说明:

  1. 首先对于迁移的便捷性而言,旧版本的MatrixOne由于没有对各个数据库可视化工具进行适配,迁移过程稍显麻烦,无法借助工具进行数据表的迁移,需要自己手动对数据库的建表语句进行调整,如果在数据表比较多的情况下,迁移起来会相对耗时。
    对于新版的MatrixOne,适配了数据库可视化工具后,整个迁移过程还是比较方便的,跟普通的MySQL数据库迁移步骤相同。
  2. 对于迁移后的性能而言,针对普通事务操作,MatrixOne执行效率与MySQL相差无几。但对于大数据量的查询,MatrixOne基于 OLAP 特性,查询效率相较于MySQL而言提升了 5 倍左右,且相同资源下未出现 SQL 结果查询不出来的情况。

当前项目运行稳定,系统状态良好,尚未出现其他稳定性问题,后续我司也计划将更多MySQL相关的业务迁移至MatrixOne。

最后,感谢迁移过程中 MatrixOne 社区提供的帮助,祝愿社区在2024年越来越好。

关于MatrixOne

MatrixOne 是一款基于云原生技术,可同时在公有云和私有云部署的多模数据库。该产品使用存算分离、读写分离、冷热分离的原创技术架构,能够在一套存储和计算系统下同时支持事务、分析、流、时序和向量等多种负载,并能够实时、按需的隔离或共享存储和计算资源。 云原生数据库MatrixOne能够帮助用户大幅简化日益复杂的IT架构,提供极简、极灵活、高性价比和高性能的数据服务。

MatrixOne企业版和MatrixOne云服务自发布以来,已经在互联网、金融、能源、制造、教育、医疗等多个行业得到应用。得益于其独特的架构设计,用户可以降低多达70%的硬件和运维成本,增加3-5倍的开发效率,同时更加灵活的响应市场需求变化和更加高效的抓住创新机会。在相同硬件投入时,MatrixOne可获得数倍以上的性能提升。

MatrixOne秉持开源开放、生态共建的理念,核心代码全部开源,全面兼容MySQL协议,并与合作伙伴打造了多个端到端解决方案,大幅降低用户的迁移和使用成本, 也帮助用户避免了供应商锁定风险。

关键词:超融合数据库、多模数据库、云原生数据库、国产数据库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/443953.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT 结合实际地图实现问答式地图检索功能基于Function calling

ChatGPT 结合实际地图实现问答式地图检索功能基于Function calling ChatGPT结合实际业务&#xff0c;主要是研发多函数调用&#xff08;Function Calling&#xff09;功能模块&#xff0c;将自定义函数通过ChatGPT 问答结果&#xff0c;实现对应函数执行&#xff0c;再次将结果…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:文本通用)

文本通用属性目前只针对包含文本元素的组件&#xff0c;设置文本样式。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 属性 名称参数类型描述fontColorResourceColor设置字体颜色。 从API version 9开…

VBA更新xlOLELinks链接的值

xlOLELinks是在Excel文档中插入对象的链接&#xff0c;该链接能够显示被插入文档的数据&#xff0c;通常情况下链接的数值会自动更新&#xff0c;但有时更新也会不及时或失效&#xff0c;这时就需要手动更新&#xff0c;如下图&#xff1a; 以插入Word文档为例&#xff0c;使用…

【漏洞复现】Laykefu客服系统任意文件上传

漏洞描述 Laykefu客服系统/admin/users/upavatar.html接口处存在文件上传漏洞,而且当请求中Cookie中的”user_name“不为空时即可绕过登录系统后台,未经身份验证的攻击者可利用此问题,上传后门文件,获取服务器权限。 免责声明 技术文章仅供参考,任何个人和组织使用网络…

js【深度解析】代码的执行顺序

代码的分类 我们将每一句要执行的 js 代码当做一个任务&#xff0c;则 js 代码可以按照其执行方式的不同&#xff0c;按下图分类 同步任务&#xff1a;立即执行的代码异步任务&#xff1a;延迟执行的代码 微任务&#xff1a;被放入微任务队列&#xff08;micro task queue&…

【记录37】VueBaiduMap 踩坑一

截图 错误 Error in callback for watcher “position.lng”: “TypeError: Cannot read properties of undefined (reading ‘setPosition’)” 解释 回调观察程序“content”时出错&#xff1a;“TypeError:无法读取未定义的属性&#xff08;读取’setContent’&#xff09;”…

设计模式-行为型模式-模版方法模式

模板方法模式&#xff0c;定义一个操作中的算法的骨架&#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。[DP] 模板方法模式是通过把不变行为搬移到超类&#xff0c;去除子类中的重复代码来体现它的优势。 //首…

L-2:插松枝(Python)

作者 陈越 单位 浙江大学 人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上&#xff0c;做成大大小小的松枝。他们的工作流程&#xff08;并不&#xff09;是这样的&#xff1a; 每人手边有一只小盒子&#xff0c;初始状态为空。每人面前有用不完的松枝干和一个推送…

《汇编语言》第3版(王爽)实验9

第9章 实验9 编程&#xff1a;在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串 ‘welcome to masm!’ assume cs:code,ds:datadata segmentdb welcome to masm!,0 data endscode segmentstart:mov ax,data mov ds,ax ;ds指向data段mov ax,0B800H ;显存空间从B800H…

LeetCode_24_中等_两两交换链表中的节点

文章目录 1. 题目2. 思路及代码实现&#xff08;Python&#xff09;2.1 递归2.2 迭代 1. 题目 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换…

windows11编译FFmpeg源码完整步骤

1.安装MSYS2 下载并安装MSYS2 安装GCC GCC安装成功 克隆FFmpeg源码 打开MSYS2终端并进入ffmpeg文件夹,然后输入./configure回车开始生成makefile

JavaEE——简单认识JS(Web API)

文章目录 一、认识什么是 WebAPI二、认识事件三、操作元素1. innerHTML 属性2. 获取 / 修改元素内容3. 获取 / 修改 元素属性4. 获取 / 修改 表单元素属性5. 获取 / 修改 样式属性6. 创建 / 删除元素 一、认识什么是 WebAPI 1.什么是API 在我们了解 WebAPI 之前&#xff0c;我们…

苍穹外卖学习-----2024/03/09

1.菜品分页查询 代码在这里 分页查询菜品 2.删除菜品 [链接]param 1、概览 本文将带你了解 Spring 中 RequestParam 注解的用法。 简单地说&#xff0c;可以使用 RequestParam 从请求中提取查询参数、表单参数甚至是多个参数。 2、示例端点 假设我们有一个端点 /api/foos&a…

二叉树遍历(前中后序的递归/非递归遍历、层序遍历)

二叉树的遍历 1. 二叉树的前序、中序、后序遍历 前、中、后序遍历又叫深度优先遍历 注&#xff1a;严格来说&#xff0c;深度优先遍历是先访问当前节点再继续递归访问&#xff0c;因此&#xff0c;只有前序遍历是严格意义上的深度优先遍历 首先需要知道下面几点&#xff1a; …

Spring学习 基础(三)MVC

5、Spring MVC 传统Web模式&#xff1a; Model:系统涉及的数据&#xff0c;也就是 dao 和 bean。View&#xff1a;展示模型中的数据&#xff0c;只是用来展示。Controller&#xff1a;处理用户请求都发送给 &#xff0c;返回数据给 JSP 并展示给用户。 随着 Spring 轻量级开发…

Vue项目实战-空间论坛(2)

项目实战 实现userlist页面 获取userlist列表&#xff0c;可使用ajax,axios 实现 这里采用ajax实现&#xff0c;需要添加Jquery依赖&#xff0c;然后在UserListView.vue中引入 在UserListView.vue组件的入口函数中定义users变量&#xff0c;并引入ref 使用ajax从云端动…

目标检测——监控下打架检测数据集

一、简述 首先&#xff0c;监控下打架检测是维护公共安全的重要手段。在公共场所、学校、监狱等地方&#xff0c;打架事件往往难以避免。通过安装打架检测监控系统&#xff0c;可以实时监控并准确识别打架事件&#xff0c;及时采取必要的应对措施&#xff0c;有效地减少打架事…

手写分布式配置中心(五)整合springboot(不自动刷新的)

springboot中使用配置方式有四种&#xff0c;分别是environment、BeanDefinition、Value、ConfigurationProperties。具体的原理可以看我之前的一篇文章https://blog.csdn.net/cjc000/article/details/132800290。代码在https://gitee.com/summer-cat001/config-center 原理 …

PTA L2-004 这是二叉搜索树吗?

一棵二叉搜索树可被递归地定义为具有下列性质的二叉树&#xff1a;对于任一结点&#xff0c; 其左子树中所有结点的键值小于该结点的键值&#xff1b;其右子树中所有结点的键值大于等于该结点的键值&#xff1b;其左右子树都是二叉搜索树。 所谓二叉搜索树的“镜像”&#xf…

减少PDF文件大小的方法,亲测巨好用!!!

周六晚上&#xff0c;导师突然发了两个pdf&#xff0c;让把大小改成1M以下&#xff01;&#xff01;&#xff01; 试了很多方法最后&#xff0c;发现了个最好使用的&#xff0c;不过需要下载下Adobe Acrobat文件编辑软件&#xff0c;下载地址如下 链接&#xff1a;https://pan.…