最近又来了个棘手的项目,时间紧任务重,要基于现有的软件,把MySQL数据库完全复制到Oracle数据库,查了相关数据库迁移的资料,最后决定使用dbswitch,以下是我使用时的一些经验。
gitee地址:dbswitch
功能描述
一句话,dbswitch工具提供源端数据库向目的端数据库的批量迁移同步功能,支持数据的全量和增量方式同步。包括:
- 结构迁移
支持字段类型、主键信息、建表语句等的转换,并生成建表SQL语句。
支持基于正则表达式转换的表名与字段名映射转换。
- 数据同步。
基于JDBC的分批次读取源端数据库数据,并基于insert/copy方式将数据分批次写入目的数据库。
支持有主键表的 增量变更同步 (变化数据计算Change Data Calculate)功能(千万级以上数据量的性能尚需在生产环境验证)
使用步骤及注意事项
1.直接拉取代码,或者下载zip包到桌面
2.双击build.cmd脚本文件即可编译打包
JDK:>=1.8 (建议用JDK 1.8)
maven:>=3.6
要配置对应的环境遍历,按win+r,打开cmd,输入mvn -v可以出现maven版本号即可
3.打包完成后,在同目录(target文件夹)下会出现:dbswitch-release-1.9.9.tar.gz压缩包,直接解压
4.编辑dbswitch-release-1.9.9\conf文件夹下的application.yml文件
server:
port: 9088
spring:
application:
name: dbswitch-admin
tomcat:
uri-encoding: UTF-8
max-http-header-size: 8096
mvc:
throw-exception-if-no-handler-found: false
static-path-pattern: /statics/**
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://你自己的数据库ip地址:3306/zhwy_fx?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=UTF8&autoReconnect=true&useSSL=false&allowMultiQueries=true&failOverReadOnly=false&connectTimeout=30000
username: 账号
password: 密码
validation-query: SELECT 1
test-on-borrow: true
flyway:
locations: classpath:db/migration
baseline-on-migrate: true
table: DBSWITCH_SCHEMA_HISTORY
enabled: true
mybatis:
configuration:
lazy-loading-enabled: true
aggressive-lazy-loading: false
map-underscore-to-camel-case: true
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#注意此处地址就是解压后的dbswitch-release-1.9.9文件夹中drivers的地址
dbswitch:
configuration:
drivers-base-path: C:\Users\22727\Desktop\dbswitch-release-1.9.9\drivers
注意配置数据库的url,username,password,还有驱动包的地址drivers-base-path
5.找到bin目录中的startup.cmd文件,双击启动即可
如果启动的时候报错,说你配置的数据库中缺少什么表(不影响启动),就打开如下文件复制sql执行下
6.启动成功后
在浏览器中输入地址:http://localhost:9088,默认账号密码:admin/123456
7.配置连接
将目标库和源库信息添加进去
以下是我的相关配置可作为参考(MySQL库导入到Oracle库)
源库(MySQL)配置:
目标库(Oracle)配置:
注意红框中内容,别写错了,配置完后可以测试下是否连接成功,如果没找到自己的驱动,也可以在【连接管理-驱动配置】中添加
8.创建同步任务
在【数据接入-任务管理】中创建任务,我的配置如下:
在配置目标端时,注意在【同步前置执行SQL脚本】中执行以下内容:
CREATE PROCEDURE RemoveNotNullConstraintsExceptPrimaryKey()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE tbl_name VARCHAR(255);
DECLARE cur CURSOR FOR SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE();
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO tbl_name;
IF done THEN
LEAVE read_loop;
END IF;
-- 构建 ALTER 语句,排除主键列
SET @alter_sql = (
SELECT GROUP_CONCAT(CONCAT('MODIFY ', COLUMN_NAME, ' ', COLUMN_TYPE, ' NULL'))
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = tbl_name
AND IS_NULLABLE = 'NO'
AND COLUMN_KEY != 'PRI'
);
-- 执行修改表结构的 SQL
IF @alter_sql IS NOT NULL THEN
SET @full_alter_sql = CONCAT('ALTER TABLE ', tbl_name, ' ', @alter_sql);
PREPARE stmt FROM @full_alter_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END LOOP;
CLOSE cur;
END //
DELIMITER ;
-- 调用存储过程
SET FOREIGN_KEY_CHECKS = 0;
CALL RemoveNotNullConstraintsExceptPrimaryKey();
9.启动!
然后就是等待执行即可,我这里基本上都执行完了,执行异常是因为我有个表的名称超长了,Oracle11中表名长度不能超过30个字符。
出现异常可以点开日志进行排查(重要)
3 条评论
这篇文章不错!
?幽默类评语?
作者的布局谋篇匠心独运,让读者在阅读中享受到了思维的乐趣。