达梦数据实时同步软件 DMHS 是达梦公司推出的新一代支持异构环境的高性能、高可靠和高可扩展的数据库实时同步系统。该产品基于成熟的关系数据模型和标准接口,跨越多种软硬件平台实现秒级数据实时同步。该产品可广泛应用于应急系统、容灾备份、负载均衡、数据移植、联机维护、订阅分发和多业务中心等业务领域。本文档主要介绍如何完成ORACLE-ARC到DM主备数据库实时同步的部署,并对部署遇到的问题做解答。
环境如下:
Oracle端 | DM端 | |
IP | 公有IP:192.168.1.1/192.168.1.2 | 业务IP:192.168.2.1/192.168.2.2 |
数据库版本 | Oracel 11.2.0.4 | V7.6.1.92-Build(2021.02.26-135621)SEC |
DMHS软件版本 | V3.1.8-Build(2022.02.24-106302trunc)_D64 | V4.1.2-Build(2021.06.18-100195truncccc)_D64 |
系统版本 | CentOS 6.8 | 麒麟3.2-8 |
服务名 | racdb | mdb |
软件安装路径 | /opt/dmhs | /home/dmdba/dm/dmhs |
归档路径 | +DATA | |
数据库端口 | 1521 | 5236 |
管理模块监听端口 | 5345 | 5345 |
NET模块监听端口 | 5346 | 5346 |
一、ORACLE端配置(仅在一个计算节点配置)
1、配置环境变量
echo “export LD_LIBRARY_PATH=\$LIBPATH:\$ORACLE_HOME/lib” >> ~/.bash_profile |
2、配置ORACLE 网络服务名
2.1、添加配置到tnsname配置文件
cat $ORACLE_HOME/network/admin/tnsnames.ora racdb = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.1)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = racdb) ) ) ASM = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.1)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.2)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = +ASM) ) ) |
注意:IP尽量使用公有IP或VIP
2.2、验证
sqlplus system/oracle@racdb |
3、开启ORACLE归档
[oracle@rac1:racdb1]$ srvctl stop database -d racdb SQL> startup mount SQL> alter database archivelog; SQL> alter system set log_archive_dest_1='location=+DATA'; SQL>shutdown immediate [oracle@rac1:racdb1]$ srvctl start database -d racdb SYS@orcl>archive log list; Automatic archival Enabled --为开启 |
注意:配置完成后,需要配置归档,清理计划任务和脚本,确保数据库不会因空间不足导致运行异常。
4、Oracle同步开启全列附加日志
4.1、开启数据库最小附加日志
alter database add supplemental log data; SELECT supplemental_log_data_min min, MIN PK UI FK ALLC #MIN=YES,全列附加日志才会生效 |
4.2、如果是整库同步,需要打开数据库全列附加日志
alter database add supplemental log data (all) columns ; |
4.3、如果是单表同步,需要打开表级别全列附加日志
在Oracle端的dmhs.hs cpt中添加<supplement_log>1</supplement_log> 注释:supplement_log参数为表级附加日志参数,阈值1支持只开启表级的附加日志。 sqlplus / as sysdba SQL> alter table owner.table_name add supplemental log data(all,primary key,unique,foreign key) columns; 查看是否开启成功: |
注意
- 开启数据库全列附加日志过程中会锁表
- 开启表级全列附加日志,如果此表有排他锁,会报错ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
- 开启全列附加日志DML操作会产生更多的redo信息,需要关注归档空间,以防磁盘空间不足
5、设置源端/执行端ORACLE客户端字符集
当数据库数据包含中文字符时,需将DMHS运作所在窗口的NLS_LANG设置为对应的字符集,建议使用AMERICAN_AMERICA.ZHS16GBK。
windows平台设置客户端字符集: set NLS_LANG=AMERICAN_AMERICA.ZHS16GBK UNIX/LINUX平台设置客户端字符集: export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK |
6、建立DMHS同步用户并授权(数据同步用户需要有对表创建、删除的权限)
su - oracle sqlplus / as sysdba create user dmhs identified by dmhs; grant dba to dmhs; su - grid sqlplus / as sysasm SQL> create user dmhs identified by "dmhs"; SQL> grant dba to dmhs; |
7、源端 DDL 支持
7.1、源端数据库必须允许DDL触发器的触发动作
即数据库参数_system_trig_enabled为TRUE或者未设置。查看该参数的命令如下:
Select x.ksppinm name,y.ksppstvl value From |
7.2、在sys用户下执行脚本
脚本在/dmhs/scripts文件下
sqlplus / as sysdba @/opt/dmhs/scripts/ddl_sql_ora.sql 建议逐条手动执行,删除触发器注释并在尾部加 / ,确认编译是否成功,若失败数据库无法执行DDL操作,同步有影响。 |
8、安装ODBC
推荐安装odbc版本unixodbc2.3.2,下面介绍如何使用源码安装unixidbc。
- 下载unixodbc2.3.2源码unixODBC-2.3.2.tar.gz。
- 解压unixodbc源码
8.1、卸载老版本ODBC
[root@rac1 etc]# rpm -qa|grep -i odbc unixODBC-2.2.14-14.el6.x86_64 unixODBC-devel-2.2.14-14.el6.x86_64 [root@rac1 etc]# rpm -e unixODBC-devel-2.2.14-14.el6.x86_64 [root@rac1 etc]# rpm -e unixODBC-2.2.14-14.el6.x86_64 |
8.2、安装ODBC
yum install -y glibc glibc-devel glibc-headers glibc-common gcc tar -xzvf unixODBC-2.3.4.tar.gz 当服务器系统为 UNIX/LINUX 64bits 时,在./configure 之前需执行 export CFLAGS="-maix64 -DBUILD_REAL_64_BIT_MODE" ##服务器是64位CPU export OBJECT_MODE=64 ##设定cc编译环境为64位 ./configure --enable-drivers=no --with-iconv-char-enc=GB18030 --enable-gui=no --enable-iconv=yes make make install |
注意:
若编译报错:configure: error: C compiler cannot create executables
错误产生的原因其实很简单:由于我们在编译软件之前,进行了export操作,改变了CFLAGS和LIBS的值。将这个值清空就可以了。执行:
export LIBS=
export CFLAGS=
8.3、配置ODBC.INI
cat /usr/local/etc/odbc.ini [ORACLE] Description = ORACLE ODBC DSN Driver = Oracle in OraDb11g_home1 SERVER = 127.0.0.1 UID = dmhs PWD = dmhs Servername = RACDB PORT = 1521 |
8.4、配置odbcinst.ini
cat /usr/local/etc/odbcinst.ini [Oracle in OraDb11g_home1] Description = ODBC DRIVER FOR ORACLE Driver = /u01/app/oracle/product/11.2.0/db_1/lib/libsqora.so.11.1 Threading = 0 |
8.5、测试
isql -v ORACLE DMHS DMHS |
注意1:
[oracle@rac1:racdb1]$isql -v ORACLE DMHS DMHS
[01000][unixODBC][DriverManager]Can't open lib '/u01/app/oracle/product/11.2.0/db_1/lib/libsqora.so.11.1' : file not found
[ISQL]ERROR: Could not SQLConnect
问题是没有libodbcinst.so.1,解决方法是创建软连接:
Oracle用户测试
[oracle@rac1:racdb1]$ldd /u01/app/oracle/product/11.2.0/db_1/lib/libsqora.so.11.1
libodbcinst.so.1 => not found
[root@rac1 lib]# ln -s /usr/local/lib/libodbcinst.so /lib64/libodbcinst.so.1
9、Oracle端视情况关闭外键,触发器和JOB(防止因触发器导致数据混乱)
set pagesize 0 line 999 long 999 关闭用户外键: select 'alter table '|| owner||'.'||t.table_name||' disable constraint '|| t.constraint_name ||';' from dba_constraints t where t.constraint_type='R' and t.status='ENABLED' and owner in(‘用户1’,‘用户2’); 关闭用户触发器: Select 'alter Trigger '||Owner||'."'||Trigger_Name||'" disable;' From Dba_Triggers 关闭数据库JOB: alter system set job_queue_processes=0; |
二、配置DM端
1、修改DM7 Oracle兼容性
disql SYSDBA/SYSDBA sp_set_para_value(2,'COMPATIBLE_MODE',2); select para_name,para_value,para_type from v$dm_ini where para_name='COMPATIBLE_MODE'; |
2、设置归档标记和逻辑日志标记
在dm.ini中修改,重启后生效
RLOG_APPEND_LOGIC = 1 ##逻辑日志标记 ARCH_INI= 1 ##开启归档 |
三、DMHS部署
1、ORACLE端、DM端DMHS软件安装
2、 DMHS同步规则配置
2.1 ORACLE配置文件
<?xml version="1.0" encoding="GB2312"?> <dmhs> <base> <siteid>1</siteid> <mgr_port>5345</mgr_port> <chk_interval>2</chk_interval> <ckpt_interval>60</ckpt_interval> <lang>ch</lang> <version>2.0</version> </base>
<exec> <recv> <data_port>5346</data_port> </recv> <db_type>oracle11g</db_type> <db_server>racdb</db_server> <db_user>dmhs</db_user> <db_pwd>dmhs</db_pwd> <db_port>1521</db_port> <level>0</level> <exec_thr>32</exec_thr> <exec_sql>1024</exec_sql> <exec_trx>5000</exec_trx> <exec_rows>1000</exec_rows> <exec_policy>0</exec_policy> <toggle_case>0</toggle_case> <commit_policy>1</commit_policy> <enable_merge>1</enable_merge> <check_index>0</check_index> <enable_depended>0</enable_depended> <affect_row>0</affect_row> <seq_sync_mode>0</seq_sync_mode> </exec> <cpt> <db_type>oracle11g</db_type> <db_server>racdb</db_server> <db_user>dmhs</db_user> <db_pwd>dmhs</db_pwd> <idle_time>10</idle_time> <ddl_mask>OBJ:OP:REC</ddl_mask> <supplement_log>1</supplement_log> <arch> <clear_interval>600</clear_interval> <clear_flag>0</clear_flag> </arch> <rac> <rac_type>1</rac_type> <db_server>ASM</db_server> <db_user>dmhs</db_user> <db_pwd>dmhs</db_pwd> <nodes>2</nodes> <epoch>0</epoch> </rac> <send> <ip>192.168.2.1</ip> <mgr_port>5345</mgr_port> <data_port>5346</data_port> <trigger>1</trigger> <constraint>1</constraint> <level>0</level> <identity>1</identity> <net_turns>0</net_turns> <filter> <enable> <item>TEST.*</item> </enable> <disable> </disable> </filter> <map> </map> </send> </cpt> </dmhs> |
2.2 DM端配置文件
<?xml version="1.0" encoding="GB2312" standalone="no"?> <dmhs> <base> <lang>ch</lang> <mgr_port>5345</mgr_port> <chk_interval>3</chk_interval> <ckpt_interval>60</ckpt_interval> <siteid>2</siteid> <version>2.0</version> </base> <exec> <recv> <data_port>5346</data_port> </recv> <db_type>DM7</db_type> <db_server>mdb</db_server> <db_user>SYSDBA</db_user> <db_pwd>SYSDBA</db_pwd> <db_port>5236</db_port> <level>0</level> <exec_thr>32</exec_thr> <exec_sql>1024</exec_sql> <exec_trx>5000</exec_trx> <exec_rows>250</exec_rows> <check_index>0</check_index> <exec_policy>0</exec_policy> <commit_policy>1</commit_policy> <enable_merge>1</enable_merge> <affect_row>0</affect_row> <seq_sync_mode>0</seq_sync_mode> </exec> <cpt> <db_type>DM7</db_type> <db_server>192.168.2.1</db_server> <db_user>SYSDBA</db_user> <db_pwd>SYSDBA</db_pwd> <idle_time>10</idle_time> <ddl_mask>OBJ:OP:REC</ddl_mask> <arch> <clear_interval>600</clear_interval> <clear_flag>0</clear_flag> </arch> <send> <ip>192.168.1.1</ip> <mgr_port>5345</mgr_port> <data_port>5346</data_port> <trigger>0</trigger> <constraint>0</constraint> <level>0</level> <identity>1</identity> <net_turns>0</net_turns> <filter> <enable> <item>TEST.*</item> </enable> <disable> </disable> </filter> <map> </map> </send> </cpt> </dmhs> |
2.3 两端启动DMHS
/etc/init.d/DmhsServiceHSSERVER start |
四、数据装载
1、DM7、ORACLE开启exec
cd 到dmhs/bin路径下分别执行: ./dmhs_console connect start exec; |
2、 ORACLE端启动初始化数据
先在DM7端建好需要同步的TEST用户和模式
Oracle端: clear exec lsn 0 DM端: clear exec lsn 0 oracle端: copy 0 "sch.name='TEST'" CREATE|INSERT|INDEX|DICT|REG|LSN DM端: COPY 0 "sch.name='TEST'" DICT|LSN |
注意1:
(1)一定要观察日志中从获取的LSN号,如果获取异常,很可能会更改ORACLE端的数据(SND[INFO]: 分析模块2成功获取LSN:67452736 LFS:0 目的端REV[INFO]: 192.168.2.1:2站点获取当前执行模块中的最小LSN: 89067419等回显)
(2)一定要使用REG掩码,不然装载过去的数据会通过目标端的 CPT 捕获分析以后投递到源端的 EXEC 模块来入库。
注意2:
源端schema名字为小写,目标端提示找不到该模式处理:
添加参数:
<map> <item>test.*==TEST.*</item> </map> |
注意3:
DM7配置文件中<db_server>mdb</db_server>配置的是别名,确保/etc/dm_svc.conf里配置了mdb
cat /etc/dm_svc.conf TIME_ZONE=(480) LANGUAGE=(cn) char_chk=(0) direct=(n) dummy=(y) RW_SEPARATE=(1) RW_PERCENT=(80) LOGIN_MODE=(1) mdb=(192.168.2.1:5236,192.168.2.2:5236) |
五、相关配置文件附件
六、报错解决
6.1、ODBC编译报错
若编译报错:configure: error: C compiler cannot create executables
错误产生的原因其实很简单:由于我们在编译软件之前,进行了export操作,改变了CFLAGS和LIBS的值。将这个值清空就可以了。执行:
export LIBS= export CFLAGS= |
6.2、同步报错-1
ERR:[Oracle][ODBC][Ora]ORA-26947: Oracle GoldenGate replication is not enabled.
原因:是没有逻辑复制所需的所有补充日志记录的权限,需要在开启数据库允许REPLICATION的参数。
更改命令:
ALTER SYSTEM SET ENABLE_GOLDENGATE_REPLICATION = TRUE SCOPE=BOTH; |
注:ENABLE_GOLDENGATE_REPLICATION控制由RDBMS for Oracle GoldenGate提供的服务(捕获和应用服务)。将此值设置为 true 可启用 Oracle GoldenGate 使用的 RDBMS 服务。此参数主要控制支持新数据类型和操作的逻辑复制所需的补充日志记录。
6.3、同步报错-2
EXE[ERROR]: SITEID:0 SEQID:0 TRXID:0 LAST ROWID:NULL SQL_ERROR = SQL:begin dbms_xstream_gg.set_gg_session(); end; EXE[ERROR]: SITEID:0 SEQID:0 TRXID:0 STATE:HY000 CODE: 1031 ROWID:NULL ERR:[Oracle][ODBC][Ora]ORA-01031: insufficient privileges ORA-06512: at "SYS.DBMS_XSTREAM_GG_INTERNAL", line 94 ORA-06512: at "SYS.DBMS_XSTREAM_GG", line 93 ORA-06512: at "SYS.DBMS_XSTREAM_GG", line 124 ORA-06512: at line 1 |
需要将DM端dm.hs设置为:
<trigger>0</trigger> |
注:
trigger阈值为0或者1,0表示关闭禁用触发器,1表示开启禁用触发器。
该配置参数只针对下一级的 EXEC 模块数据库为 DM 系列时有效,所有oracle到DM7需要配置为0;constraint阈值为0或者1,0表示关闭禁用约束,1表示开启禁用约束。 该配置参数只针对下一级的 EXEC 模块数据库为 DM 系列才有效,所有oracle到DM7需要配置为0。
6.4 同步报错-3
CPT[ERROR]: 打开asm 日志文件失败file(+DATA/racdb/archivelog/2022_04_12/thread_1_seq_108.441.1101840279)
出现此报错,是因为Oracle 归档日志文件已经被删除,但数据库认为归档日志文件还在,需要手动进行清理,或者配置文件,如果Oracle本身找不到归档,可以
进入RMAN crosscheck archivelog all; delete expired archivelog all; |
- 注意事项
1、<seq_sync_mode>1</seq_sync_mode>开启后两边序列一直在变化无法做到过滤,导致进入死循环。
2、DM端必须不可以设置<trigger>1</trigger> <constraint>1</constraint>,否则Oracle端会报错。
4. 源端、目的段同时对同一张表进行数据更新操作,容易产生锁,违反约束,插入相同的数据还会不同步等问题。
5. DM7到ORACLE同步时,需要禁用ORACLE同步表的外键,否则在对外键引用表进行更新时,可能会引起执行端 ORACLE 数据库操作错误。
6. DM7到ORACLE同步时,需要禁用ORACLE同步表的触发器,否则会对触发器操作的表进行二次操作,导致同步结果错误。
7. DM7到ORACLE同步时,有些JOB会对同步表做操作,比如对主键列定时插入数据等,会导致同步报错。
8. copy要加上REG参数
9. 特别注意, COPY一定要观察日志中从获取的LSN号,如果获取异常,启动两边CPT很可能会更改生产库端的数据一定要出现类似获取LSN的日志 (SND[INFO]: 分析模块2成功获取LSN:67452736 LFS:0 目的端REV[INFO]: 192.168.2.1:2站点获取当前执行模块中的最小LSN: 89067419)
10.ORACLE端开启或创建不检测原来数据的违反约束的外键(使用novalidate参数建立违反外键约束的外键),DM端会报错,外键不会被创建或开启
11. DM端建立触发器,Oracle同步触发器后,处于开启状态
12. DM 到ORACLE 时,ORACLE外键触发器需要关闭,JOB查看是否会改变同步的表。
13. 检测双向COPY表,发现REG掩码失效,COPY到目标端的数据,被反向COPY回来,造成数据重复,所以只可以单向COPY
14.rac需要注意的参数:
<db_type>oracle11g</db_type> --数据库类型
<db_server>racdb</db_server> 填写tnsname网络服务名,或者IP:端口+服务名
<level>0</level> 配置为0,该参数配置在执行端,用于表示同步拓扑架构的级联等级,对于同步拓扑架构为单向或双向同步时,执行端配置该参数为0。
<rac> --Oracle rac 配置
<rac_type>1</rac_type> --数据库为rac
<db_server>ASM</db_server> --使用asm磁盘组
<db_user>dmhs</db_user>
<db_pwd>dmhs</db_pwd>
<nodes>2</nodes> --rac计算节点数量
<epoch>0</epoch> --由于 DM7 RAC 是多节点的,而 DMHS 则是单进程程序, DMHS 会同时收集 RAC各节点的运行日志,按照 LSN 把各节点的日志归类并排序后才能分析。 由于各个节点间产生的日志 LSN 存在重叠,不能完全依赖LSN 的顺序进行排序分析,所以需要配置一个间隔值用于确定当前的节点产生的连续 LSN 日志不需要等待其他节点产生日志,直接排序返回结果。当该参数配置为 0 时,表明禁用时间戳归类排序的功能,改由使用各节点日志流中的 SCN 对齐的方式进行排序。
</rac>