【真实体验】使用崖山YMP 迁移 Oracle/MySQL 至YashanDB 23.2 验证测试【YashanDB迁移体验官】

一、前言

说一下我和崖山数据库的结缘,大概在去年吧,因为我经常在墨天轮写文章,看到崖山数据库推出了一崖山体验官的活动,我就报名参加了。第一次体验了崖山数据库,也测试了我司数据库到崖山数据库的兼容性,发现崖山数据库的兼容性真的很不错的,尤其是对Oracle的兼容性做的真的挺不错。而且崖山数据库的一些命令和Oracle很兼容,对一些Oracle DBA来说上手特别容易,甚至可以说是无缝衔接。

最近受崖山数据库邀请做为【YashanDB迁移体验官】,体验了一把YMP的迁移,我也搭建了测试环境,并验证了我司一些Oracle和MySQL到崖山数据库的迁移,并参与了上周五崖山的直播和大家分享了YMP的迁移感受。

在验证测试中也发现了一些YMP的问题,也将这些问题反馈了崖山官方技术人员,他们的响应速度也是非常快,对于反馈的一些问题有些已经提交研发进行修复,给他们点个大大的赞。

下面我将为大家附上我本次迁移测试的全过程,以及对YMP的迁移感受。不足之处还望大家多多指正。

也希望大家多多支持崖山,多多支持国产数据库,只有大家齐心协力,国产数据库的将来才会越来越好。

1.1 产品介绍

根据崖山官网介绍,崖山迁移平台(Yashan Migration Platform),简称YMP,是YashanDB提供的数据库迁移产品,支持异构RDBMS与YashanDB之间进行迁移评估、离线迁移、数据校验的功能。另外,YMP提供页面可视化服务,使用者只需通过一些简单的界面操作,即可完成从评估到迁移到数据一致性评估整个流程的执行与监控,整个操作过程门槛比较低,操作比较流畅。

YMP安装后,会集成一个YashanDB内置库,该内置库的作用是用于YMP进行校验评估是需要的,不能作为业务目标库使用,建议在做数据迁移时,单独部署一套YashanDB(目标端业务库),

内置库是用于ymp在迁移评估阶段待迁移元数据的兼容度评估,不能作为业务目标库使用,做数据同步测试,部署一套YashanDB(目标端业务库)和YMP自嵌的内置库是很规范的。

当前YMP支持(Oracle、MySQL、DM)等异构库到YashanDB的迁移,也支持YashanDB到YashanDB的同构迁移。

YMP整个迁移过程包括如下 六 个主要阶段,如下图所示:

image.png

这六个主要阶段分别是:

  • 创建任务
  • 迁移评估
  • 迁移配置
  • 离线迁移
  • 校验初始化
  • 一致性校验

1.2 产品架构

在崖山官网,有如下一幅图介绍YMP的检品架构,如下所示:

image.png

根据上面产品架构显示,主要包括了(对象评估、元数据迁移、数据迁移、数据校验)等几个核心服务。

1.3 数据库版本支持

根据官网资料介绍,当前最新版YMP版本为YMP 23.2,其对异构和同构数据库有一定的版本限制,详见如下:

数据库说明
YashanDB适配YashanDB数据库v23.2版本,形态支持单机、共享集群,并兼容YashanDB数据库v22.2版本。
Oracle支持的版本为 11g,12c,19c,21c,部署形态为单机和RAC。
MySQL支持的版本为 5.6,5.7,8.0。
DM支持的版本为 8。

另外在官网【https://doc.yashandb.com/ymp/23.2/zh/产品简介/产品规格】链接页面中,也有对异构RDBMS库相应数据类型的支持。

二、外置库部署

部署外置库的目的是为将迁移评估后源端数据迁移到YashanDB后的目标端库,为保证迁移顺利,外置库存放数据目录一定要有足够存储空间。

建议将外置库和YMP内置库分开部署,推荐是将内置库和外置库部署在不同服务器上,若部署在同一台服务器,使用不同用户部署外置库和内置库。

因为条件限制,我本次选择在同一台物理测试服务器上部署外置库和YMP,两者分别部署在不同用户下,外置库选择部署在yashan用户下,内置库部署在ymp用户下。

对于外置库的安装部署,在官方文档【https://doc.yashandb.com/yashandb/23.2/zh/产品描述/产品简介.html】里有详细的介绍,本次就不再做过多赘述,只是简单描述整个安装部署过程。

1) 软件下载:

​ 截止到2024-04-25日,当前YashanDB最新版本为23.2,可在官网主页【https://www.yashandb.com/】,点击**【免费下载】根据操作系统类型下载YashanDB 个人版**,当前可供下载的类型包括X86和ARM两种类型。

2)环境准备:

​ 环境准备包括服务器系统及网络规划、系统参数调整、目录及用户规划等,服务器和操作系统的配置要满足官网服务器配置需求。

3)软件安装:

​ 崖山数据库的安装方式有命令行安装和可视化安装两种类型,数据库安装类型有(单机主备部署、分布式部署、共享集群部署)这三种部署形态,可以按照自己的业务需求选择相应的部署方式。

4)初始化环境:

​ 数据库安装部署后,需要设置环境变量、初始数据库。如在安装过程中未对监听端口进行调整,默认监听端口为1688。可根据需要设置是否开机启动,实例如下。

[yashan@dsmart install]$ ./bin/yasboot package se gen --cluster yashandb -u yashan -p yashan --ip 10.110.8.42 --port 22 --install-path /data/yashan/yasdb_home  --data-path /data/yashan/yasdb_data --begin-port 1688
 hostid   | group | node_type | node_name | listen_addr      | replication_addr | data_path               
----------------------------------------------------------------------------------------------------------
 host0001 | dbg1  | db        | 1-1       | 10.110.8.42:1688 | 10.110.8.42:1689 | /data/yashan/yasdb_data 
----------+-------+-----------+-----------+------------------+------------------+-------------------------

Generate config success

**补充:**安装YashanDB时,可通过指定-d, --child参数,展示任务以及子任务信息,以便了解部署进度。,如下所示:

[yashan@dsmart install]$ ./bin/yasboot cluster deploy -t yashandb.toml -d --child
 type  | uuid             | name               | hostid   | index             | status  | return_code | progress | cost 
------------------------------------------------------------------------------------------------------------------------
 task  | 274c34dbc58b9cbd | DeployYasdbCluster | -        | yashandb          | SUCCESS | 0           | 100      | 9    
-------+------------------+--------------------+----------+-------------------+---------+-------------+----------+------
 child | 9d1fafb987ad2b56 | DeployDBPrimary    | host0001 | yashandb.1-1      | SUCCESS | 0           | 100      | 6    
       +------------------+--------------------+----------+-------------------+---------+-------------+----------+------
       | 12f5e1c9e1bfd015 | SyncNodeConfig     | -        | yashandb          | SUCCESS | 0           | 100      | 1    
       +------------------+--------------------+----------+-------------------+---------+-------------+----------+------
       | cba90435323b808c | MonitReload        | host0001 | yashandb-host0001 | SUCCESS | 0           | 100      | 1    
-------+------------------+--------------------+----------+-------------------+---------+-------------+----------+------
task completed, status: SUCCESS 
# 返回 task completed, status: SUCCESS 表示安装成功

三、YMP部署

在官网【https://doc.yashandb.com/ymp/23.2/zh/产品简介/产品概述.html】有详细对YMP的安装部署介绍,这里根据官网文档做简要介绍。

3.1 安装前准备:

服务器配置: 安装YMP的服务器要满足官网配置要求,详见如下:

项目说明
系统CentOS 7.6以上、KylinOS V10
架构X86-64/ARM-64
CPU4核及以上
内存8G及以上
磁盘SSD(建议不小于待同步表中的最大单表数据量的三倍)

操作系统参数调整: 需确保操作系统max user processes最大用户线程数不小于65535。

 

# 查看最大用户线程数 # ulimit -u # 执行如下命令使最大用户线程数临时生效,重启后无效 # ulimit -u 65536 # 执行执行如下命令将最大用户线程数写入/etc/security/limits.conf文件,重启后参数永久生效 echo " * soft nproc 65536 * hard nproc 65536 " >> /etc/security/limits.conf

**用户准备:**创建一个用户用于安装YMP,以YMP为例,在用户创建和授权后,后续所有安装步骤均在该用户下操作。

 

# 新建YMP用户 # useradd -d /home/ymp -m ymp # passwd ymp

开放端口: 如未进行调整,YMP将采用如下端口。

YMP监听数据库监听主机间通信yasomyasagent
80908091809280938094

如无特殊需求,建议关闭服务器防火墙:

 

# 关闭防火墙 # systemctl stop firewalld # 关闭开机自启 # systemctl disable firewalld

**JDK环境准备:**YMP仅支持在JDK8或JDK11的环境下安装。

通过Java官方路径下载上述版本的JDK并安装成功后,还需配置如下环境变量:

 

# 以JDK安装路径为/usr/tools/jdk8为例 # vi /etc/profile # 在文件结尾添加如下 # export JAVA_HOME=/usr/tools/jdk8 # export PATH=$JAVA_HOME/bin:$PATH # export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar # 重新载入配置文件 # source /etc/profile # 安装成功后查看JDK版本信息 # java -version

**libaio环境准备:**YMP运行需要libaio动态库。

 

# 查看是否已安装libaio动态库 # rpm -qa | grep libaio # 若未有版本信息打印,安装libaio # yum install -y libaio


OCI环境准备(可选): 若用YMP迁移Oracle到YashanDB数据库,需要安装OCI环境。

到Oracle官网【https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html#license-lightbox】下载OCI 客户端软件。

YMP当前仅支持 OCI Version 19.19.0.0.0及以上版本。

上传安装包至YMP用户/home/ymp/路径。

 

# 修改安装包所属用户及用户组为ymp用户 # chown ymp:ymp instantclient-xxx # 从root用户切换至ymp用户 # su - ymp # 切换至安装路径 $ cd /home/ymp # 解压OCI安装包 $ unzip instantclient-xxx

软件包准备:请根据自己操作系统选择对应YMP软件安装包,当前YMP有Linux X86Linux ARM两个版本,最新版为 Yashan Migration Platform 23.2.1版本。

将下载的YMP软件包上传到服务器/home/ymp用户。

 

#修改安装包所属用户及用户组为ymp用户 # chown ymp:ymp yashan-migrate-platform-v23.2.1.0-linux-x86-64.zip # 从root用户切换至ymp用户 # su - ymp # 切换至安装路径 $ cd /home/ymp

客户端浏览器: YMP的操作需要浏览器支持,YMP支持当前主流浏览器,参照如下:

YMP支持浏览器Google Chrome、Microsoft Edge和Firefox,建议使用当前较新的版本。

浏览器支持要求版本
Google Chrome88 及以上版本
Microsoft Edge88 及以上版本
Firefox78 及以上版本

3.2 安装YMP

**1) 解压YMP安装包:****使用ymp用户解压YMP安装包,操作如下:

 

# 切换至YMP安装目录 # su - ymp $ cd /home/ymp/ $ unzip yashan-migrate-platform-v23.2.1.0-linux-x86-64.zip

**2)安装参数调整:****可依据实际需要对默认内置库安装端口、启动参数、密码登进行设置,其中有两个文件非常重要,如下所示:

# 文件所在目录 /home/ymp/yashan-migrate-platform/conf
db.properties: 默认内置库安装配置文件,里面包含内置库sys默认密码,默认端口号,默认字符集(UTF8),详细内容如下:
YASDB_PASSWORD=ymppw602.
YASDB_PORT=8091
YASDB_CHARACTER_SET=UTF8
## character_set optional: UTF8, ASCII, ISO88591, GBK

application.properties: YMP配置文件,该文件包含内容较多,详细内容如下
# YMP服务端口
server.port=8090

# 用户登录后空闲过期时间,单位秒(s),默认15分钟
shiro.session.timeout=900
# YMP使用的最大堆内存,单位: GB
ymp_memory=4
# YMP使用的堆外内存,单位: GB
ymp_direct_memory=2

# ========================================YMP业务数据库=============================================
# YMP业务数据库连接信息
spring.datasource.url=jdbc:yasdb://127.0.0.1:8091/yashan
spring.datasource.username=YMP_DEFAULT
spring.datasource.password=ymppw602
spring.datasource.largePoolSize=64M
spring.datasource.cursorPoolSize=64M
# 默认内置库表类型,默认HEAP,可选HEAP,TAC,LSC
spring.datasource.defaultTableType=HEAP
spring.datasource.openCursors=3000
spring.datasource.sharePoolSize=2G
spring.datasource.dateFormat=yyyy-mm-dd hh24:mi:ss
spring.datasource.ddlLockTimeout=2

# ========================================评估=============================================

# YMP的最大并行任务数
task.parallel.max-num=500
# 预计数据迁移速度,KB/s。修改会影响评估结果预计迁移时间的大小
commons.dataMigrateSpeed=51200
# 预计对象迁移速度,number/s。修改会影响评估结果预计迁移时间的大小
commons.objMigrateSpeed=200
# 评估任务单个会话获取DDL的数量,如果Oracle性能较差,则需要降低该值
assessment.ddlCount=50
# 评估任务最多同时拥有的会话数,如果Oracle性能较差,则需要降低该值
assessment.maxThreadCount=20
# 内置库表类型是否为LSC,默认为false
isLscTable=false
# 拦截的Oracle数据源db/schema黑名单
schemaBlackList.oracle=ANONYMOUS,APEX_030200,APEX_PUBLIC_USER,APPQOSSYS,BI,CTXSYS,DBSNMP,DIP,EXFSYS,FLOWS_FILES,HR,IX,MDDATA,MDSYS,MGMT_VIEW,OE,OLAPSYS,ORACLE_OCM,ORDDATA,ORDPLUGINS,ORDSYS,OUTLN,OWBSYS,OWBSYS_AUDIT,PM,SCOTT,SH,SI_INFORMTN_SCHEMA,SPATIAL_CSW_ADMIN_USR,SPATIAL_WFS_ADMIN_USR,SYS,SYSMAN,SYSTEM,WMSYS,XDB,XS$NULL
# 拦截的MySQL数据源db/schema黑名单
schemaBlackList.mysql=information_schema,mysql,performance_schema,sys
# 拦截的dm数据源db/schema黑名单
schemaBlackList.dm=SYS,SYSDBA,SYSSSO,SYSAUDITOR,CTISYS


# ========================================迁移=============================================

# 元数据迁移过程中源端、目标端查询视图连接数。在元数据迁移过程中会有分批量的查询的动作, 需要开启多个查询连接并行查询。该参数配置元数据迁移的源端、目标端查询的并行线程数,决定了对数据库的查询最大连接数,不设置默认20
migration.parallel.query=20
# 元数据迁移过程中目标端执行创建连接数。在元数据迁移过程中会并行把对象在目标端的执行,以提升迁移效率。该参数配置元数据迁移的目标端DDL执行的并行线程数,决定了连接数据库的执行最大连接数,不设置默认20。migration.parallel.query和migration.parallel.execute的连接总和,是最终迁移过程中所有的目标端数据库连接数。
migration.parallel.execute=20
# 创建索引是否使用并行参数,true/TRUE:使用,false/FALSE:不使用
migration.parallel.createIndexUseParallel=true
# 索引创建的并行度,需要考虑migration.parallel.execute。例:migration.parallel.execute:10,migration.parallel.index: 5,表示,同时10个连接在并行建索引,每个索引的并行度是5(CREATE INDEX XXX PARALLEL 5)。不填默认CPU核数。
migration.parallel.index=5
# 数据迁移前是否将表设为nologging,默认为false
setNoLogging=false
# 导出oracle时使用的导出方式,支持 [dts, jdbc] 两种方式
export.oracle.tool=dts
# 导出时每个csv文件的行数
export.csv.exportRowsEveryFile=2000000
# 迁移成功时候是否删除csv文件
export.csv.isRemoveCsvFileInSuccess=true
# csv文件存储路径包含对schema和table的拼接,schema名或table名中包含以上字符时,将会被替换,以避免被操作系统识别错误导致迁移失败;不过这可能会使某些表(比如AA$与AA.)在替换后使用的csv文件存储路径相同,导致迁移失败(No such file or directory),可以通过重新迁移失败表来解决
export.csv.path.replacement.from=\ /'."*$
# 发生csv文件存储路径字符替换时(详见export.csv.path.replacement.from),指定替换的目标字符或字符串
export.csv.path.replacement.to=_
# 导出时大表拆分的个数
export.table.splitCount=5
# 导出时触发大表拆分的行数
export.table.splitConditionCount=10000000
# 导出时触发大表拆分的表大小(G)
export.table.splitConditionSize=5
# 导出时带lob字段大表拆分的个数
export.lobTable.splitCount=5
# 导出时触发带lob字段大表拆分的行数
export.lobTable.splitConditionCount=1000000
# 导出时触发带lob字段大表拆分的表大小(G)
export.lobTable.splitConditionSize=5
# 使用jdbc导出时每个csv文件的最大行数
export.jdbc.thresholdForSplittingFileLines=5000000
# 使用jdbc导出时每个csv文件的最大大小(M)
export.jdbc.thresholdForSplittingFileSize=3072
# #yasldr More References: http://doc.yashandb.com/yashandb/22.2/zh/%E5%B7%A5%E5%85%B7%E6%89%8B%E5%86%8C/yasldr/yasldr%E4%BD%BF%E7%94%A8%E6%8C%87%E5%AF%BC.html
# yasldr导入时的并行度
import.degree_of_parallelism=16
# yasldr导入时每批次的CSV数据行数
import.batch_size=2048
# yasldr导入方式,包括BASIC方式和BATCH方式
import.mode=BATCH
import.SENDERS=7     
import.CSV_CHUNK_SIZE=128

# ========================================校验=============================================

# 校验任务限制每个数据源支持的最大连接数
checkTask.datasource.max-connection=500
# 校验任务获取连接超时时间,单位:ms
checkTask.datasource.connection-timeout=10000
# 校验任务获取的连接池中维持的最小连接数
checkTask.datasource.minimum-idle=0
# 校验任务的最大并行任务数
checkTask.task.parallel.max-num=20
# 校验任务的子任务的最大并行任务数,即一个任务多少个表在同时校验
checkTask.subTask.parallel.max-num=200
# 校验任务的全量校验对FLOAT数据类型的校验精度
checkTask.checkFloatPrecision=6
# 校验任务的数据类型映射有一边是char数据类型就移除数据右侧空格进行对比
checkTask.isRemoveCharBlank=true

#以上两个文件参数都可以依据需要进行调整,调整后重启YMP生效。

3)YMP安装:

YMP安装时按默认方式自行安装YashanDB作为内置库。

默认内置库相关信息:

  • 部署形态:单机
  • 集群名称:ymp
  • 安装目录:/home/ymp/yashan-migrate-platform/db

YMP安装内置库有两种方式:

  • 方式一:安装内置库并启动YMP

     

    # 进入安装目录执行安装命令 $ cd /home/ymp/yashan-migrate-platform/ $ sh bin/ymp.sh install --db /home/ymp/yashandb-23.2.1.0-linux-x86_64.tar.gz

  • 方式二:安装内置库和OCI客户端并启动YMP

    # 进入安装目录执行安装命令
    $ cd /home/ymp/yashan-migrate-platform/
    $ sh bin/ymp.sh install --db /home/ymp/yashandb-personal-23.2.1.100-linux-x86_64.tar.gz --path /home/ymp/instantclient_19_19
    

    上述两种方式的安装都需要借助YashanDB软件安装压缩文件。

    **4)查看运行状态:**通过如下方式可查看YMP运行状态

    [ymp@dsmart ~]$ cd yashan-migrate-platform/
    [ymp@dsmart yashan-migrate-platform]$ sh bin/ymp.sh status
    YMP is running, pid is 9512.
    Built-in database is used, pid is 9382.
    
    # 还可以通过如下方式查看YMP版本
    [ymp@dsmart yashan-migrate-platform]$ sh bin/ymp.sh -v
    Yashan-migrate-platform version: Release v23.2.1.0
    YashanDB SQL Personal Edition Release 23.2.1.100 x86_64
    YashanDB Loader Personal Edition Release 23.2.1.100 x86_64 2d13f1d
    

四、访问YMP(崖山数据迁移平台)

4.1 设置初始密码

YMP部署后,YMP提供了账号和密码同为admin的账户,使用该账户初次登录会提示需修改初始密码,并且初始密码的设置要符合密码规范要求。

image.png

修改初始密码后,使用新密码登录YMP,主界面如下:

image.png

如希望重新设置admin密码,可通过主界面右上角**【个人中心】**进行设置,如下所示:

image.png

点击**【个人中心】**进入如下页面:

image.png

点击上图红色箭头处,可修改admin密码,如下所示:

image.png

4.2 查看YMP版本信息

在**【个人中心】**处也能查看到当前YMP版本、内置库版本、JDBC及OCI等版本信息,如下所示:

image.png

五、数据源管理

5.1 创建用户并授权

这一步操作目的主要是为连接源端数据源,评估源端对象兼容性做准备。

此处有三种迁移平台所需权限,分别如下:

  • 跨用户评估迁移权限
  • 仅本连接用户元数据评估迁移所需权限
  • 跳过评估所需权限
注:
跨用户评估迁移权限:指的是迁移平台使用的用户和需要迁移的用户不是同一个的场景
仅本连接用户元数据评估迁移所需权限:指的是迁移平台使用的用户和需要迁移的用户是同一个的场景

本次选择使用跨用户评估迁移权限,源端执行如下操作:

CREATE USER orauser IDENTIFIED BY XXXX;
GRANT CREATE SESSION TO orauser;
GRANT SELECT_CATALOG_ROLE TO orauser;
GRANT SELECT ANY TABLE TO orauser;
GRANT SELECT ANY SEQUENCE TO orauser;

5.2 添加数据源

在YMP主界面点击**【数据源管理】**,如下所示:

image.png

5.2.1 添加源端

点击上图箭头处**【添加数据源】**

image.png

参照上图信息,填写数据源名称、数据源类型、选择连接类型、源端IP和端口、数据库可以选择ServiceName或者SID,填写用户名和密码。

然后点击测试连接,成功连接会有返回提示,然后点击确认,源端数据源添加后,如下所示:

image.png

并可以对上述创建的数据源进行相应信息修改和删除数据源。

5.2.2 添加目标端

参照添加源端,设置目标端,本次我选择使用sys系统用户,如下所示:

image.png

数据源类型选择 YashanDB,端口本次采用默认端口,然后点击测试连接,成功连接会有返回提示,然后点击确认,目标端数据源添加后,如下所示:

image.png

六、任务管理

上述数据源创建后,方可进行任务管理。

6.1 创建任务

创建任务是进行数据库迁移评估的起点,首先要先创建一个迁移评估任务。点击**【任务管理】**,进入任务管理界面。

image.png

如上图所示,点击右上角 **【创建任务】**按钮创建任务,如下所示:

image.png


 

image.png


 

image.png

image.png

创建任务有四个主要选项,分别是:

  • 基础信息 包含[任务名称、源端数据库、是否评估、评估数据库(若选择外置库,需设置外置库信息)]
  • 选择评估对象 包含如表、约束、索引、视图等相关信息
  • 选择评估范围 可根据需要选择待评估的对象用户
  • 其他设置 包含[是否校验失效对象、是否忽略nologging、评估部署模式、手动DDL保留策略]

在官网链接 [ https://doc.yashandb.com/ymp/23.2/zh/用户指南/任务管理/创建任务.html ] 这部分有对上述几个主要选项的详细描述,限于篇幅,本次不做赘述。

上述信息填写后,可点击**【保存】,会暂存填写的任务信息,此时任务状态为评估编辑中。若希望进行评估,可点击【下一步:开始迁移评估】**进入迁移评估阶段,如下所示:

image.png

image.png

迁移评估结束后,会给出评估结果,如下所示:

image.png


 

image.png

image.png

本次仅为测试验证,如上图所示,在**【对象详情】界面,勾选【不兼容】,然后点击【确定】**按钮,如下所示:

image.png

然后勾选 【全选所有】,再点击又上角**【批量设置是否忽略】,选择【忽略】**,如下所示:

image.png

此时,会有如下提示,提示需要重新刷新报告,如下所示:

image.png

然后点击 【刷新报告】,待报告刷新后,点击 【下一步:迁移配置】,如下所示:

image.png

选择批量忽略不兼容对象,然后点击 【迁移配置】

6.2 迁移配置

上面点击**【下一步:迁移配置】**进入如下界面,如下所示:

注:可根据需要进行配置,本次仅为测试,绝大多数配置选择默认。

image.png


 

image.png


 

image.png


 

image.png

image.png

点击 【下一步:离线迁移】

6.3 离线迁移

在上面点击离线迁移后,进入如下界面,如下所示:

image.png

image.png

待一段时间后,迁移结束,信息如下所示:

image.png

image.png

6.4 校验初始化

点击上图**【下一步:校验初始化】**,进入如下页面,如下所示:

image.png

image.png

6.5 一致性校验

如上图所示,点击**【下一步:开始一致性校验】**,如下所示:

image.png

image.png

6.6 MySQL 迁移

上面我们主要是测试了Oracle到崖山的数据迁移,接下来我们将演示下MySQL到崖山数据库的迁移。

本次选择的MySQL库版本是 5.6,通过YMP将其迁移到yashanDB库。

6.6.1 添加数据源

参照上述Oracle迁移,在**【数据源管理】界面,添加数据源名称、选择数据源类型为MySQL,根据MySQL环境设置数据库IP和端口号、用户名和密码,【测试连接】通过,点击【确认】**保存。

image.png

6.6.2 创建任务

在**【任务管理】**界面,创建任务,如下所示:

image.png

image.png

6.6.3 迁移评估

根据上面提示设置后,点击**【下一步:开始迁移评估】**,进入迁移评估阶段,如下所示,会对MySQL迁移到yashanDB的对象进行兼容性评估,如下所示。

image.png

根据上面的评估结果,可以查看哪些对象不兼容,选择“不兼容”在**【对象详情】菜单,选择【评估结果】**项,勾选“不兼容”选项,如下所示:

image.png

如果是生产迁移,一定要对不兼容对象进行兼容处理。

本次作为测试,对于不兼容类型,选择忽略,首先勾选**【全选所有】,然后再【批量设置是否忽略】选项,勾选【忽略】**,如下所示:

image.png

忽略全部不兼容对象后,需要重新刷新报告,如下所示:

image.png

重新刷新报告,重新评估后,结果如下所示:

image.png

只有兼容占比达到100%,才可以选择迁移配置。

6.6.4 迁移配置

上述迁移评估完成后,点击【下一步:迁移配置】,进入迁移配置界面,如下所示:

image.png


 

image.png

image.png

如上所示,在**【目标端数据库及迁移范围】选择yashanDB外智库,在【迁移初始化配置】处,如果是首次迁移,可以选择默认,如果外置库已有之前迁移的对象而未删除,再次迁移可以选择【覆盖】【表空间初始化】**选择默认“跳过”。

6.6.5 离线迁移

上述操作完成后,点击**【下一步:离线迁移】**进入离线迁移界面,在迁移过程中,会显示迁移进度,迁移结束后,如下所示:

image.png

image.png

6.6.6 校验初始化

上述离线迁移完成后,点击【下一步:校验初始化】,进入如下所示页面:

image.png


 

image.png

image.png

如上图所示,在校验初始化页面,在**【选择校验范围】选择校验的用户,在【校验设置】**可以选择“完整对比”或者“统计对比”,两者的相关含义如下所示:

  • 统计对比:一致性校验页面显示统计校验。
  • 完整对比:新增单表不一致阈值,可选无限制或自定义阈值,达到阈值后停止校验,一致性校验页面显示全量校验。

在**【高级选项】**中,性能配置表示支持最大可同时进行表校验的数目,每一对表的校验会使用一个线程,同时源端与目标端各占用一个连接数,默认范围[1,200]。

6.6.7 一致性校验

参照5.6.6 章节,在设置了相关参数后,点击**【下一步:开始一致性校验】**进行数据校验,校验过程中,会显示校验进度,校验结束后,结果如下所示:

image.png

image.png

七、问题梳理

在验证YMP的迁移过程中,也发现了一些问题,也将如下问题反馈给了崖山官方人员,他们已将收集的问题反馈给了研发,后续会进一步完善YMP功能,值得期待。

7.1 下载报告报提示未知错误

在迁移评估后,下载评估报告,总是报错,提示“未知错误”,如下所示。

未知错误

image.png

查看了相关日志,报如下错误:

# 日志目录在 /home/ymp/yashan-migrate-platform/logs,查看 YMP-INFO***.log
2024-04-19 15:32:21.627 [http-nio-8090-exec-7] INFO  com.sics.migrate.port.common.util.YasldrParser - yasldr version::YashanDB Loader Personal Edition Release 23.2.1.100 x86_64 2d13f1d
2024-04-19 15:32:21.801 [http-nio-8090-exec-2] INFO  com.sics.migrate.port.common.util.YasldrParser - yasldr version::YashanDB Loader Personal Edition Release 23.2.1.100 x86_64 2d13f1d
2024-04-19 15:32:29.143 [http-nio-8090-exec-9] INFO  com.sics.migrate.server.ObjAssessmentPercentServer - 新的连接加入:28
2024-04-19 15:32:29.180 [http-nio-8090-exec-10] INFO  com.sics.check.server.CheckTaskProgressWebSocket - 新的连接加入:29
2024-04-19 15:32:29.259 [http-nio-8090-exec-7] INFO  com.sics.migrate.handler.InterfaceLogHandler - interface Call details: {"startTime":1713511949242,"spendTime":17,"uri":"/yashan/task/getTaskList","url":"http://10.110.8.42:8090/yashan/task/getTaskList","method":"GET","ip":"10.10.52.21","parameter":"{taskStage\u003dnull, pageSize\u003d10, taskName\u003d, pageNum\u003d1, taskStatus\u003dnull, dateOrderBy\u003dnull}","result":"{\"code\":200,\"message\":\"success\",\"result\":{\"records\":[{\"id\":1,\"taskName\":\"ddd\",\"taskStage\":\"ASSESSMENT\",\"taskStatus\":\"ASSESSMENT_FINISHED\",\"taskProgress\":100.0,\"sourceDbType\":\"ORACLE\",\"startTime\":\"2024-04-19 14:28:25\"}],\"total\":1,\"size\":10,\"current\":1,\"orders\":[],\"optimizeCountSql\":true,\"searchCount\":true,\"optimizeJoinOfCountSql\":true}}"}
2024-04-19 15:32:29.821 [http-nio-8090-exec-5] INFO  com.sics.check.server.CheckTaskProgressWebSocket - 连接关闭:29
2024-04-19 15:32:29.821 [http-nio-8090-exec-2] INFO  com.sics.migrate.server.ObjAssessmentPercentServer - 连接关闭:28
2024-04-19 15:32:30.746 [http-nio-8090-exec-4] INFO  com.sics.migrate.server.ObjAssessmentPercentServer - 新的连接加入:2a
2024-04-19 15:32:30.773 [http-nio-8090-exec-6] INFO  com.sics.check.server.CheckTaskProgressWebSocket - 新的连接加入:2b
2024-04-19 15:32:30.841 [http-nio-8090-exec-1] INFO  com.sics.migrate.handler.InterfaceLogHandler - interface Call details: {"startTime":1713511950825,"spendTime":16,"uri":"/yashan/task/getTaskList","url":"http://10.110.8.42:8090/yashan/task/getTaskList","method":"GET","ip":"10.10.52.21","parameter":"{taskStage\u003dnull, pageSize\u003d10, taskName\u003d, pageNum\u003d1, taskStatus\u003dnull, dateOrderBy\u003dnull}","result":"{\"code\":200,\"message\":\"success\",\"result\":{\"records\":[{\"id\":1,\"taskName\":\"ddd\",\"taskStage\":\"ASSESSMENT\",\"taskStatus\":\"ASSESSMENT_FINISHED\",\"taskProgress\":100.0,\"sourceDbType\":\"ORACLE\",\"startTime\":\"2024-04-19 14:28:25\"}],\"total\":1,\"size\":10,\"current\":1,\"orders\":[],\"optimizeCountSql\":true,\"searchCount\":true,\"optimizeJoinOfCountSql\":true}}"}
2024-04-19 15:32:32.645 [http-nio-8090-exec-9] INFO  com.sics.check.server.CheckTaskProgressWebSocket - 连接关闭:2b
2024-04-19 15:32:32.645 [http-nio-8090-exec-10] INFO  com.sics.migrate.server.ObjAssessmentPercentServer - 连接关闭:2a
2024-04-19 15:32:33.730 [http-nio-8090-exec-5] INFO  com.sics.migrate.server.ObjAssessmentPercentServer - 新的连接加入:2c
2024-04-19 15:32:33.767 [http-nio-8090-exec-2] INFO  com.sics.check.server.CheckTaskProgressWebSocket - 新的连接加入:2d
2024-04-19 15:32:33.822 [http-nio-8090-exec-8] INFO  com.sics.migrate.handler.InterfaceLogHandler - interface Call details: {"startTime":1713511953804,"spendTime":17,"uri":"/yashan/task/getTaskList","url":"http://10.110.8.42:8090/yashan/task/getTaskList","method":"GET","ip":"10.10.52.21","parameter":"{taskStage\u003dnull, pageSize\u003d10, taskName\u003d, pageNum\u003d1, taskStatus\u003dnull, dateOrderBy\u003dnull}","result":"{\"code\":200,\"message\":\"success\",\"result\":{\"records\":[{\"id\":1,\"taskName\":\"ddd\",\"taskStage\":\"ASSESSMENT\",\"taskStatus\":\"ASSESSMENT_FINISHED\",\"taskProgress\":100.0,\"sourceDbType\":\"ORACLE\",\"startTime\":\"2024-04-19 14:28:25\"}],\"total\":1,\"size\":10,\"current\":1,\"orders\":[],\"optimizeCountSql\":true,\"searchCount\":true,\"optimizeJoinOfCountSql\":true}}"}
2024-04-19 15:32:35.525 [http-nio-8090-exec-6] INFO  com.sics.migrate.server.ObjAssessmentPercentServer - 连接关闭:2c
2024-04-19 15:32:35.525 [http-nio-8090-exec-4] INFO  com.sics.check.server.CheckTaskProgressWebSocket - 连接关闭:2d
2024-04-19 15:32:35.577 [http-nio-8090-exec-1] INFO  com.sics.migrate.port.common.util.YasldrParser - yasldr version::YashanDB Loader Personal Edition Release 23.2.1.100 x86_64 2d13f1d
2024-04-19 15:32:35.694 [http-nio-8090-exec-10] INFO  com.sics.migrate.port.common.util.YasldrParser - yasldr version::YashanDB Loader Personal Edition Release 23.2.1.100 x86_64 2d13f1d
2024-04-19 15:32:37.817 [http-nio-8090-exec-4] INFO  com.sics.migrate.port.common.util.YasldrParser - yasldr version::YashanDB Loader Personal Edition Release 23.2.1.100 x86_64 2d13f1d
2024-04-19 15:33:12.736 [http-nio-8090-exec-4] ERROR com.sics.migrate.handler.GlobalExceptionHandler - 错误的请求:
com.sics.migrate.exception.YashanMigratePlatformException: null
        at com.sics.migrate.controller.ReportDownloadController.getObjAssessmentTaskReport(ReportDownloadController.java:78)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
        at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
        at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154)
        at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
        at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
        at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154)
        at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
        at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:458)
        at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:373)
        at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
        at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
        at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
        at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:370)
        at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.NullPointerException: null
        at java.util.Comparator.lambda$comparingInt$7b0bb60$1(Comparator.java:490)
        at java.util.TimSort.countRunAndMakeAscending(TimSort.java:356)
        at java.util.TimSort.sort(TimSort.java:220)
        at java.util.Arrays.sort(Arrays.java:1512)
        at java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:348)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:483)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
        at com.sics.migrate.serviceimpl.ObjAssessmentResultServiceImpl.getObjAssessmentTaskReport(ObjAssessmentResultServiceImpl.java:613)
        at com.sics.migrate.serviceimpl.ObjAssessmentResultServiceImpl$$FastClassBySpringCGLIB$$92addf36.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
        at com.sics.migrate.serviceimpl.ObjAssessmentResultServiceImpl$$EnhancerBySpringCGLIB$$51c97367.getObjAssessmentTaskReport(<generated>)
        at com.sics.migrate.serviceimpl.ObjAssessmentResultServiceImpl$$FastClassBySpringCGLIB$$92addf36.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
        at com.sics.migrate.serviceimpl.ObjAssessmentResultServiceImpl$$EnhancerBySpringCGLIB$$3a0b72e9.getObjAssessmentTaskReport(<generated>)
        at com.sics.migrate.controller.ReportDownloadController.getObjAssessmentTaskReport(ReportDownloadController.java:67)
        ... 68 common frames omitted

该问题已反馈崖山官方相关人员

7.2 迁移评估修改对象后需新刷新报告

在执行迁移评估过程中,如果对一些有问题的对象,比如选择选择忽略该对象,在执行后,会提示需要重新刷新报告,如下所示:

image.png

7.3 任务名称不对应

在创建迁移任务时,开始随便创建了一个任务,并设置了一个任务名称,点击**“保存”**,未退出该页面,直接在该页面删除了原任务名称,重新填写了一个任务名称,点击保存并进行下一步,结果发现在主页面看到的任务名称和点击该任务名称看到的任务名称不对应,如下所示。

该问题已反馈给崖山官方人员。

image.png

image.png

7.4 不兼容TIMESTAMP (6) WITH TIME ZONE DEFAULT

当前我们这边很多表中有字段使用 timestamp with zone,当前yashandb不支持这种类型,已将问题反馈给官方人员。

image.png

image.png

7.5 迁移失败对象不允许手动修复

迁移时,不允许对迁移失败的对象进行手动修复。

image.png

7.6 YMP不支持Oracle 10g

配置数据源的时候,可以正常连接Oracle10g,但在配置任务时提示不支持Oracle 10g

image.png

7.7 需删除评估任务才能评估同名的用户

当新创建的任务在评估任务时,如果评估的schema和其它任务评估的schema同名,会提示有冲突。

image.png

image.png

7.8 不支持对DG备库评估对象

image.png


 

image.png


 

image.png


 

image.png

image.png

7.9 YMP和数据库建议选择相同版本

我初期在部署YMP的时候,YashanDB数据库软件的版本高于YMP版本,导致安装YMP时出现报错。

image.png

官方建议YMP版本应高于YashanDB数据库软件版本或者选择相同版本。

image.png

如果yashan-migrate-platform采用 23.1.1版本,而 数据库采用 23.2.1版本,安装就会报如下错误

image.png

八、补充

以下为一些验证中不兼容的类型实例:

image.png

image.png

image.png

image.png

九、问答环节

以下是受崖山直播之邀,谈谈对于迁移的感受,迁移有同构和异构迁移,一个完整而顺利的迁移是要在迁移前付出很多的努力的,以下是我个人对数据库的迁移的感受整理。

Q1.一般在数据迁移场景中,我们常见的风险有哪些?

在数据迁移过程中,尤其是涉及异构数据库时,以下是几个具体的常见风险及应对策略:

  1. 数据丢失或损坏

    • 风险:在迁移过程中,由于错误配置、网络问题或其他技术故障,可能会导致数据丢失或损坏。
    • 应对:确保进行完整的数据备份,并在迁移前进行完整性检查。使用可靠的迁移工具和经过验证的迁移过程。
  2. 数据不一致

    • 风险:在迁移过程中,由于事务处理不同步或迁移脚本错误,源和目标数据库之间可能出现数据不一致。
    • 应对:使用数据比较工具定期校验源数据库和目标数据库之间的数据一致性,确保同步机制正确实施。
  3. 性能下降

    • 风险:迁移到新的数据库可能由于配置不当或硬件限制导致性能问题。
    • 应对:在迁移前进行容量规划和基准测试,迁移后对系统进行调优,如索引优化、查询优化等。
  4. 兼容性问题

    • 风险:数据兼容性:
      1. 数据类型兼容性问题
      2. 数据表兼容性(普通表、分区表等)
      3. 数据结构兼容性问题
        数字、字符串,时间类型(精度问题)
      4. SQL语句兼容性、执行计划兼容性问题
        执行计划、逻辑等
      5. 存储过程、函数、包、触发器等翻译问题
      6. 表大小存储逻辑等
      7. 迁移后,数据库与其他系统之间接口,业务,或者复制等关系问题相关协调&优化
      8. 针对TP/AP等不同业务系统,测试重点关注点等问题
    • 应对:在做迁移之前,应该进行大量兼容性验证测试,避免迁移前后数据库不兼容
  5. 成本和时间超支

    • 风险:迁移项目可能因未预见的技术挑战、资源不足或管理不当导致时间延长和成本增加。
    • 应对:进行详尽的项目规划,设立明确的时间表和预算。适时调整计划,保持通信透明,及时解决出现的问题
  6. 反向复制:

    • 风险:数据的不一致,导致数据错乱
    • 应对:为保证迁移后因其它情况需要回退,一定要制定好反向复制方案,保证能顺利进行回退

Q2. 您觉得在做异构数据库迁移前后需要做哪些操作呢?

对于成功的数据库迁移,每个阶段的准备和后续操作都至关重要:

迁移前的操作
  1. 详细评估
    • 审核现有数据库的规模、使用的数据类型、复杂的SQL查询和存储过程。
    • 评估目标数据库的功能以及可能的限制。
  2. 迁移策略制定
    • 决定迁移是一次性还是分阶段进行。
    • 选择适当的迁移工具和方法(如全量迁移或增量迁移)。
  3. 测试环境准备
    • 构建与生产环境相仿的测试环境,用于迁移过程中的测试。
  4. 风险管理计划
    • 设计回滚方案以应对迁移失败的情况。
    • 制定紧急恢复计划和数据备份策略。
迁移后的操作
  1. 系统验证
    • 执行数据完整性检查,验证数据迁移后的准确性。
    • 进行功能测试和性能测试,确保所有系统功能正常运行,性能达标。
  2. 优化调整
    • 根据实际运行情况调整数据库参数。
    • 优化SQL查询和索引,提高查询效率和响应时间。
  3. 持续监控
    • 监控系统的性能和稳定性,及时发现和解决新出现的问题。
    • 使用监控工具跟踪关键性能指标和日志。
  4. 培训与文档
    • 更新技术文档和用户手册。
    • 对维护团队和用户进行新系统的培训。

Q3.您觉得在使用YMP过程中,有什么好用的地方和需要改进的地方吗?

**好的方面:**安装部署简单,文档也比较详尽,迁移过程步骤明确,而且界面比较清爽,这是我特别欣赏的地方,对于很多操作也有明确的提示,另外在迁移过程中对于不明白的地方也得到官方技术人员的给力指导。

**需要改进的方面:**目前YMP迁移还只支持全量迁移,另外对于支持的数据库类型还比较少,另外在迁移过程中也发现了一些待改进的地方,这块也已反馈给相关负责人。

​ 建议后续增加增量迁移,以及复制迁移,另外也希望能支持更多异构数据库类型。

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

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

相关文章

钉钉手机端调试前端H5项目流程

此流程以Vue项目为例 一、操作步骤 在根目录下 vue.config.js 文件中将 devServer.host 设置为 0.0.0.0 // vue.config.js module.exports {devServer: {host: 0.0.0.0,...},...}本地启动项目&#xff0c;获取 Network App running at:- Local: http://localhost:8080/ -…

JAVA 学习·泛型(二)——通配泛型

有关泛型的基本概念&#xff0c;参见我的前一篇博客 JAVA 学习泛型&#xff08;一&#xff09;。 协变性 泛型不具备协变性 在介绍通配泛型之前&#xff0c;先来看一下下面的例子。我们定义了一个泛型栈&#xff1a; import java.util.ArrayList; class GenericStack<E>…

全新TOF感知RGBD相机 | 高帧率+AI,探索3D感知新境界

海康机器人在近期的机器视觉新品发布会上推出的全新TOF感知RGBD相机,无疑是对当前机器视觉技术的一次革新。这款相机不仅融合了高帧率、轻松集成、体积小巧以及供电稳定等诸多优点,更重要的是,它将AI与3D感知技术完美结合,通过高帧率+AI算法,实现了对不同场景的快速捕捉与…

Android Studio报错:Constant expression required

【出现的问题】&#xff1a; 使用JDK17以上版本&#xff0c;switch语句报错&#xff1a;Constant expression required 【解决方法】&#xff1a; 在gradle.properties配置文件下添加代码&#xff1a; android.nonFinalResIdsfalse 如图&#xff1a; 接着再点击右上角的Sync…

asyncionetworkxFuncAnimation学习--动态显示计算图的运行情况

asyncio&networkx&FuncAnimation学习--动态显示计算图的运行情况 一.效果二.代码 一.目的 1.动态显示计算图的运行状态(点或边是否已完成) 二.步骤: 1.定义计算图 2.asyncio 并行计算 3.networkx 显示计算图 4.FuncAnimation 动态更新 三.依赖: conda install pygraphv…

Linux shell编程学习笔记48:touch命令

0 前言 touch是csdn技能树Linux基础练习题中最常见的一条命令&#xff0c;这次我们就来研究它的功能和用法。 1. touch命令的功能、格式和选项说明 我们可以使用命令 touch --help 来查看touch命令的帮助信息。 purpleEndurer bash ~ $ touch --help Usage: touch [OPTION]…

pyqt 按钮常用格式Qss设置

pyqt 按钮常用格式Qss设置 QSS介绍按钮常用的QSS设置效果代码 QSS介绍 Qt Style Sheets (QSS) 是 Qt 框架中用于定制应用程序界面样式的一种语言。它类似于网页开发中的 CSS&#xff08;Cascading Style Sheets&#xff09;&#xff0c;但专门为 Qt 应用程序设计。使用 QSS&am…

数据分析--客户价值分析RFM(分箱法/标准化)

原数据 原数据如果有异常或者缺失等情况&#xff0c;要先对数据进行处理 &#xff0c;再进行下面的操作&#xff0c;要不然会影响结果的正确性 一、根据RFM计算客户价值并对客户进行细分 1. 数据预处理 1.1 创建视图存储 R、F、M的最大最小值 创建视图存储R 、F、M 的最大最小…

力扣练习题(2024/5/2)

1填充每个节点的下一个右侧节点指针 给定一个 完美二叉树 &#xff0c;其所有叶子节点都在同一层&#xff0c;每个父节点都有两个子节点。二叉树定义如下&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&#xff0c;让这个…

C#知识|Dictionary泛型集合的使用总结

哈喽,你好,我是雷工! 以下是C#Dictionary泛型集合的学习笔记。 01 Dictionary泛型集合 1.1、Dictionary<K,V>通常称为字典, 1.2、其中<K,V>是自定义的,用来约束集合中元素类型。 1.3、在编译时检查类型约束, 1.4、无需装箱拆箱操作, 1.5、操作与哈希表(Ha…

C++ string类

目录 0.前言 1.为什么学习string类 1.1 C语言字符串的局限性 1.2 C string类的优势 2.标准库中的string类 2.1 字符串作为字符序列的类 2.2 接口与标准容器类似 2.3 基于模板的设计 2.4 编码和字符处理 3.string类的常用接口说明 3.1构造函数 3.1.1默认构造函数 3…

前端Web开发基础知识

HTML定义 超文本标记语言&#xff08;英语&#xff1a;HyperText Markup Language&#xff0c;简称&#xff1a;HTML&#xff09;是一种用于创建网页的标准标记语言。 什么是 HTML? HTML 是用来描述网页的一种语言。 HTML 指的是超文本标记语言: HyperText Markup LanguageH…

ELK Stack 8 接入ElasticFlow

介绍 Netflow v5 / v9 / v10&#xff08;IPFIX&#xff09;&#xff0c;支持大部分网络厂商及VMware的分布式交换机。 NetFlow是一种数据交换方式。Netflow提供网络流量的会话级视图&#xff0c;记录下每个TCP/IP事务的信息。当汇集起来时&#xff0c;它更加易于管理和易读。…

EasyExcel 处理 Excel

序言 本文介绍在日常的开发中&#xff0c;如何使用 EasyExcel 高效处理 Excel。 一、EasyExcel 是什么 EasyExcel 是阿里巴巴开源的一个 Java Excel 操作类库&#xff0c;它基于 Apache POI 封装了简单易用的 API&#xff0c;使得我们能够方便地读取、写入 Excel 文件。Easy…

常用AI工具分享 + IDEA内使用通义灵码

引言 随着人工智能技术的飞速发展&#xff0c;AI工具已经渗透到我们日常生活和工作的各个领域&#xff0c;带来了前所未有的便利。现在我将分享一下常用的AI工具&#xff0c;以及介绍如何在IDEA中使用通义灵码。 常用AI工具 1. 通义灵码 (TONGYI Lingma) - 由阿里云开发的智能…

Neo4j v5 中 Cypher 的变化

How Cypher changed in Neo4j v5 Neo4j v5 中 Cypher 的变化 几周前&#xff0c;Neo4j 5 发布了。如果你像我一样&#xff0c;在 Neo4j 4 的后期版本中忽略了所有的弃用警告&#xff0c;你可能需要更新你的 Cypher 查询以适应最新版本的 Neo4j。幸运的是&#xff0c;新的 Cyp…

【翻译】REST API

自动伸缩 API 创建或更新自动伸缩策略 API 此特性设计用于 Elasticsearch Service、Elastic Cloud Enterprise 和 Kubernetes 上的 Elastic Cloud 的间接使用。不支持直接用户使用。 创建或更新一个自动伸缩策略。 请求 PUT /_autoscaling/policy/<name> {"rol…

什么是UDP反射放大攻击,有什么安全措施可以防护UDP攻击

随着互联网的飞速发展和业务复杂性的提升&#xff0c;网络安全问题日益凸显&#xff0c;其中分布式拒绝服务&#xff08;DDoS&#xff09;攻击成为危害最为严重的一类网络威胁之一。 近些年&#xff0c;网络攻击越来越频繁&#xff0c;常见的网络攻击类型包括&#xff1a;蠕虫…

AI图书推荐:用ChatGPT快速创建在线课程

您是否是您领域的专家&#xff0c;拥有丰富的知识和技能可以分享&#xff1f;您是否曾想过创建一个在线课程&#xff0c;但被这个过程吓倒了&#xff1f;那么&#xff0c;是时候把这些担忧放在一边&#xff0c;迈出这一步了&#xff01;有了这本指南和ChatGPT的帮助&#xff0c…

ssh远程访问windows系统下的jupyterlab

网上配置这一堆那一堆&#xff0c;特别乱&#xff0c;找了好久整理后发在这里 由于既想打游戏又想做深度学习&#xff0c;不舍得显卡性能白白消耗&#xff0c;这里尝试使用笔记本连接主机 OpenSSH 最初是为 Linux 系统开发的&#xff0c;现在也支持包括 Windows 和 macOS 在内…