Oracle11.2.0.1.0数据迁移到udb

本节讲述 data2udb 工具的使用,此工具可以将 表结构/数据/视图/函数/存储过程/触发器等 导出到文件,并对语法自动转换,最后将文件导入到udb。
结合ogg实现增量数据同步。

注意事项

  • 目标端对应数据库的表将被清除,如有重要数据请先备份

  • 需要 docker 环境

  • arm架构服务器仅支持全量迁移

  • 内存需大于4G

  • 数据导出时需要落到磁盘上,确保磁盘空间充足

  • 确保系统时间和源端目标端一致

  • 账号,密码,库名不建议有特殊字符

  • Oracle必须大于等于10.2.0.5(对于 10g)或11.2.0.2(对于 11g).否则需要把redo文件(例如/home/oracle/app/oracle/oradata/helowin/redo03.log)挂载到容器内

  • 增量同步期间不支持表结构变更

操作步骤

准备连接信息—–下载容器镜像—–启动容器—–获取当前SCN号—–准备增量同步—–全量导出—–全量导入—–开启增量同步

准备

开启oracle日志

sqlplus / as sysdba

--设置日志和启动OGG复制
alter database force logging;
alter database add supplemental log data;
--alter system set enable_goldengate_replication=true;

select force_logging,supplemental_log_data_min from v$database;
--上述查询结果均为YES

开启归档

mkdir -p /home/oracle/app/oracle/oradata/arch
sqlplus / as sysdba

alter system set log_archive_dest_1='location=/home/oracle/app/oracle/oradata/arch' scope=spfile;
shutdown immediate;
startup mount;
alter database archivelog;
alter database open;
archive log list;

账号授权

sqlplus / as sysdba

create user test identified by test;
grant dba to test;

例如:
s_h=192.168.4.11 #源端地址
s_p=1521 #源端端口
s_s=orcl #源端数据库服务名或SID
s_d=TEST1 #源端数据库名
s_u=TEST1 #源端账号
s_w=test #源端密码

d_h=192.168.4.11 #目标端地址
d_p=5678 #目标端口
d_d=test1_ora19c #目标端库名
d_u=unvdb #目标端账号
d_w=tx #目标端密码

下载容器镜像文件

x86_64 http://download.unvdb.com/您的服务编码/source/tool/ogg/app/x86_64/data2udb.tar.gz
arm64 http://download.unvdb.com/您的服务编码/source/tool/ogg/app/aarch64/data2udb.tar.gz
服务编码联系技术支持获取

启动容器

导入docker镜像

docker load -i 容器镜像文件    
Loaded image: data2udb_x86:v24.8 
#导入的镜像是 data2udb_x86:v24.8,下文使用此名称创建容器 

创建容器

docker run --network=host -it --name data2udb -e TZ=Asia/Shanghai -e s_h=源端地址 -e s_p=源端端口 -e s_s=源端服务名或SID -e s_d=源端数据库名,通常和账号相同 -e s_u=源端账号 -e s_w=源端密码 -e d_h=目标端地址 -e d_p=目标端口 -e d_d=目标端数据库名 -e d_u=目标端账号 -e d_w=目标端密码 -e ty=full -v /home/oracle/app/oracle/oradata:/home/oracle/app/oracle/oradata:ro  data2udb_x86:v24.8 /bin/bash
#请对应修改账号信息和镜像名称和redo挂载目录    

获取当前SCN号

记录oracle SCN 号,后面使用此号码继续增量同步.

export LD_LIBRARY_PATH=/usr/lib/oracle/19.10/client64/lib/
scn=`sqlplus -s /nolog <<EOF
set heading off feedback off pagesize 0 verify off echo off
connect $s_u/$s_w@//$s_h:$s_p/$s_s
SELECT to_char(current_scn) FROM v\\$database;
quit
EOF`
echo "get now SCN $scn"

准备增量同步,仅当增量同步时操作

开启目标端接收

export LD_LIBRARY_PATH=/app/udb/lib/:/app/instantclient_19_3/
cat << EOF > /etc/odbc.ini
[unvdb]
Description = unvdb
Driver = /app/udb/lib/GGpsql25.so
Database = $d_d
Servername = $d_h
UserName = $d_u
Password = $d_w
PortNumber = $d_p
ReadOnly = 0
ConnSettings = set client_encoding to UTF8
EOF

cat << EOF > /app/udb/dirprm/repz.prm
replicat repz
SETENV(ODBCINI=/etc/odbc.ini)
SETENV(NLS_LANG=AMERICAN_AMERICA.ZHS16GBK)
ASSUMETARGETDEFS
TARGETDB unvdb,userid $d_u,password $d_w
DISCARDFILE ./dirrpt/repz.rpt, append
reportcount every 60 seconds, rate
cachemgr  cachesize  1G 
container  mem_limit  2G
map $s_d.*, target public.*;
EOF

启动目标端接收

cat << EOF > /tmp/2
start mgr
dblogin sourcedb unvdb
add checkpointtable public.checkpointtab
add replicat repz,exttrail ./dirdat/11,checkpointtable public.checkpointtab
exit
EOF

/app/udb/ggsci paramfile /tmp/2 

配置源端提取

cat << EOF > /app/instantclient_19_3/network/admin/tnsnames.ora
ORCL =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = ${s_h})(PORT = ${s_p}))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = ${s_s})
    )
  )
EOF
cat << EOF > /app/ogg11/dirprm/mgr.prm
port 9060
dynamicportlist 9061-9069
purgeoldextracts ./dirdat/*, usecheckpoints,minkeepfiles 5
AUTORESTART ER *, RETRIES 3, WAITMINUTES 2,RESETMINUTES 10
EOF

echo "ggschema ${s_u}" > /app/ogg11/GLOBALS

cat << EOF > /app/ogg11/dirprm/extz11.prm
extract extz11
USERID $s_u@orcl, PASSWORD $s_w
DYNAMICRESOLUTION
discardfile ./dirrpt/extz11.dsc, append
rmthost 127.0.0.1, mgrport 8030, tcpbufsize 288750, tcpflushbytes 288750
RMTTRAIL ./dirdat/11
reportcount every 60 seconds, rate
TABLE $s_d.*;
EOF

启动源端提取

cat << EOF > /tmp/s11
create subdirs
start mgr
dblogin userid $s_u@orcl password $s_w
add trandata $s_d.*
add ext extz11, tranlog, begin now
add exttrail ./dirdat/11, extract extz11
START EXTRACT extz11
exit
EOF

/app/ogg11/ggsci paramfile /tmp/s11

检查增量数据

在源端插入数据, /app/udb/dirdat/ 目录下存在ea开头的文件,说明增量数据已经开始接收

ls /app/udb/dirdat/ -al
total 4
drwxr-x--- 1 root root   33 Aug  5 10:50 .
drwxr-xr-x 1 root root  140 Aug  5 10:45 ..
-rw-r----- 1 root root 1336 Aug  5 10:50 ea000000000

执行全量导出

准备ddl导出配置文件

mkdir /data/oradata -p
cat <<EOF > /tmp/ddl.conf 
ORACLE_HOME        /usr/lib/oracle/19.10/client64/
ORACLE_DSN         dbi:Oracle://$s_h:$s_p/$s_s
#源端为oracle
#ORACLE_DSN         dbi:mysql:host=$s_h;database=$s_s;port=$s_p
#源端为mysql
ORACLE_USER        $s_u
ORACLE_PWD         $s_w
SCHEMA             $s_u
#Oracle一般和用户名相同,Mysql使用库名
USE_RESERVED_WORDS 1
#启用后关键字用双引号包起来
#INDEXES_SUFFIX _idx
#给索引名添加后缀,当索引跟表同名时,建议配置该项
INDEXES_RENAMING 1
#按照“表名_列名“的格式给索引重命名,当多次使用相同索引名或相同表名的数据库,建议开启
NULL_EQUAL_EMPTY 1
#把Null设置为空字符串
#EXPORT_SCHEMA 1
#导出模式,默认为0
#CREATE_SCHEMA 1
#在导出的文件中创建模式,默认为0。这里的模式对应oracle用户名或者SCHEMA
TYPE               TYPE,TABLE,FUNCTION,GRANT,MVIEW,PARTITION,PROCEDURE,VIEW,TRIGGER,SEQUENCE,SYNONYM,SEQUENCE_VALUES
#导出类型,表,函数等对象
PG_NUMERIC_TYPE    0
PG_INTEGER_TYPE    1
#DATA_TYPE          NUMBER:bigint
DEFAULT_NUMERIC    numeric
ENABLE_MICROSECOND      1
#开启时间类型YYYY-MM-DD HH24:MI:SS.FF,设置为0时间类型则是YYYY-MM-DD HH24:MI:SS
#REPLACE_ZERO_DATE 
#默认将0000-00-00 00:00:00 替换为 NULL。但当列有非空约束时,需配置该项, 替换为 1970-01-01 00:00:00
EMPTY_LOB_NULL 1
#将空的empty数据指定为null,如果有大量的空lob数据列,建议开启,可以提升迁移速度
#PACKAGE_AS_SCHEMA	0
#不将包导出为模式,而是导出为简单函数
#SKIP               fkeys checks
#SKIP              keys pkeys ukeys indexes checks
#NLS_LANG           AMERICAN_AMERICA.UTF8
#设置字符编码
OUTPUT_DIR         /data/oradata
#输出sql目录
OUTPUT             ddl.sql
PG_VERSION         14
#STOP_ON_ERROR 0
PACKAGE_AS_SCHEMA 1
PREFIX_PARTITION 1
PREFIX_SUB_PARTITION 1
DISABLE_PARTITION 1
RENAME_PARTITION 1
TRANSACTION readonly
EOF

准备数据导出配置文件

cat << EOF > /tmp/data.conf
ORACLE_HOME        /usr/lib/oracle/19.10/client64/
ORACLE_DSN         dbi:Oracle://$s_h:$s_p/$s_s
#源端为oracle
#ORACLE_DSN         dbi:mysql:host=$s_h;database=$s_s;port=$s_p
#源端为mysql
ORACLE_USER        $s_u
ORACLE_PWD         $s_w
SCHEMA             $s_u
TYPE               COPY
USE_RESERVED_WORDS 1
#启用后关键字用双引号包起来
#INDEXES_SUFFIX _idx
#给索引名添加后缀,当索引跟表同名时,建议配置该项
INDEXES_RENAMING 1
#按照“表名_列名“的格式给索引重命名,当多次使用相同索引名或相同表名的数据库,建议开启
NULL_EQUAL_EMPTY 1
#把Null设置为空字符串
#STOP_ON_ERROR 0
PG_NUMERIC_TYPE    0
PG_INTEGER_TYPE    1
DEFAULT_NUMERIC    numeric
ENABLE_MICROSECOND      1
#REPLACE_ZERO_DATE 
EMPTY_LOB_NULL 1
#PACKAGE_AS_SCHEMA	0
#SKIP               fkeys checks
#SKIP              fkeys pkeys ukeys indexes checks
#NLS_LANG           AMERICAN_AMERICA.UTF8
OUTPUT_DIR         /data/oradata
OUTPUT             data.sql
FILE_PER_TABLE    1
#每个表导出为一个文件,默认所有数据导出到一个文件
PREFIX_PARTITION 1
PREFIX_SUB_PARTITION 1
DISABLE_PARTITION 1
RENAME_PARTITION 1
#如果您希望重命名分区表,请启用此指令。
#默认情况下禁用。
#如果您有多个分区表,则在导出时,某些分区可能具有相同的名称但不同的父表。这是不允许的,表名必须是唯一的,在这种情况下启用此指令。分区将按照以下规则重命名:“tablename”_part“pos”,其中“pos”是分区号。
#对于子分区,这是:“tablename”_part“pos”_subpart“pos”如果这是分区/子分区默认值:“tablename”_part_default“tablename”_part“pos”_subpart_default
TRANSACTION readonly
JOBS                 32
#线程并发数
DATA_LIMIT 50000
#每次导出50000行数据
#PARALLEL_TABLES 4
#表并行数

#EXCLUDE           table1 example_.*
#排除表
#ALLOW   CUSTOMER,STUDENT,APPLICATION,EMPLOYEE
#只导出指定表
#PG_DSN             dbi:Pg:dbname=oracle;host=192.168.2.81;port=5678
#PG_USER            unvdb
#PG_PWD             udb
#PG_SCHEMA          soe
#以上几项开启时将直接导入udb,注意要先手动在udb创建好表和schema
PG_VERSION         14
EOF

开始导出

data2udb -c /tmp/ddl.conf
[========================>] 11/11 tables (100.0%) end of scanning.          
[========================>] 0/0 types (100.0%) end of output.     
[========================>] 11/11 tables (100.0%) end of table export. 
[========================>] 0/0 functions (100.0%) end of functions export.
[========================>] 0/0 materialized views (100.0%) end of output. 
[========================>] 0/0 partitions (100.0%) end of output.        
[========================>] 0/0 procedures (100.0%) end of procedures export.
[========================>] 0/0 views (100.0%) end of output.                
[========================>] 0/0 triggers (100.0%) end of output.
[========================>] 0/0 sequences (100.0%) end of output.
[========================>] 0/0 synonyms (100.0%) end of output.
data2udb -c /tmp/data.conf  --scn $scn #按scn导出
[========================>] 11/11 tables (100.0%) end of scanning.          
[========================>] 119121/119121 rows (100.0%) Table FRGH_BILL (29 sec., 4107 recs/sec)                     
[========================>] 161699/161699 rows (100.0%) Table FRGH_ORDER (18 sec., 8983 recs/sec)                     
[========================>] 1765938/1765938 rows (100.0%) Table INV_ENTRY (61 sec., 28949 recs/sec)                     
[========================>] 115629/115629 rows (100.0%) Table INV_SKU (7 sec., 16518 recs/sec)                          
[========================>] 0/0 rows (100.0%) Table INV_STACK (0 sec., 0 recs/sec)                                    
[========================>] 1385773/1385773 rows (100.0%) Table INV_TALLY (71 sec., 19517 recs/sec)                     
[========================>] 2165/2165 rows (100.0%) Table REF_VESSEL (1 sec., 2165 recs/sec)                            
[========================>] 444288/444288 rows (100.0%) Table TALLY_TICKET (23 sec., 19316 recs/sec)                       
[========================>] 3507/3507 rows (100.0%) Table VSL_VISIT (2 sec., 1753 recs/sec)                                
[========================>] 7014/7014 rows (100.0%) Table VSL_VOYAGE (2 sec., 3507 recs/sec)                            
[========================>] 1/1 rows (100.0%) Table t1 (1 sec., 1 recs/sec)                                          
[========================>] 4005135/4005135 rows (100.0%) on total estimated data (216 sec., avg: 18542 tuples/sec)

执行全量导入

导入之前通过以下命令调整导入顺序,如主键外键触发器等需要在导入数据后执行.

提取主键外键

grep 'FOREIGN KEY' /data/oradata/TABLE_ddl.sql > /tmp/foreign.sql #提取外键  
grep '^ALTER TABLE' /data/oradata/TABLE_ddl.sql | grep -v 'FOREIGN KEY' > /tmp/alter.sql #提取主键
cp /data/oradata/TABLE_ddl.sql /tmp/TABLE_ddl.sql && sed -i '/FOREIGN KEY/d' /data/oradata/TABLE_ddl.sql #删除外键
sed -i "s/^ALTER TABLE/-- ALTER TABLE/g" /data/oradata/TABLE_ddl.sql #删除主键

导入对象

export LD_LIBRARY_PATH=/app/udbclient/lib PGPASSWORD=$d_w

/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/TABLE_ddl.sql;
/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/FUNCTION_ddl.sql;
/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/GRANT_ddl.sql;
/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/MVIEW_ddl.sql;
/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/PARTITION_ddl.sql;
/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/PROCEDURE_ddl.sql;
/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/VIEW_ddl.sql;
/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/SEQUENCE_ddl.sql;
/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/SYNONYM_ddl.sql;

注意: 自定义类型 /data/oradata/TYPE_ddl.sql 语法转换可能会不正确,需要手动处理.可以参考 https://www.sqlines.com/online 网站 进行转换或联系技术支持协助.

此时所有对象已导入目标库中.

导入数据

/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/data.sql

请务必确认此步骤无报错.

导入主键/外键/触发器

/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /tmp/alter.sql 
/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /tmp/foreign.sql 
/app/udbclient/ud_sql -v ON_ERROR_STOP=1 -h $d_h -p $d_p -U $d_u -w $d_d -f /data/oradata/TRIGGER_ddl.sql 

此时所有数据已导入目标库中.

开启增量同步,仅当增量同步时操作

export LD_LIBRARY_PATH=/app/udb/lib/:/app/instantclient_19_3/
echo "START REPLICAT repz, AFTERCSN $scn" > /tmp/3
echo "exit" >> /tmp/3
/app/udb/ggsci paramfile /tmp/3

此时在源端的数据修改操作会同步到目标端.

其它命令

docker exec data2udb /bin/bash -c '/app/scripts/status.sh' #查看增量同步状态
docker exec data2udb /bin/bash -c 'cat /app/udb/dirrpt/REPZ.rpt' #查看增量同步接收报告
docker logs -f data2udb #查看容器日志
docker stop data2udb #停止容器
docker rm data2udb #删除容器
cat /app/udb/ggserr.log #查看目标端增量同步进程日志
cat /app/ogg11/ggserr.log #查看源端增量同步进程日志