Mysql数据迁移到udb
本节讲述 data2udb 工具的使用,此工具可以将 mysql表结构/数据/视图/函数/存储过程/触发器等 导出到文件,并对语法自动转换,最后将文件导入到udb。
结合ogg实现增量数据同步。
注意事项
目标端对应数据库的表将被清除,如有重要数据请先备份
需要 docker 环境
arm架构服务器仅支持全量迁移
内存需大于4G
数据导出时需要落到磁盘上,确保磁盘空间充足
账号,密码,库名不建议有特殊字符
Mysql 版本需大于5.1.5
binlog_format 必须是 ROW
必须存在和用户名相同的库名,仅用于连通性检查
确保系统时间和源端目标端一致
Mysql认证插件只支持 mysql_native_password ,同时分配数据库只读权限. 例如:
CREATE USER youruser@% IDENTIFIED WITH mysql_native_password BY 'yourpwd'; GRANT Index, Lock Tables, Select, Show Databases, Show View ON *.* TO youruser@%;
.如果直接修改原有用户的认证插件,可能需要重新设置密码才生效.增量同步目前不支持停机迁移,需要先停止数据库写入,等全量导入完成后再允许写入.
可以利用mysql从实例,源端使用从实例,结合
stop slave;start salve;
实现间接零停机增量同步到增量同步期间不支持表结构变更
操作步骤
准备连接信息—–下载容器镜像—–启动容器—–停止源端写入—–准备增量同步—–全量导出—–全量导入—–开启增量同步
以下以mysql5.7.41为例.
准备
检查源端和账号名相同的库名是否存在
检查源端是否开启bin_log show variables like "%log_bin%";
, log_bin 值为ON,仅用于增量同步
检查源端binlog格式 show variables like "%binlog_format%";
,binlog_format值为ROW,仅用于增量同步
准备源端和目标端账号/密码/端口/库名/信息
例如:
s_h=192.168.4.11 #源端地址
s_p=3309 #源端端口
s_s=tpcc #源端数据库名
s_d=tpcc #源端数据库名
s_u=root #源端账号
s_w=root #源端密码
d_h=192.168.4.11 #目标端地址
d_p=5678 #目标端口
d_d=tpcc_mysql #目标端库名
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=源端数据库名 -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 data2udb_x86:v24.8 /bin/bash
#请对应修改账号信息和镜像名称
停止源端写入,仅当增量同步时操作
如需使用增量同步,请务必停止源端写入操作.
或在从实例中执行 stop slave;
断开同步.
准备增量同步,仅当增量同步时操作
开启目标端接收
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)
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/ea,checkpointtable public.checkpointtab
exit
EOF
/app/udb/ggsci paramfile /tmp/2
开启源端提取
cat << EOF > /app/mysql/dirprm/extz.prm
extract extz
setenv (TZ="GMT+8")
-- 需要和database time zone as timestamp in MySQL 设置一致
sourcedb $s_u@$s_h:$s_p,userid $s_u,password $s_w
-- 必须存在和用户名相同的数据库
TRANLOGOPTIONS ALTLOGDEST REMOTE
-- 远程获取binlog数据
-- tranlogoptions altlogdest /var/lib/mysql/mysql-bin.index
-- 使用本地的binlog数据
rmthost 127.0.0.1, mgrport 8030, tcpbufsize 288750, tcpflushbytes 288750
RMTTRAIL ./dirdat/ea
discardfile ./dirrpt/extz.dsc, append
gettruncates
-- 默认情况下OGG 是不捕获truncate 操作,使用此参数捕获truncate。EXTRACT端和REPLICAT端都需要开启(有时目标端不开启也行)
cachemgr cachesize 1G
container mem_limit 2G
reportcount every 60 seconds, rate
table $s_d.*;
EOF
启动源端提取
cat << EOF > /tmp/2
start mgr
add ext extz, tranlog, begin now
add exttrail ./dirdat/ea, extract extz
START EXTRACT extz
exit
EOF
/app/mysql/ggsci paramfile /tmp/2
检查增量数据
确认 /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:mysql:host=$s_h;database=$s_s;port=$s_p
#支持以上3种方式
ORACLE_USER $s_u
ORACLE_PWD $s_w
SCHEMA $s_s
USE_RESERVED_WORDS 1
#启用后关键字用双引号包起来
#INDEXES_SUFFIX _idx
#给索引名添加后缀,当索引跟表同名时,建议配置该项
INDEXES_RENAMING 1
#按照“表名_列名“的格式给索引重命名,当多次使用相同索引名或相同表名的数据库,建议开启
NULL_EQUAL_EMPTY 1
#把Null设置为空字符串
#oracle账号密码
#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
#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
#JOBS 6
#多个jobs会导致trigger分成多个文件
EOF
准备数据导出配置文件
cat << EOF > /tmp/data.conf
ORACLE_HOME /usr/lib/oracle/19.10/client64/
ORACLE_DSN dbi:mysql:host=$s_h;database=$s_s;port=$s_p
ORACLE_USER $s_u
ORACLE_PWD $s_w
SCHEMA $s_s
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
#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
TRANSACTION readonly
JOBS 32
#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
[========================>] 11/11 tables (100.0%) end of scanning.
[========================>] 4/4 rows (100.0%) Table bmsql_config (0 sec., 4 recs/sec)
[========================>] 30000/28865 rows (103.9%) Table bmsql_customer (3 sec., 10000 recs/sec)
[========================>] 10/10 rows (100.0%) Table bmsql_district (0 sec., 10 recs/sec)
[========================>] 30218/30070 rows (100.5%) Table bmsql_history (1 sec., 30218 recs/sec)
[========================>] 100000/99444 rows (100.6%) Table bmsql_item (2 sec., 50000 recs/sec)
[=======================> ] 8992/9000 rows (99.9%) Table bmsql_new_order (0 sec., 8992 recs/sec)
[========================>] 30202/30195 rows (100.0%) Table bmsql_oorder (1 sec., 30202 recs/sec)
[========================>] 300831/297408 rows (101.2%) Table bmsql_order_line (13 sec., 23140 recs/sec)
[========================>] 100000/97506 rows (102.6%) Table bmsql_stock (7 sec., 14285 recs/sec)
[========================>] 1/1 rows (100.0%) Table bmsql_warehouse (0 sec., 1 recs/sec)
[========================>] 1/1 rows (100.0%) Table t1 (0 sec., 1 recs/sec)
[========================>] 600259/592504 rows (101.3%) on total estimated data (27 sec., avg: 22231 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" > /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/mysql/ggserr.log
#查看源端增量同步进程日志