LightDB to Oracle 实时数据同步参考手册
1. 前言
LightDB to Oracle 数据同步工具是 LightDB 团队出品的从 LightDB 数据库向 Oracle 数据库实时同步数据的工具,该工具提供实时同步功能,不提供迁移现有数据的功能。
本文档的内容包括 LightDB to Oracle 数据同步工具(以下简称本工具)的功能说明、使用方法、配置方法。
2. 功能简介
本工具是基于 LightDB 的逻辑复制机制开发的数据同步工具,它由两部分组成,都已默认包含在 LightDB 中:
-
wal2sql 插件
-
ltdts_recvlogical 工具
wal2sql 是一个 LightDB 插件,它会捕获 WAL 日志中的变更,通过流复制协议(复制槽)向外输出; ltdts_recvlogical 通过流复制协议于 LightDB 对接,解析 wal2sql 输出的 Json ,转换为 SQL ,通过 Oracle OCI 接口写入到 Oracle 中。
受益于复制槽的机制,ltdts_recvlogical 工具能够在高可用环境中发生故障切换后继续使用。
3. 安装与配置
工具已经在 LightDB 中自带,无需额外安装。
但在使用同步功能之前,仍有一些必要的配置需要进行。
3.1. 配置数据库
需要在 $LTDATA/lightdb.conf
中增加以下配置:
wal_level=logical
这项配置需要重启 LightDB 数据库,重启 LightDB 数据库的方法可参考 LightDB数据库运维手册 。
请注意,如果您使用了高可用环境,则主备库所有数据库都要进行这项配置。
3.2. 创建复制槽
当您准备使用同步工具时,需要先创建复制槽。
小心
请注意,一旦创建了复制槽,在创建这个时间点后面的所有变更全部会累积到复制槽中;若没有及时启动 ltdts_recvlogical 程序进行消费,可能会导致 WAL 日志变得越来越大,直到达到 max_wal_size 或 max_slot_wal_keep_size 中较小值的尺寸。
创建复制槽的方法:
export PGPASSWORD=lightdb123
ltdts_recvlogical --create-slot --slot=demo_slot -d demodb -h 10.0.200.3 -p 5432 -T oracle -U lightdb
命令行参数不支持设置 LightDB 密码,必须设置环境变量。
如果想要删除槽,可以这样调用:
export PGPASSWORD=lightdb123
ltdts_recvlogical --drop-slot --slot=demo_slot -d demodb -h 10.0.200.3 -p 5432 -T oracle -U lightdb
当槽正常创建后,可以启动 ltdts_recvlogical 同步。
3.3. 高可用环境配置
如果您在高可用环境使用同步工具,需要在主库执行:
ltdts_logicalrepl_copier.sh start
这样主库会每隔一段时间将槽复制到备库中。
4. 启动
建议将启动参数放入 shell 文件中进行保存,并且使用 nohup 后台运行,方便后续启动。
export NLS_LANG="AMERICAN_AMERICA.AL32UTF8"
export SLOT_NAME=demo_slot
export ORACLE_URL=10.0.200.3:1521/orcl
export ORACLE_USERNAME=system
export ORACLE_PASSWORD=oracle
export LIGHTDB_HOST=10.0.200.3
export LIGHTDB_PORT=5432
export LIGHTDB_USERNAME=lightdb
export LIGHTDB_DATABASE=demodb
export PGPASSWORD=lightdb123
nohup ltdts_recvlogical --start --tnsname=$ORACLE_URL --oracle-username=$ORACLE_USERNAME --oracle-password=$ORACLE_PASSWORD \
--slot=$SLOT_NAME -o write-in-chunks=true -o include-types=false -o include-type-oids=true \
-d $LIGHTDB_DATABASE -h $LIGHTDB_HOST -p $LIGHTDB_PORT -T oracle -f debug-null -U $LIGHTDB_USERNAME \
--ignore-not-found --ignore-duplicate >> output.log 2>&1 &
小心
注意环境变量 NLS_LANG 非常重要,否则当 Oracle 使用的编码与 LightDB 不同时,可能导致乱码!
NLS_LANG 配置的值应当与 LightDB 的编码保持一致,一般为 "AMERICAN_AMERICA.AL32UTF8"。
启动后需要查看 output.log 中有无报错,如果启动日志类似下面的表示,则为成功。
start to sync message to oracle
ltdts_recvlogical: starting log streaming at 0/0 (slot demo_slot)
ltdts_recvlogical: streaming initiated
ltdts_recvlogical: 24-01-31 15:05:17: confirming write up to 0/0, flush to 0/0 (slot demo_slot)
5. 功能详细说明
5.1. 命令行参数说明
ltdts_recvlogical 程序支持的配置参数如下:
参数 |
是否必填 |
示例配置 |
参数说明 |
---|---|---|---|
--help |
--help |
打印帮助信息 |
|
--start |
--start |
启动同步,必须指定 oracle 与 lightdb 连接信息 |
|
--create-slot |
--create-slot |
创建槽,需要指定 lightdb 连接信息 |
|
--drop-slot |
--drop-slot |
删除槽,需要指定 lightdb 连接信息 |
|
--tnsname |
10.0.200.3:1521/orcl |
Oracle 连接信息 |
|
--oracle-username |
system |
Oracle 用户名 |
|
--oracle-password |
oracle |
Oracle 密码 |
|
--slot |
是 |
demo_slot |
槽名称 |
-d |
是 |
demodb |
LightDB 库名 |
-h |
是 |
10.0.200.3 |
LightDB 地址 |
-p |
是 |
5432 |
LightDB 端口 |
-T |
是 |
oracle |
同步目标,目前仅支持 oracle |
-U |
是 |
lightdb |
LightDB 用户名 |
-f
|
是
|
-f debug.dat
|
写入文件名。当文件名为 debug.dat 时,会向 debug.dat 写入收到的 json;其他文件名无效。
需注意此文件尺寸很大,生产环境不要配置为 debug.dat 。
|
-o
|
是
|
-o write-in-chunks=true
-o include-types=false
-o include-type-oids=true
|
额外配置项,必须配置这两项:
-o include-types=false
-o include-type-oids=true
若您的环境中存在很大的事务,导致同步工具报错 out of memory ,则可增加以下参数:
-o write-in-chunks=true:
|
--ignore-duplicate |
是 |
--ignore-duplicate |
忽略执行插入时发生的主键冲突报错 |
--ignore-not-found |
是 |
--ignore-not-found |
忽略执行更新或删除时更新 0 条的报错 |
6. 注意事项
6.1. max_slot_wal_keep_size 参数配置
要稳定使用同步功能,一定要注意配置 max_wal_size 与 max_slot_wal_keep_size 这两个参数,它们对同步工具 非常重要。
槽中能够保留的未同步数据的情况包括:
-
当 max_slot_wal_keep_size 为 -1 时,取 max_slot_size
-
当 max_slot_wal_keep_size 不为 -1 时,取 max_slot_size 与 max_slot_wal_keep_size 的最小值
若 WAL 日志量超过了保留限制,会引起 槽失效 ,此时若要继续使用实时同步,一般需要以下步骤:
-
删除槽
-
重新进行全量数据迁移,从 LightDB 到 Oracle
-
重建槽
-
开启同步工具
若您的系统会进行批处理,会涉及如百万条或更多数据的批量更新,建议增大 max_slot_wal_keep_size 和 max_wal_size ,避免槽失效。
若要确定这个数字的大小,可以创建槽之后,执行一些批量处理事务,然后用一下 SQL 查询已落后的大小:
SELECT
slot_name,
plugin,
slot_type,
database,
active,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS lag_bytes,
safe_wal_size
FROM
pg_replication_slots;
其中 lag_bytes 就是当前批处理事务写入的 wal 日志大小,可根据此数据来预估生产环境所需的 max_slot_wal_keep_size 和 max_wal_size 尺寸,当然上线前请一定在测试环境对同步工具进行充分的压力测试,以确保它能够满足需求而不会失效。
6.2. debug.dat 注意事项
此文件会记录同步程序从 LightDB 到二进制程序的协议内容,它的尺寸与表结构相关,会非常巨大,建议不要开启,即使是测试环境也不要开启。
使用前面“启动”章节中的命令,配置 -f debug-null
即可不写入 debug.dat 。
7. 常用维护手段
7.1. 查看槽的状态
在 pg_replication_slots 视图中可以获取槽的状态,可这样查询:
SELECT
slot_name,
plugin,
slot_type,
database,
active,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS lag_bytes,
safe_wal_size
FROM
pg_replication_slots;
其中 lag_bytes 和 safe_wal_size 这两个字段可以用作监控,当 lag_bytes 大于 2GB 时,说明已有较多延迟 ,可告警;当 safe_wal_size 小于 10G 时可告警,说明 LightDB 再写 10GB 的 wal 日志后,这个槽就可能失效了。
槽失效是较难处理的情况,无法继续增量同步,必须将槽删除,通过其他方式进行全量同步后重新创建槽。
7.2. 创建槽/删除槽
创建复制槽的方法:
export PGPASSWORD=lightdb123
ltdts_recvlogical --create-slot --slot=demo_slot -d demodb -h 10.0.200.3 -p 5432 -T oracle -U lightdb
命令行参数不支持设置 LightDB 密码,必须设置环境变量。
删除复制槽的方法:
export PGPASSWORD=lightdb123
ltdts_recvlogical --drop-slot --slot=demo_slot -d demodb -h 10.0.200.3 -p 5432 -T oracle -U lightdb
8. 常见问题
8.1. 槽不存在
启动日志中会出现:
ltdts_recvlogical: error: could not send replication command "START_REPLICATION SLOT "demo_slot" LOGICAL 0/0 ("include-types" 'false', "include-type-oids" 'true', "write-in-chunks" 'true')": ERROR: replication slot "hsfut_slot1" does not exist
需要确认是否已经创建了槽,需要确认 --slot 参数。
8.2. 槽已失效
ltdts_recvlogical: error: could not send replication command "START_REPLICATION SLOT "hsfut_slot" LOGICAL 0/0 ("include-types" 'false', "include-type-oids" 'true', "write-in-chunks" 'true')": ERROR: cannot read from logical replication slot "hsfut_slot"
DETAIL: This slot has been invalidated because it exceeded the maximum reserved size.
出现这个日志说明槽已经失效了,必须重新进行数据全量同步,删除槽,再重新创建槽。
要避免这种情况的发生,需要做好对 pg_replication_slots 视图的监控。
8.3. Oracle 表不存在
在同步期间可能遇到以下报错出现在同步程序的输出中:
Error - ORA-00942: table or view does not exist
execute sql failed, sql: insert into hys_sys.b( id ) values(:1)
values:1
说明 Oracle 中不存在 hys_sys.b 这个表,这个报错会阻塞同步,一定要确保两边表结构一致。
8.4. 中文同步后变成问号
需要注意启动 ltdts_recvlogical 时没有正确配置 NLS_LANG 环境变量。需要在启动前进行设置:
export NLS_LANG="AMERICAN_AMERICA.AL32UTF8"
这个 NLS_LANG 应当与 lightdb 数据库使用的编码保持一致。如果您使用了 GBK 版本的 LightDB,则应当配置为 SIMPLIFIED CHINESE_CHINA.ZHS16GBK 。