业务系统从Oracle迁移到openGauss数据库的简单记录

本文详细记录了从Oracle数据库切换到openGauss的过程,包括官网文档查阅、安装配置、数据迁移、Java、C++编程调整以及数据库结构优化。重点讨论了数据库迁移工具、编码问题和跨平台兼容性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一)为啥要动数据库

由于世界风云变幻,无论是国家、客户、还是公司老板。
都希望数据库能够自主可控,不是米国的,自研的,最好还是开源的。
所以用了20年的Oracle数据库也准备更换了(省略吐槽,不考虑工作量?)……

(1.1)关于openGauss

在这里插入图片描述
👉 官网

源于PostgreSQL-XC,由华为主导、各个生态合作伙伴共同建设的。开源发行协议遵从木兰宽松许可证v2。
目前版本3.0.0,介绍分为【企业版】和【轻量版】,不过这次我们用到的却是【极简版】……
周边工具和生态如下(省略吐槽,Spark咋办?):
在这里插入图片描述

(1.2)数据库对比和迁移

在这里插入图片描述
下面是这个网站关于openGauss和目前最流行关系型数据库的对比(可以自己加上SQL Server 和 PostgreSQL)
🔗 MySQL vs. OpenGauss vs. Oracle

因为工作都是用的Oracle(少量MySQL,SQL Server)。
完全没有接触过openGauss(甚至没用过PostgreSQL)也没时间慢慢研究了,
所以大概拟定步骤如下:

  • 1. 学习并安装使用openGauss数据库。
  • 2. 业务数据库结构和元数据的迁移。
  • 3. 涉及数据库软件(Java)的开发。
  • 4. 涉及数据库软件(Delphi/C++)的开发。
  • 5. 涉及数据库软件(Go/Python)的开发。

(二)学习并安装使用openGauss

(2.1)官网文档资料

为啥以前连PostgreSQL都没用(省略吐槽)……
对比Oracle多了非常多的数据类型。
官网好些文档并没有随着版本更新。
但详细的步骤和各种资料都是中文的!

(2.2)下载安装包并安装

(2.2.1)准备安装

  • 获取安装包:openGauss-3.0.0-CentOS-64bit.tar.bz2 (极简版)
  • 解压到目录:tar -zxf /xxxx/openGauss-Lite-3.0.0-CentOS-x86_64.tar.gz -C ~/openGauss
  • 检查目录结构:ll ~/openGauss/
总用量 16
drwxr-xr-x. 3 Shion Shion 4096 41 18:24 bin
drwx------. 3 Shion Shion   25 56 10:18 data
drwxr-xr-x. 3 Shion Shion   22 41 18:24 etc
drwxr-xr-x. 3 Shion Shion   24 41 18:24 include
drwxr-xr-x. 4 Shion Shion   95 41 18:24 jre
drwxr-xr-x. 5 Shion Shion 4096 41 18:24 lib
drwx------. 2 Shion Shion  126 56 10:18 logs
drwxr-xr-x. 5 Shion Shion   53 41 18:24 share
drwxr-xr-x. 2 Shion Shion   94 56 10:19 simpleInstall
-rw-r--r--. 1 Shion Shion   32 41 18:24 version.cfg

(2.2.2)准备环境

官网都有,不详细写了,CentOS7:

  • 依赖检查一遍:
  • libaio-devel 建议版本:0.3.109-13
  • flex 要求版本:2.5.31 以上
  • bison 建议版本:2.7-4
  • ncurses-devel 建议版本:5.9-13.20130511
  • glibc-devel 建议版本:2.17-111
  • patch 建议版本:2.7.1-10
  • redhat-lsb-core 建议版本:4.1
  • readline-devel 建议版本:7.0-13
    ——
  • 关闭防火墙
  • 设置字符集参数
  • 设置时区和时间
  • 关闭swap交换内存(可选)
  • 关闭RemoveIPC

(2.2.3)安装

官方的例子是【极简版】不是【轻量版】,那么就按教程来吧。
也不准备弄主备,快点搭建好才行。

simpleInstall目录。
$ sh install.sh -w "你的初始用户密码"

......
Would you like to create a demo database (yes/no)? yes   #这里不yes也行,不生成样例数据库而已。
Load demoDB [school,finance] success. 
...... 
[complete successfully]: You can start or stop the database server using:   
gs_ctl start|stop|restart -D $GAUSSHOME/data/single_node -Z single_node
......

检查:
$ ps -ef |grep -v grep |grep gaussdb
$ gs_ctl query -D ~/openGauss/data/single_node

安装时应该会报错,官网有提到问题和解决方式。

完成后会修改一些环境变量,
但我这安装后它改的.bashrc里面limit -n 1000000会报错。

(2.3)客户端和连接数据库

数据库安装完成后,默认生成名称为postgres的数据库。

(2.3.1)使用gsql命令行连接

$ gsql -d postgres (-p 5432)

gsql ((openGauss 3.0.0 build 02c14696) compiled at 2022-04-01 18:12:34 commit 0 last mr  )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

openGauss=#

(2.3.2)Navicat

平时可没法全用命令行,得有个正常的图形界面管理工具。
Oracle都是用的Toad……这次准备试试Navicat。

但新安装好的openGauss默认不能从别的主机连接数据库,需要:

>>配置pg_hba.conf允许主机连接:

host    all             all             0.0.0.0/0                md5   #使任何地址均可使用md5加密认证方式

>>配置postgresql.conf监听/绑定地址,以及密码加密方式:

listen_addresses = '*'                  # what IP address(es) to listen on;
local_bind_address = '0.0.0.0'             
password_encryption_type = 0            #Password storage type, 0 is md5 for PG, 1 is sha256 + md5, 2 is sha256 only

>>新建数据库用户:
配置好上面两项后重启数据库:

$ gs_ctl restart -D $GAUSSHOME/data/single_node -Z single_node

由于安全原因初始用户不能从网络访问,所以新建用户并赋予权限。

$ gsql -d postgres

openGauss=# CREATE USER ac_man_parse PASSWORD '新用户的密码';
NOTICE:  The encrypted password contains MD5 ciphertext, which is not secure.
CREATE ROLE

openGauss=# ALTER ROLE ac_man_parse SYSADMIN;
ALTER ROLE

>>在Navicat中配置PostgreSQL的方式访问:

在这里插入图片描述
小插曲:

Windows10下的自带防火墙,分配了盘符的磁盘分区上的程序通过没有问题。
但是挂载到空目录的磁盘分区,上面的程序设置规则也没用,自带防火墙依然拦截,原理不明。
所以我收到了很多socket error 10013,害我以为是服务端问题。

(2.3.3)Data Studio

🔗下载页面
不知道为啥我跳过了官方的工具,刚才试了一下,JDK劝退。
虽然Data Studio的readme.txt中写着:

Software:  
----------------------------------------------------------------------
Java 1.8.0_181 or later    

但实际运行则不行,所以没有继续使用。
JDK版本要求

(2.3.3)Toad Edge

正在试用,稍微有点重啊。
反应比较慢,但是操作逻辑和TOAD for Oracle差不多。

呃Freeware版本要求每30天登录一次账号进行授权,未联网机器无解(没有Offline模式)。
所以目前还是放弃,等等看是不是要买商业版。

😄 目前看来能够支持PostgreSQL的客户端工具,都可以连接openGauss呢。

(三)业务数据库结构和元数据迁移

官方提供的工具比如Ora2Pg还没用过。
Navicat迁移数据很方便,包括Blob类型字段数据。没有购买也可以先试用来导数据。

(3.1)用工具迁移数据

1)运行Navicat菜单中的Data Transfer,选源和目标:
在这里插入图片描述

2)设置选项:
我测试中Oracle->PostgreSQL,下面红框中选项(十六进制格式的BLOB)的勾要取消。
而再倒PostgreSQL->PostgreSQL,则要勾上……原理不明……在这里插入图片描述

3)选择对象:
选需要迁移的数据类型和具体对象,如果是同类数据库,则索引、序列等可选。
在这里插入图片描述

4)确认和开始:
点开始后,可以看到进度(我已经导过,这里就不贴图了)。
完成后先别关闭。可以返回去再选另一个数据库来同步。
在这里插入图片描述

5)检查数据结构:
迁移成功后需要检查:各种数据类型长度对不对,大对象(BLOB)内容是否正确。

(3.2)注意建表和导数语法

当然,我们也需要正常的建表导入元数据。
用图形化工具执行脚本很方便,主要问题是Oracle的建表SQL语句需要修改,导入数据语句也需要修改。类似:

  • 去掉: SET DEFINE OFF
  • 去掉: Create table 的修饰NOCOMPRESS,NOCACHE
  • 修改:VARCHAR2(100 BYTE) -> VARCHAR2(100)
  • 修改:ADD (CONSTRAINT XXXXX PRIMARY KEY -> ADD PRIMARY KEY
  • 等等……

不是很明白:PK和Unique的索引,到底要不要自己建?(Oracle不需要)
网上查了一下说PostgreSQL也会自动建,但是看不到啊?

(3.3)表和字段的注释写法

表和字段的注释,不能和Oracle&MySQL一样直接写到建表语句中,
当然Oracle也支持这种先建表再注释的方式,所以脚本还是按照通用的方式写比较方便。如下:

  1. 先建表:CREATE TABLE SampleTable ...
  2. 注释表:COMMENT ON TABLE SampleTable IS '表的注释说明'
  3. 循环注释字段 COMMENT ON COLUMN SampleTable.Field1 IS '字段的注释说明'

(3.4)编码导致长度差异

从上面步骤创建的openGauss数据库字符编码是UTF8
而原Oracle数据库是ZHS16GBK
导入数据时,如果字段内容是中文(多字节)的,则可能原来够用而现在超长。

⚠️注意:并不准确 --> 字段大概估算GBK汉字长度x2,而UTF8汉字长度x3。
具体看这篇《【锟斤拷】的故事:谈谈汉字编码和常用字符集》吧,
这里不再赘述了。

(四)码农的工作(monkey is coding)

(4.1)Java

肯定用JDBC了,
只需要改一点点,其它的用法和Oracle一样(当然得注意SQL语法,别再用Oracle专用函数,省略吐槽)……

(4.1.1)PostgreSQL JDBC Driver

使用PostgreSQL包的方式也可以访问openGauss:

        <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.3.5</version>
        </dependency>
	JDBCUrl = "jdbc:postgresql://host:port/db";
	driverClass = "org.postgresql.Driver";

(4.1.2)OpenGauss JDBC Driver

使用openGauss包的方式:
这一段官方的文档似乎忘记更新了,一处写com.huawei.opengauss,一处还写的postgre。

        <!-- https://mvnrepository.com/artifact/org.opengauss/opengauss-jdbc -->
        <dependency>
            <groupId>org.opengauss</groupId>
            <artifactId>opengauss-jdbc</artifactId>
            <version>3.0.0</version>
        </dependency>
	JDBCUrl = "jdbc:opengauss://host:port/db";
	driverClass = "org.opengauss.Driver";

这种方式会在console打印一些日志,我们的系统需要去掉。
随手丢了个log4j.properties进去,发现亲不是用log4j输出的日志呢……
于是设置loggerLevel=off

		...
		Properties info = new Properties();
		info.setProperty("loggerLevel","off");
		info.setProperty("user", Username);
		info.setProperty("password", gPass);		
		...
		try (Connection conn = DriverManager.getConnection(jdbcUrl, info)) {
			...
		}

(4.1.3)MySQL JDBC Driver

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.29</version>
        </dependency>
	JDBCUrl = "jdbc:mysql://host:port/db";
	driverClass = "com.mysql.cj.jdbc.Driver"; //请注意字符串中间【cj】,不要加载旧驱动了。

(4.1.4)SQL Loader & COPY FROM STDIN & …

>>Oracle

大量数据入库的时候,Oracle可以用SQL Loader:
类似下面的命令行(不是Java也能调用)。
参数direct很重要高速导入都靠它。
文件尽量完整一点,遇到错误可以看logbad更方便。

sqlldr user/password@Database control=sample.ctl log=sample.log bad=sample.bad discard=sample.dis direct=true parallel=true streamsize=16777216

当然,命令行中的控制文件(sample.ctl)需要提前生成,内容大概如下:
稍微有些复杂,比如长字段需要指定长度。

OPTIONS (skip=0)
LOAD DATA CHARACTERSET ZHS16GBK INFILE 'Sample.txt'
APPEND INTO TABLE SampleTable
FIELDS TERMINATED BY X'09'
OPTIONALLY  ENCLOSED BY "'" 
TRAILING NULLCOLS (field1,field2 char(3000),field3, ......)
>>PostgreSQL(openGauss)

它的JDBC提供了一个很类似的方法,还要简单一些。
从文件中拷贝数据到数据库表,如下。
没太多的参数,返回入库了的条数。

...
import org.opengauss.copy.CopyManager;
import org.opengauss.core.BaseConnection;
...
    public static long copyFromFile(Connection connection, String filePath, String tableName) throws SQLException, IOException {
        try (FileInputStream fileInputStream = new FileInputStream(filePath)){
            CopyManager copyManager = new CopyManager((BaseConnection)connection);
            return copyManager.copyIn("COPY " + tableName + " FROM STDIN with (DELIMITER '\t', ENCODING 'gb18030')", fileInputStream);
        }
    }

分隔符和字符集根据实际情况替换。
比较奇怪的是官网文档的例子居然有语法问题,漏写了逗号,还写得很长……

试了一下主表50万左右的用户量,一共10多张表导入,包括建立索引:
感觉没比insert语句更快啊……
如果正式用起来这个速度……ToT

  • Oracle 12c: 20
  • openGauss 3.0.0: 240

试了可以报错,比如:extra data after last expected column
并不会看不出问题在哪,这个就是文本字段多了。

>>MySQL

LOAD DATA LOCAL INFILE ‘xxxx’
参考:🔗这里
……

(4.2)C & C++

(4.2.1)头文件

头文件来自分别安装的客户端。

extern "C" {
	#include "mysql.h"
	#include "libpq-fe.h"
}

(4.2.2)PostgreSQL(libpq)

其实都是c代码,
真实SQL最好用绑定变量,而不是下面的一堆NULL,SQL全字符串拼接。
这方面资料很多所以不写了,例子:

	//连接
	sprintf(connStr,"user=%s password=%s host=%s port=%s dbname=%s sslmode=disable",xxx,yyy,zzz,...);
	PGconn *z_pgSession = PQconnectdb(connStr);
	if (PQstatus(z_pgSession)!=CONNECTION_OK)
		throw MyException(PQerrorMessage(z_pgSession));
	......
	
	//执行insert,update,...
	PGresult * pres=PQexec(z_pgSession, "update ...");
		if (PGRES_COMMAND_OK!=PQresultStatus(pres))
			throw MyException(PQerrorMessage(z_pgSession));		
		PQclear(pres);	
	......
	
	//执行查询(字符串)
	PGresult * pres=PQexec(z_pgSession, "select ...");
	if (PQresultStatus(pres) != PGRES_TUPLES_OK)
		throw MyException(PQerrorMessage(z_pgSession));
	int RowCount = PQntuples(pres) ;
	for(int RowIndex = 0;RowIndex < RowCount; RowIndex++)
	{
		unsigned int rowcount = PQnfields(pres);
		strcpy(value1 , PQgetvalue(pres,RowIndex,0));
		strcpy(value2 , PQgetvalue(pres,RowIndex,1));
		......
	}
	PQclear(pres);
	......
	
	//执行查询(二进制)
	PGresult * preXs=PQprepare(z_pgSession, "","select blob ...",0,NULL);
	if (preXs== NULL)
		throw MyException(PQerrorMessage(z_pgSession));
	PQclear(preXs);
	
	PGresult * pre3s=PQexecPrepared(z_pgSession, "",0,NULL,NULL,NULL,1);
	if (PQresultStatus(pre3s) != PGRES_TUPLES_OK)
		throw MyException(PQerrorMessage(z_pgSession));
					
	unsigned long obj1size = PQgetlength(pre3s,0,0);
	std::ofstream ofs; //sorry, c++ 更方便
	ofs.open("filename",std::ios::out|std::ios::binary);
	if (obj1size>0) //有内容才写
	{
		char *object = (char*)malloc(obj1size);
		if (object == NULL){
			throw MyException("error alloc mem...");
		}
		memcpy(object, PQgetvalue(pre3s,0,0), obj1size);
		ofs.write(object,obj1size);
		free(object);
	}
	ofs.close();		
	PQclear(pre3s);
	...

	PQfinish(z_pgSession);

(4.2.3)MySQL

和上面几乎是一样的流程,
呃,但没懂MySQL怎么用绑定变量。例子:

	//连接
	MYSQL *z_mySession=mysql_init(NULL);
	if (z_mySession==NULL)
		throw MyException("Error mysql_init");

	if (mysql_real_connect(z_mySession,"Host","User", "Passwd","DBName","Port"),NULL,0)==NULL)
		throw MyException(mysql_error(z_mySession));
	......

	//执行查询
	if(mysql_query(z_mySession,"select ...")!=0)
		throw MyException(mysql_error(z_mySession));	
	MYSQL_RES *result = mysql_store_result(z_mySession);
	if (result==NULL)
    	throw MyException(mysql_error(z_mySession));    		
	while (MYSQL_ROW sql_row = mysql_fetch_row(result))
	{
		strcpy(value1 , sql_row[0]);
		strcpy(value2 , sql_row[1]);
		......
	}
	mysql_free_result(result);
	......

	//执行查询(二进制)
	if(mysql_real_query(z_mySession,"select blob ...",SQLlength)!=0)
		throw MyException(mysql_error(z_mySession));
	MYSQL_RES *result2 = mysql_store_result(z_mySession);
	if (result2==NULL)
		throw MyException(mysql_error(z_mySession));
	if (MYSQL_ROW sql_row2 = mysql_fetch_row(result2))//获取具体的数据
	{
		unsigned long *rowlength =  = mysql_fetch_lengths(result2);
		unsigned int rowcount  = mysql_num_fields(result2);
		unsigned long objsize = rowlength [0];
		std::ofstream ofs;
		ofs.open("filename",std::ios::out|std::ios::binary);
		if (obj1size>0) //其实也可以不判断,直接 malloc(0)。
		{
			char *object = (char*)malloc(obj1size);
			if (object == NULL){
				throw MyException("error alloc mem...");
			}
			memcpy(object, sql_row2[0], objsize);
			ofs.write(object,obj1size);
			free(object);
		}
		ofs.close();
	}
	......

	mysql_close(z_mySession);

(4.2.4)客户端环境(Ubuntu)

用C可没有Java那么方便,运行也需要客户端的库。
所以需要一些准备:

$ sudo apt install libpq-dev
$ sudo apt install libmysqlclient-dev

PS:开发方面参考:🔗《Linux编译C++项目找到.so库后找不到里面的函数》
哎……

(4.3)Object Pascal

单身20年的delphi7老程序本已停止维护,都准备放弃了。
通过Java发现既然PostgreSQL方式可以访问openGauss,那么也试试,结果可以:

	MainSession.Close;
	MainSession.ProviderName:='PostgreSQL';
	MainSession.Server:=theHost;
	MainSession.Port:=StrToIntDef(thePort,-1);
	MainSession.Database:=theDB;
	MainSession.Username:=Username;
	MainSession.Password:=gPass;
	MainSession.Open;

但需要注意,主机、端口、数据库名称。
需要像上面的代码拆开分别赋值。
注意不能和Oracle一样直接MainSession.Server:=//ip:port/databasename
另外似乎也不能乱加数据库不支持的参数比如MainSession.SpecificOptions.Values['xxxxx'] := 'yyyyy';
毕竟不是只支持Oracle一种数据库了。

⚠️ ⚠️ ⚠️ 神秘的bug ⚠️ ⚠️ ⚠️
【delphi+unidac+openGauss】,当SQL选出的字段是日期型(Timestamp)时(包括选now())。
程序.AsDatetime取到的任何日期永远是2000-01-01 08:00:00,用.value也一样,取出来时已经变了。
其它语言和数据库组合未发现这种问题。
不知道是unidac的锅,还是openGauss的锅。
目前不知道怎么解决,暂时改程序,绕过不要直接取日期。

(4.4)大小写问题

Oracle默认所有对象名称大写(除非你加双引号强行小写)。
PostgreSQL则都是小写。

在一般的SQL中不会有什么问题,但是牵涉到选出表名做比较时,两个数据库就不一样了。
最好用Upper(字段)来进行统一,否则只能程序里if else判断不同的库写不同的SQL了。

还有,登录的用户名Oracle随意大小写,
但是PostgreSQL需要严格区分。

(4.5)特有语法与高亮

不仅处理部分需要考虑不同的数据库语法。
有显示或配置界面的地方,得注意不同数据库特有的关键字,加以高亮。
比如Oracle的`

select sysdate from dual;

比如PostgreSQL

select now();

(五)未完待续

【2022-05-07】弄了一整天总算可以简单的访问openGauss了,以后的工作和遇到的问题,再继续记录吧。
【2022-05-10】增加了表和字段注释脚本问题,以及sqlldrCOPY FROM STDIN导入文件内容。
【2022-05-13】对比sqlldrCOPY FROM STDIN效率,报错。语法和高亮。神秘bug。客户端工具。
【2022-07-28】一些C++的代码例子。

实际做下来SQL改动不少……
具体请参考下一篇:🔗《业务系统兼容数据库Oracle/PostgreSQL(openGauss)/MySQL的琐事》


<think>好的,我现在需要帮助用户解决将Oracle数据库迁移高斯数据库的问题。首先,我需要确认用户提到的“EBS Oracle”是什么。通常来说,EBS是指Oracle的电子商务套件(E-Business Suite),而用户可能是在使用Oracle数据库作为后端,现在想迁移高斯(GaussDB)数据库,这是华为推出的一款关系型数据库。 接下来,我需要考虑用户可能的背景和需求。用户可能是一个企业IT人员或者数据库管理员,负责系统迁移工作。他们的主要需求可能是了解迁移的步骤、注意事项以及工具支持。此外,用户可能关心迁移过程中如何保证数据一致性、应用兼容性以及性能优化等问题。 用户可能没有明确提到的深层需求包括迁移后的系统稳定性、迁移的时间成本、潜在的兼容性问题以及是否需要外部支持等。因此,在回答中需要涵盖这些方面,提供全面的指导。 接下来,我需要整理迁移的主要步骤。通常,数据库迁移包括评估和规划、环境准备、数据迁移、应用适配、测试验证以及切换上线等阶段。每个阶段都需要详细说明,特别是针对Oracle到GaussDB的特殊注意事项,比如数据类型转换、SQL语法差异、存储过程和触发器的改写等。 同时,工具支持是关键部分。华为是否有提供专门的迁移工具?比如华为的UGO(数据库和应用迁移工具)和DRS(数据复制服务)是否支持从Oracle到GaussDB的迁移。需要确认这些工具的功能,比如结构迁移、数据同步、语法转换等。 兼容性问题也是重点。Oracle和GaussDB在SQL语法、事务处理、存储过程等方面存在差异,需要指出常见的兼容性问题和解决方案。例如,Oracle的PL/SQL需要转换为GaussDB的PL/pgSQL,或者使用其他方式实现。 性能优化方面,迁移后可能需要调整索引、查询语句或配置参数,以适应GaussDB的特性。这部分需要给出一些优化建议,帮助用户提升迁移后的数据库性能。 另外,需要提醒用户注意数据一致性校验的重要性,确保迁移过程中没有数据丢失或损坏。同时,回滚计划也是必要的,以防迁移过程中出现不可预见的问题。 最后,总结整个迁移过程,强调逐步进行的重要性,并建议用户参考官方文档或联系技术支持获取更详细的帮助。可能还需要提到华为提供的专业服务,如迁移咨询和技术支持,帮助用户顺利完成迁移。 在回答时,要使用清晰的结构,分点说明每个步骤和注意事项,确保用户能够按部就班地进行操作。同时,语言要简洁明了,避免使用过于专业的术语,或者在必要时进行解释,以便不同技术背景的用户都能理解。</think>将Oracle数据库(尤其是Oracle E-Business Suite相关环境)迁移到华为高斯数据库(GaussDB)是一个涉及多个环节的复杂过程,需要系统性的规划和验证。以下是迁移的主要步骤和注意事项: --- ### **1. 迁移前的评估与规划** - **兼容性分析**: - **对象兼容性**:检查Oracle的表结构、索引、视图、存储过程、触发器等在高斯数据库中是否支持。例如: - Oracle的`NUMBER`类型需转为GaussDB的`NUMERIC`或`DECIMAL`。 - 高斯DB对PL/SQL的兼容性有限,需重写或调整为PL/pgSQL。 - **SQL差异**:识别Oracle特有的语法(如`ROWNUM`、`CONNECT BY`层级查询)并适配为GaussDB支持的语法(如`ROW_NUMBER()`窗口函数、递归CTE)。 - **工具评估**: - **华为UGO(数据库和应用迁移工具)**:用于自动分析Oracle对象兼容性,生成迁移报告并转换DDL/DML。 - **DRS(数据复制服务)**:支持全量+增量数据迁移,减少停机时间。 - **制定回退方案**:确保迁移失败时可快速切回原库。 --- ### **2. 迁移步骤** #### **2.1 结构迁移** - **使用UGO转换数据库对象**: - 自动转换表、索引、约束等对象定义。 - 对存储过程、函数等需手动调整逻辑(如Oracle的`DBMS_JOB`需替换为高斯DB的定时任务)。 - **示例转换**: ```sql -- Oracle原生语法 CREATE SEQUENCE seq_emp START WITH 1 INCREMENT BY 1 CACHE 20; -- GaussDB适配 CREATE SEQUENCE seq_emp START 1 INCREMENT 1 CACHE 20; ``` #### **2.2 数据迁移** - **全量迁移**: - 使用DRS或`gs_dump/gs_restore`工具导出Oracle数据(如通过CSV或Oracle Data Pump),再导入GaussDB。 - 注意字符集兼容(如Oracle的`AL32UTF8`与GaussDB的`UTF8`)。 - **增量同步**: - 在业务低峰期启动DRS的增量同步,持续捕获Oracle的redo log或归档日志,确保数据实时同步。 #### **2.3 应用适配** - **JDBC/ODBC配置**: - 修改应用的数据库连接字符串,指向GaussDB实例。 - 替换Oracle驱动为GaussDB的`gsjdbc4.jar`驱动。 - **SQL改写**: - 例如,Oracle的`SYSDATE`改为GaussDB的`CURRENT_TIMESTAMP`。 - 分页查询从`ROWNUM`改为`LIMIT/OFFSET`。 - **事务与锁机制**: - GaussDB的MVCC机制与Oracle存在差异,需验证应用在高并发下的行为。 --- ### **3. 验证与优化** - **功能验证**: - 对关键业务场景进行全链路测试(如订单提交、报表生成)。 - 验证存储过程逻辑的正确性(尤其是异常处理部分)。 - **性能调优**: - **索引优化**:根据执行计划分析缺失索引(GaussDB的`EXPLAIN ANALYZE`)。 - **参数调整**:优化`work_mem`、`shared_buffers`等参数以适应业务负载。 - **并行查询**:利用GaussDB的并行计算能力加速复杂查询。 --- ### **4. 切换与监控** - **最终切换**: - 停止Oracle写入,等待DRS完成最后一次增量同步。 - 使用华为Cloud Eye监控GaussDB的CPU、内存、锁等待等指标。 - 配置慢查询日志,定期分析性能瓶颈。 --- ### **5. 常见问题与解决** - **数据不一致**:使用校验工具(如`md5sum`对比关键表)确保数据完整性。 - **时区问题**:检查时间类型字段的时区设置(GaussDB默认使用UTC)。 - **权限迁移**:手动重建Oracle的角色和权限(GaussDB的权限模型与Oracle不同)。 --- ### **工具与资源** - **官方文档**:[GaussDB迁移指南](https://support.huaweicloud.com/usermanual-gaussdb/gaussdb_01_0010.html) - **华为支持**:可联系华为云团队获取迁移方案咨询或POC(概念验证)支持。 --- 迁移过程中建议分阶段实施(如先迁历史库再迁生产库),并预留充足的测试时间。若涉及Oracle EBS等复杂系统,需协调应用厂商共同验证业务兼容性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值