喵♂呜 的博客

一个刚毕业就当爹的程序猿 正在迷雾中寻找道路...

MigrationToolkit数据库迁移工具的使用

近期在做SqlServer数据库迁移到Postgresql 用到了MigrationToolkit

Migration Toolkit 数据库迁移工具

简介

MigrationToolkit是 EnterpriseDB 的 Postgres Plus Advanced Server 管理工具

安装 MigrationToolkit

  • 打开 Postgresql 自带的 Application Stack Builder
  • 选择目标数据库
  • 选择 Registration-required and trial products
  • 选择 EnterpriseDB Tools
  • 打勾 Migration Toolkit
  • 点击下一步 直到完成安装

下载数据库的JDBC驱动

这里用到了 SqlServer点击下载 和 PostgresqlJAVA7版本JAVA8版本

注意: 必须选择 Java 对应版本的 Postgresql 数据库驱动
如果用到其他驱动可以查看这里 JDBC数据库驱动
把下载的文件放到 安装目录\lib\ext\ 目录下

配置数据源和目标数据库

在安装目录的etc文件夹 找到 toolkit.properties 文件

如果打不开或者出现错误 直接删掉就好了 然后新建一个
填写数据源的信息和目标数据库的信息

1
2
3
4
5
6
7
SRC_DB_URL=jdbc:jtds:sqlserver://192.168.2.79:1433;databasename=OA20160401
SRC_DB_USER=OA20151231
SRC_DB_PASSWORD=hg123.XX

TARGET_DB_URL=jdbc:postgresql://172.30.16.7:5432/sqlserver
TARGET_DB_USER=sqlserver
TARGET_DB_PASSWORD=325325

参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
Running EnterpriseDB Migration Toolkit (Build 49.0.4) ...

EnterpriseDB Migration Toolkit (Build 49.0.4)

用法: runMTK [-选项] SCHEMA

若未指定任何选项,则将导入完整的架构。

其中,选项包括:
-help 显示应用程序的命令行用法。
-version 显示应用程序版本信息。
-verbose [on|off] 以标准输出显示应用程序日志消息 (默认值: on)。

-schemaOnly 只导入架构对象定义。
-dataOnly 只导入表数据。若指定了 -tables,则只导入所选表的数据。注意: 如果对目标表定义了任何外键约束,则此选项需与 -truncLoad 选项一起使用。

-sourcedbtype db_type The -sourcedbtype option specifies the source database type. db_type may be one of the following values: mysql, oracle, sqlserver, sybase, postgresql, enterprisedb. db_type is case-insensitive. By default, db_type is oracle.
-targetdbtype db_type The -targetdbtype option specifies the target database type. db_type may be one of the following values: oracle, sqlserver, postgresql, enterprisedb. db_type is case-insensitive. By default, db_type is enterprisedb.

-allTables 导入所有表。
-tables LIST 导入以逗号分隔的表列表。
-constraints 导入表约束。
-indexes 导入表索引。
-triggers 导入表触发器。
-allViews 导入所有视图。
-views LIST 导入以逗号分隔的视图列表。
-allProcs 导入所有存储过程。
-procs LIST 导入以逗号分隔的存储过程列表。
-allFuncs 导入所有函数。
-funcs LIST 导入以逗号分隔的函数列表。
-allPackages 导入所有包。
-packages LIST 导入以逗号分隔的包列表。
-allSequences 导入所有序列。
-sequences LIST 导入以逗号分隔的序列列表。
-targetSchema NAME 目标架构的名称 (默认: 目标架构以源架构命名)。
-allDBLinks 导入所有数据库链接。
-allSynonyms It enables the migration of all public and private synonyms from an Oracle database to an Advanced Server database. If a synonym with the same name already exists in the target database, the existing synonym will be replaced with the migrated version.
-allPublicSynonyms It enables the migration of all public synonyms from an Oracle database to an Advanced Server database. If a synonym with the same name already exists in the target database, the existing synonym will be replaced with the migrated version.
-allPrivateSynonyms It enables the migration of all private synonyms from an Oracle database to an Advanced Server database. If a synonym with the same name already exists in the target database, the existing synonym will be replaced with the migrated version.

-dropSchema [true|false] 若架构已存在于目标数据库中,则删除此架构 (默认值: false)。
-truncLoad 此选项对目标表禁用任何约束,并且在导入新数据之前先截断表中的数据。此选项只能与 -dataOnly 一起使用。
-safeMode 使用纯 SQL 语句,以安全模式传输数据。
-copyDelimiter 在加载表数据时,指定一个字符作为复制命令中的分隔符。默认值为 \t
-batchSize 指定“批量插入”要使用的“批次大小”。有效值为 1-1000,默认批次大小为 1000,如果出现“内存不足”异常,则可以降低此值
-cpBatchSize 指定复制命令要使用的“批次大小”,以 MB 为单位。有效值大于 0,默认批次大小为 8 MB
-fetchSize 指定提取大小 (每次应从结果集中提取的行数)。当数据表含有数百万个行,而您想避免发生内存不足错误时,可以使用此选项。
-filterProp 包含表 where 子句的属性文件。
-skipFKConst 跳过外键约束的迁移。
-skipCKConst 跳过检查约束条件的迁移。
-ignoreCheckConstFilter 在缺省的情况下MTK不从Sybase中迁移检查约束和缺省子句,使用这个选项可以关闭这个过滤功能。
-fastCopy 略过 WAL 日志记录,以优化方式执行 COPY 操作,默认情况下禁用。
-customColTypeMapping LIST 使用以分号分隔的列表表示的自定义类型映射,其中每个条目都使用 COL_NAME_REG_EXPR=TYPE 对来指定,例如 .*ID=INTEGER
-customColTypeMappingFile PROP_FILE 由属性文件表示的自定义类型映射,其中每个条目都使用 COL_NAME_REG_EXPR=TYPE 对来指定,例如 .*ID=INTEGER
-offlineMigration [DDL_PATH] 这将执行脱机迁移并将 DDL 脚本保存在文件中供以后执行。默认情况下,如果要求后跟 -offlineMigration 选项以及自定义路径,则脚本文件将保存在用户主文件夹下。
-logDir LOG_PATH 指定用于保存日志文件的自定义路径。默认情况下,日志文件保存在工作目录中的“logs”文件夹下。
-copyViaDBLinkOra 此选项可用来通过使用 dblink_ora COPY 命令复制数据。此选项仅限用在从 Oracle 到 EnterpriseDB 迁移模式中。
-singleDataFile Use single SQL file for offline data storage for all tables. This option cannot be used in COPY format.
-allUsers 从源数据库导入所有用户和角色。
-users LIST 从源数据库导入选定用户/角色。LIST 是一个用逗号分隔的用户/角色名称列表,如 -users MTK,SAMPLE
-allProfiles Import all profiles from the source database.
-profiles LIST Import the selected profiles from the source database. LIST is a comma-separated list of profile names e.g. -profiles USER_PROFILE,ADMIN_PROFILE
-allRules 从源数据库导入所有规则。
-rules LIST 从源数据库导入选定规则。 LIST 是一个用逗号分隔的名称列表,如 -rules high_sal_emp,low_sal_emp
-allGroups 从源数据库导入所有组。
-groups LIST 从源数据库导入选定组。 LIST 是一个用逗号分隔的组名称列表,如 -groups acct_emp,mkt_emp
-allDomains 从源数据库导入所有域、枚举和复合类型。
-domains LIST 从源数据库导入所选域、枚举和复合类型。 LIST 是一个用逗号分隔的域名称列表,如 -domains d_email,d_dob, mood
-objecttypes 导入用户定义的对象类型。
-replaceNullChar <CHAR> 如果空字符是列值得一部分,那么通过JDBC协议迁移数据就会失败.这个选项可以使用用户指定的字符来替代空字符串。
-importPartitionAsTable [LIST] 通过使用这个选项能够将Oracle中的分区表以常规表的形式导入到EnterpriseDB中。为了在所选择表集合上的应用规则,在选项后面应跟随以逗号分隔的表名列表。
-enableConstBeforeDataLoad 通过使用这个选项可以在数据导入前重新启用约束(和触发器).当要迁移的表在EnterpriseDB中对应的是一张分区表时,使用这个选项是非常有用的。
-checkFunctionBodies [true|false] 设置为 false 时,将禁用创建函数过程中的函数体验证,从而避免在函数包含向前参考时发生错误。 目标数据库为 Postgres/EnterpriseDB 时适用,默认值为 true。
-retryCount VALUE 指定 MTK 迁移由于跨架构相关性而失败的对象的重试次数。 VALUE 参数应该大于 0,默认值为 2。
-analyze 它将对目标 Postgres 或 Postgres Plus Advanced Server 数据库调用 ANALYZE 操作。 ANALYZE 收集用于有效查询计划的迁移表的统计信息。
-vacuumAnalyze 它将对目标 Postgres 或 Postgres Plus Advanced Server 数据库调用 VACUUM 和 ANALYZE 操作。 VACUUM 回收非活动元组存储,ANALYZE 收集用于有效查询计划的迁移表的统计信息。
-loaderCount VALUE 指定并行执行数据加载的作业(线程)数目。 VALUE 参数应该大于 0,默认值为 1。
-logFileSize VALUE It represents the maximum file size limit (in MB) before rotating to a new log file, defaults to 50MB.
-logFileCount VALUE It represents the number of files to maintain in log file rotation history, defaults to 20. Specify a value of zero to disable log file rotation.
-useOraCase It preserves the identifier case while migrating from Oracle, except for functions, procedures and packages unless identifier names are given in quotes.
-logBadSQL It saves the DDL scripts for the objects that fail to migrate, in a .sql file in log folder.
-targetDBVersion It represents the major.minor version of the target database. This option is applicable for offline migration mode and is used to validate certain migration options as per target db version [default is 9.5 for EnterpriseDB database].

数据库连接信息:
应用程序将从文件toolkit.properties中读取源和目标数据库服务器的连接信息.
更多的信息参见MTK的自述文档.

修改bat文件

打开 runMTK.bat 添加启动参数 -Djava.ext.dirs=..\lib\ext (这里的路径就是数据库驱动的所在目录)

修改后的文件如下

1
2
3
4
5
6
7
8
9
10
11
@echo off
@REM ----------------------------------------------------------------------------
@REM --
@REM -- Copyright (c) 2004-2015 - EnterpriseDB Corporation. All Rights Reserved.
@REM --
@REM ----------------------------------------------------------------------------

setlocal disabledelayedexpansion
FOR /F "tokens=1* delims==" %%i IN (..\etc\sysconfig\edbmtk-49.config) DO set %%i=%%j

cscript //nologo "..\etc\sysconfig\runJavaApplication.vbs" "..\etc\sysconfig\edbmtk-49.config" "-Dprop=..\etc\toolkit.properties -Djava.ext.dirs=..\lib\ext -jar edb-migrationtoolkit.jar %*"

同步数据

runMTK.bat 同级目录下打开命令行
输入以下命令 runMTK.bat -sourcedbtype sqlserver -targetdbtype postgresql -targetSchema public dbo
命令说明:

  • -sourcedbtype sqlserver 数据源类型(这里是sqlserver)
  • -targetdbtype postgresql 目标库类型(这里是postgresql)
  • -targetSchema public 目标架构

开始同步数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Running EnterpriseDB Migration Toolkit (Build 49.0.4) ...
源数据库连接信息...
连接 =jdbc:jtds:sqlserver://192.168.0.8:21533;databasename=tds_fdw_test
用户 =sa
密码=******
目标数据库连接信息...
连接 =jdbc:postgresql://172.30.16.7:5432/sqlserver
用户 =sqlserver
密码=******
正在连接源SQL Server数据库服务器...
Connected to Microsoft SQL Server, version '11.00.3000'
正在连接目标Postgres数据库服务器...
Connected to PostgreSQL, version '9.6.0'
正在导入 SQL Server 架构 dbo...
Getting Table Definitions
正在创建表...
正在创建表: test
正在创建表: news
已创建 2 个表。
正在以 8 MB 批次大小加载表数据...
正在加载表: test ...
[test] 已迁移 4 行。
[test] 表数据加载摘要: 时间总计 (秒): 0.011 行数总计: 4
正在加载表: news ...
[news] 已迁移 3 行。
[news] 表数据加载摘要: 时间总计 (秒): 0.008 行数总计: 3
数据加载摘要: 时间总计 (秒): 0.111 行数总计: 7 大小总计 (MB): 0.0
Getting Constraint Definitions
正在创建约束: pk_test
正在创建约束: pk_news
Getting Index Definitions
Getting View Definitions

已成功导入架构 dbo。


迁移过程已成功完成。

迁移日志已保存到 C:\Users\蒋天蓓\.enterprisedb\migration-toolkit\logs

******************** 迁移摘要 ********************
Tables: 2 来自 2
Constraints: 2 来自 2

全部对象: 4
成功计数: 4
失败计数: 0
Invalid count: 0

*************************************************************

报错问题解决

1
2
3
MTK-17003:复制表时发生错误:拒绝了对对象 'columns' (数据库 'mssqlsystemresource',架构 'sys')的 SELECT 权限。
MTK-03000: General Error
DB-229: java.sql.SQLException: 拒绝了对对象 'columns' (数据库 'mssqlsystemresource',架构 'sys')的 SELECT 权限。

权限不足 请使用超级用户进行复制

1
2
MTK-11009: Error Connecting Database "SQL Server"
java.lang.ClassNotFoundException: net.sourceforge.jtds.jdbc.Driver

SqlServer驱动未找到 请下载驱动

1
2
MTK-11009: Error Connecting Database "SQL Server"
DB-18456: java.sql.SQLException: 用户 'sa' 登录失败。

账户密码错误

1
2
MTK-11009: Error Connecting Database "SQL Server"
DB-18456: java.sql.SQLException: 用户 'sa' 登录失败。

账户密码错误

1
2
3
4
5
6
7
MTK-15013: Error Creating Table pj_invoice
DB-42883: org.postgresql.util.PSQLException: ERROR: function newid() does not exist
建议:No function matches the given name and argument types. You might need to add explicit type casts.

MTK-15013: Error Creating Table pj_cus
DB-42883: org.postgresql.util.PSQLException: ERROR: function newsequentialid() does not exist
建议:No function matches the given name and argument types. You might need to add explicit type casts.

Postgresql 不支持 newid()newsequentialid() 请手动 新建函数

1
2
3
4
5
MTK-15001: 创建约束 pk_gplist 时发生错误
DB-42P01: org.postgresql.util.PSQLException: ERROR: relation "gplist" does not exist

MTK-15007: 创建索引 pj_cus-cus_customid_task_id_pj_result-non 时发生错误
DB-42P01: org.postgresql.util.PSQLException: ERROR: relation "pj_cus" does not exist

数据表不存在 请检查表导入是否出错

1
2
3
正在创建视图: syncobj_0x3239433643303932
MTK-15008: Error Creating View: syncobj_0x3239433643303932
DB-42601: org.postgresql.util.PSQLException: ERROR: syntax error at or near "select"

语法不兼容 请手动修改导入

1
2
MTK-13004:对于 MySQL 和 Sybase 数据库,您不能迁移触发器、序列、过程、函数、包及同义词。
MTK-02001:请运行 runMTK -help 以查看用法详细信息。

不支持导入 请手动修改导入

1
2
3
MTK-15013: Error Creating Table taskdaiyunwei
DB-42804: org.postgresql.util.PSQLException: ERROR: column "addtime" is of type timestamp without time zone but default expression is of type integer
建议:You will need to rewrite or cast the expression.

字段的默认值不匹配 修改字段默认值为 Postgresql 能够识别的

1
2
MTK-15008: Error Creating View: view_daizhibiao
DB-3F000: org.postgresql.util.PSQLException: ERROR: schema "dbo" does not exist

修改 错误视图的表名 去除架构的名称 比如这里的 view_daizhibiao 视图 把里面的表带有 dbo 的前缀都删除
当然也有可能是语句过于复杂导致的 这个时候你可以直接复制视图的Sql到Postgresql里面创建 一般都可以成功(前提是没有用到sqlserver专用函数)
点击查看语法兼容性

欢迎关注我的其它发布渠道