DM7数据复制之数据库级复制

DM 的数据复制可以在表级,模式级和库级进行配置,表级复制因为不能同步DDL,所以必须要求主从段表的结构必须完全一致。 本篇我们看下数据库级数据复制的配置过程。
下面举一个简单的例子来说明数据复制的配置。
1. 准备工作
参与复制的复制实例的信息如下表所示。
数据库 实例名 IP地址 数据库端口号 MAL端口号 文件目录
复制数据库 jydm 10.10.10.180 5236 5241 /dm_home/dmdba/dmdbms/data/
主数据库 hy 10.10.10.184 5236 5242 /dm_home/dmdba/dmdbms/data/
从数据库 wy 10.10.10.185 5236 5243 /dm_home/dmdba/dmdbms/data/

假设主数据库上存在hy用户,从数据库上存在wy用户,现需要创建一个主数据库上的hy用户到从数据库上wy用户的同步复制关系,其名称为REPHY2WY。

2. 参数设置
修改3台DM数据库的dm.ini 文件,添加如下内容:
数据库 dm.ini 设置
复制数据库 INSTANCE_NAME = jydm
PORT_NUM = 5236
MAL_INI = 1
主数据库 INSTANCE_NAME = hy
PORT_NUM = 5236
MAL_INI = 1
从数据库 INSTANCE_NAME = wy
PORT_NUM = 5236
MAL_INI = 1

配置dmmal.ini 文件
修改dmmal.ini文件,添加如下内容。Dmmal 配置文件默认没有,可以从示例目录下复制过来修改。

[root@shard1 ini_script]# pwd
/dm_home/dmdba/dmdbms/samples/ini_script
[root@shard1 ini_script]# ls -lrt
总用量 48
-rwxr-xr-x 1 dmdba dinstall  890 2月  14 2019 dmarch_example.ini
-rwxr-xr-x 1 dmdba dinstall 1966 2月  14 2019 dmdcr_cfg_example.ini
-rwxr-xr-x 1 dmdba dinstall  631 2月  14 2019 dmdcr_example.ini
-rwxr-xr-x 1 dmdba dinstall 1537 2月  14 2019 dminit_example.ini
-rwxr-xr-x 1 dmdba dinstall 2070 2月  14 2019 dmmal_example.ini
-rwxr-xr-x 1 dmdba dinstall 1277 2月  14 2019 dmmonitor_example.ini
-rwxr-xr-x 1 dmdba dinstall  288 2月  14 2019 dmmpp_example.ini
-rwxr-xr-x 1 dmdba dinstall 1679 2月  14 2019 dmtimer_example.ini
-rwxr-xr-x 1 dmdba dinstall 1241 2月  14 2019 dmwatch_example.ini
-rwxr-xr-x 1 dmdba dinstall 2146 2月  14 2019 dmwatcher_example.ini
-rwxr-xr-x 1 dmdba dinstall  522 2月  14 2019 dmwmon_example.ini
-rwxr-xr-x 1 dmdba dinstall  636 2月  14 2019 sqllog_example.ini

在每个数据库服务器上创建一个dmmal.ini文件,每个dmmal.ini 配置必须一致:

MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

[dmdba@shard1 jydm]$ cat dmmal.ini
MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

[dmdba@jydm2 hy]$ cat dmmal.ini
MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

[dmdba@jydm3 wy]$ cat dmmal.ini
MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

对3个数据库都要启用mal_ini参数

SQL> sp_set_para_value(2,'MAL_INI',1);
DMSQL executed successfully
used time: 7.465(ms). Execute id is 23.

复制数据库初始化
如果是第一次使用复制数据库,需要对复制数据库执行初始化操作。通过执行系统函数SP_INIT_REP_SYS(create_flag)来初始化复制数据库。其主要作用是创建复制用户(SYSREP/SYSREP)和创建复制数据库上需要的系统表。SP_INIT_REP_SYS 的参数create_flag为1时表示创建用户和系统表,为0时表示删除用户和系统表。

开始初始化:

SQL> SP_INIT_REP_SYS(1);
DMSQL executed successfully
used time: 115.960(ms). Execute id is 30.
SQL> conn SYSREP/SYSREP

Server[LOCALHOST:5236]:mode is normal, state is open
login used time: 9.684(ms)
SQL> select table_name from user_tables;

LINEID     TABLE_NAME       
---------- -----------------
1          RPS_GROUPS
2          RPS_INSTANCES
3          RPS_REPLICATIONS
4          RPS_TABMAPS
5          RPS_FAULT_HISTORY
6          RPS_CONFLICTS
7          RPS_TIMERS

7 rows got

used time: 170.443(ms). Execute id is 31.

创建的7张复制系统表如下:
1) 复制组表
CREATE TABLE SYSREP.RPS_GROUPS (
NAME VARCHAR(128), // 复制组名
ID INT, // 复制组ID
DESC$ VARCHAR(1000), // 描述
CLUSTER PRIMARY (NAME)
);
2) 复制节点实例表
CREATE TABLE SYSREP.RPS_INSTANCES(
INST_NAME VARCHAR(128), // 复制节点实例名
GRP_ID INT, // 复制组ID
INST_ID INT, // 实例在复制组中编号
FAULT_TIMEOUT INT, // 故障超时处理值,以秒为单位,0为立即超时
VALID_FLAG CHAR(1), // 节点系统状态
FAULT_TIME DATETIME, // 节点故障开始时间
NET_VALID_FLAG CHAR(1), // 网络状态
NET_FAULT_TIME DATETIME, // 网络故障开始时间
CLUSTER PRIMAY KEY(GRP_ID, INST_NAME)
);
3) 复制关系表
CREATE TABLE SYSREP.RPS_REPLICATIONS(
REP_NAME VARCHAR(128), // 复制名
GRP_ID INT, // 复制组ID
REP_ID INT, // 复制ID,全局唯一
MINST_ID INT, // 主节点实例编号
SINST_ID INT, // 从节点实例编号
ARCH_DIR VARCHAR(256), // 主节点归档日志路径
FAULT_TIMEOUT INT, // 故障超时处理值,以秒为单位,0为立即超时
VALID_FLAG CHAR(1), // 复制关系状态
FAULT_TIME DATETIME, // 故障开始时间
SYNC_FLAG INTEGER //指定同步或异步复制
TIMER_NAME VARCHAR(128) //指定异步复制的定时器(同步复制没有此项)
DESC$ VARCHAR(1000), // 复制描述
CLUSTER PRIMARY KEY(GRP_ID, REP_NAME)
);
4) 复制映射表
CREATE TABLE SYSREP.RPS_TABMAPS(
REP_ID INT, //复制ID
MSCH_NAME VARCHAR(128), //主表模式名
MTAB_NAME VARCHAR(128), //主表名
MSCH_ID INT, //主表模式ID
MTAB_ID INT, //主表ID
SSCH_NAME VARCHAR(128), //从表模式名
STAB_NAME VARCHAR(128), //从表名
SSCH_ID INT, //从表模式ID
STAB_ID INT, //从表ID
READONLY_MODE INT, //映射模式1:只读模式,0:非只读模式
CLUSTER PRIMARY KEY(REP_ID, MTAB_ID, STAB_ID)
);
5) 复制故障历史表
CREATE TABLE SYSREP.REP_FAULT_HISTORY(
GRP_NAME VARCHAR(128), // 复制组
OBJ_NAME VARCHAR(128), // 故障节点或关系
FAULT_TYPE VARCHAR(128), // 故障类型描述
START_TIME DATETIME, // 故障开始时间
END_TIME DATETIME // 故障结束时间
);
6) 复制冲突历史表
CREATE TABLE SYSREP.RPS_CONFLICTS
(
SEQ_NO BIGINT // 冲突序号
REP_ID INT, // 对应复制号
INST_ID INT, // 产生冲突的节点编号
TABLE_ID INT, // 冲突表ID
TYPE TINYINT // 操作类型
OCC_TIME DATETIME, // 冲突产生时间
KEY_DATA VARCHAR(8000), // 冲突数据的PK值,如包含多个KEY值,则以逗号分隔。如键值超长则截断
);
7) 复制定时器表
CREATE TABLE SYSREP.RPS_TIMERS (
NAME VARCHAR(128), // 定时器名称
TYPE$ INT, // 定时类型,取值可参见SP_RPS_CREATE_TIMER
FERQ_INTERVAL INT, // 间隔天数
FREQ_SUB_INTERVAL INT, // 间隔的月/周(调度类型决定)数
FREQ_MINUTE_INTERVAL INT, // 间隔的分钟数
START_TIME TIME, // 开始时间
END_TIME TIME, // 结束时间
DURING_START_DATE DATETIME // 开始时间点
DURING_END_DATE DATETIME, // 结束时间点
NO_END_DATA_FLAG INTEGER //是否有结束日期(0:有结束日期;1:没有结束日期)
DESC$ VARCHAR(1000), // 定时器描述
CLUSTER PRIMARY KEY(REP_NAME)
);
配置模式级复制

启动3台服务器,启动的顺序不分先后。

[root@shard1 jydm]# systemctl stop DmServicejydm.service
[root@shard1 jydm]# systemctl start DmServicejydm.service

[root@jydm2 ~]# systemctl stop DmServicehy.service
[root@jydm2 ~]# systemctl start DmServicehy.service

[root@jydm3 ~]# systemctl stop DmServicewy.service
[root@jydm3 ~]# systemctl start DmServicewy.service

登录复制数据库(RPS jydm),保证服务器状态为OPEN,开始复制配置。

[dmdba@shard1 bin]$ ./disql sysdba/abcd

Server[LOCALHOST:5236]:mode is normal, state is open
login used time: 9.851(ms)
disql V7.1.6.46-Build(2018.02.08-89107)ENT 
Connected to: DM 7.1.6.46

创建复制组REP_GRP_hy2wy

SQL> SP_RPS_ADD_GROUP('REP_GRP_hy2wy', '主从同步复制');
DMSQL executed successfully
used time: 32.545(ms). Execute id is 26.
SQL> select * from SYSREP.RPS_GROUPS;

LINEID     NAME          ID          DESC$       
---------- ------------- ----------- ------------
1          REP_GRP_hy2wy 3           主从同步复制

used time: 1.073(ms). Execute id is 27.

开始设置

SQL> SP_RPS_SET_BEGIN('REP_GRP_hy2wy');
DMSQL executed successfully
used time: 0.530(ms). Execute id is 57.

添加复制关系

SQL> SP_RPS_ADD_REPLICATION ('REP_GRP_hy2wy', 'REPhy2wy', 'hy到wy的同步复制', 'hy', 'wy', NULL, '/dm_home/dmdba/dmdbms/dmreplog');
DMSQL executed successfully
used time: 2.529(ms). Execute id is 29.

添加数据库级复制

SQL> SP_RPS_ADD_DB_MAP('REPhy2wy', 0);
DMSQL executed successfully
used time: 0.597(ms). Execute id is 30.

提交设置

SQL> SP_RPS_SET_APPLY();
DMSQL executed successfully
used time: 00:00:05.035. Execute id is 31.

SQL>  select * from SYSREP.RPS_REPLICATIONS;

LINEID     REP_NAME GRP_ID      REP_ID      MINST_ID    SINST_ID    ARCH_DIR                       FAULT_TIMEOUT VALID_FLAG  FAULT_TIME                  SYNC_FLAG   TIMER_NAME DESC$           
---------- -------- ----------- ----------- ----------- ----------- ------------------------------ ------------- ----------- --------------------------- ----------- ---------- ----------------
1          REPhy2wy 3           4           7           8           /dm_home/dmdba/dmdbms/dmreplog -1            0           NULL                        1           NULL       hy到wy的同步复制

used time: 1.277(ms). Execute id is 32.
SQL> select * from SYSREP.RPS_INSTANCES;

LINEID     INST_NAME GRP_ID      INST_ID     FAULT_TIMEOUT VALID_FLAG  FAULT_TIME                  NET_VALID_FLAG NET_FAULT_TIME             
---------- --------- ----------- ----------- ------------- ----------- --------------------------- -------------- ---------------------------
1          hy        3           7           -1            0           NULL                        0              NULL
2          wy        3           8           -1            0           NULL                        0              NULL

used time: 1.014(ms). Execute id is 33.
SQL> select * from SYSREP.RPS_TABMAPS;

LINEID     REP_ID      MSCH_NAME MTAB_NAME MSCH_ID     MTAB_ID     SSCH_NAME STAB_NAME SSCH_ID     STAB_ID     READONLY_MODE
---------- ----------- --------- --------- ----------- ----------- --------- --------- ----------- ----------- -------------
1          4           NULL      NULL      -1          -1          NULL      NULL      -1          -1          0

used time: 1.129(ms). Execute id is 34.

至此,数据库级复制配置完成。注意一点,DM的复制配置必须在开始复制配置之前执行SP_RPS_SET_BEGIN,配置完成之后执行SP_RPS_SET_APPLY提交。

验证同步
在主库上的hy用户下创建一个测试表t4

SQL> create table t4 as select * from sysobjects;
executed successfully
used time: 12.280(ms). Execute id is 12.
SQL> select count(*) from t4;

LINEID     COUNT(*)            
---------- --------------------
1          1480

used time: 1.256(ms). Execute id is 13.

在从库上的wy用户查询这个表t4

SQL> select count(*) from t4;
select count(*) from t4;
[-2106]:Error in line: 1
Invalid table or view name [T4].
used time: 0.423(ms). Execute id is 0.

可以看到创建表的DDL语句没有同步到wy用户下。

在主库上创建用户jy

SQL> create user jy identified by "abcd";
executed successfully
used time: 4.940(ms). Execute id is 5.
SQL> grant dba,resource to jy;
executed successfully
used time: 2.929(ms). Execute id is 6.

在从库上登录用户jy

[dmdba@jydm3 bin]$ ./disql jy/abcd
[-70028]:Create SOCKET connection failure.
disql V7.1.6.46-Build(2018.02.08-89107)ENT 
username:

从从库上的日志可以看到故障信息

2019-12-20 00:15:08 [WARNING] database P0000029732 main_thread  rps sys init failed, code:-8748

从复制数据库上查看复制故障信息

SQL> select * from SYSREP.RPS_FAULT_HISTORY;

LINEID     GRP_NAME      OBJ_NAME FAULT_TYPE         START_TIME                  END_TIME                   
---------- ------------- -------- ------------------ --------------------------- ---------------------------
1          REP_GRP_hy2wy REPhy2wy REPLICATION FAULT  2019-12-20 00:14:23.366210  2019-12-20 00:15:24.042032
2          REP_GRP_hy2wy wy       INSTANCE SYS FAULT 2019-12-20 00:14:23.366210  2019-12-20 00:15:24.042032
3          REP_GRP_hy2wy REPhy2wy REPLICATION FAULT  2019-12-20 00:16:23.386842  NULL
4          REP_GRP_hy2wy wy       INSTANCE SYS FAULT 2019-12-20 00:16:23.386842  NULL

used time: 1.179(ms). Execute id is 4.

从测试结果可以看到数据库级的数据复制不支持DDL,数据库的数据复制对创建用户的操作处理异常,会导致从库奔溃。

DM7数据复制之模式级复制

DM 的数据复制可以在表级,模式级和库级进行配置,表级复制因为不能同步DDL,所以必须要求主从段表的结构必须完全一致。 本篇我们看下模式级数据复制的配置过程。
下面举一个简单的例子来说明数据复制的配置。
1. 准备工作
参与复制的复制实例的信息如下表所示。
数据库 实例名 IP地址 数据库端口号 MAL端口号 文件目录
复制数据库 jydm 10.10.10.180 5236 5241 /dm_home/dmdba/dmdbms/data/
主数据库 hy 10.10.10.184 5236 5242 /dm_home/dmdba/dmdbms/data/
从数据库 wy 10.10.10.185 5236 5243 /dm_home/dmdba/dmdbms/data/

假设主数据库上存在hy用户,从数据库上存在wy用户,现需要创建一个主数据库上的hy用户到从数据库上wy用户的同步复制关系,其名称为REPHY2WY。

2. 参数设置
修改3台DM数据库的dm.ini 文件,添加如下内容:
数据库 dm.ini 设置
复制数据库 INSTANCE_NAME = jydm
PORT_NUM = 5236
MAL_INI = 1
主数据库 INSTANCE_NAME = hy
PORT_NUM = 5236
MAL_INI = 1
从数据库 INSTANCE_NAME = wy
PORT_NUM = 5236
MAL_INI = 1

配置dmmal.ini 文件
修改dmmal.ini文件,添加如下内容。Dmmal 配置文件默认没有,可以从示例目录下复制过来修改。

[root@shard1 ini_script]# pwd
/dm_home/dmdba/dmdbms/samples/ini_script
[root@shard1 ini_script]# ls -lrt
总用量 48
-rwxr-xr-x 1 dmdba dinstall  890 2月  14 2019 dmarch_example.ini
-rwxr-xr-x 1 dmdba dinstall 1966 2月  14 2019 dmdcr_cfg_example.ini
-rwxr-xr-x 1 dmdba dinstall  631 2月  14 2019 dmdcr_example.ini
-rwxr-xr-x 1 dmdba dinstall 1537 2月  14 2019 dminit_example.ini
-rwxr-xr-x 1 dmdba dinstall 2070 2月  14 2019 dmmal_example.ini
-rwxr-xr-x 1 dmdba dinstall 1277 2月  14 2019 dmmonitor_example.ini
-rwxr-xr-x 1 dmdba dinstall  288 2月  14 2019 dmmpp_example.ini
-rwxr-xr-x 1 dmdba dinstall 1679 2月  14 2019 dmtimer_example.ini
-rwxr-xr-x 1 dmdba dinstall 1241 2月  14 2019 dmwatch_example.ini
-rwxr-xr-x 1 dmdba dinstall 2146 2月  14 2019 dmwatcher_example.ini
-rwxr-xr-x 1 dmdba dinstall  522 2月  14 2019 dmwmon_example.ini
-rwxr-xr-x 1 dmdba dinstall  636 2月  14 2019 sqllog_example.ini


在每个数据库服务器上创建一个dmmal.ini文件,每个dmmal.ini 配置必须一致:

MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

[dmdba@shard1 jydm]$ cat dmmal.ini
MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

[dmdba@jydm2 hy]$ cat dmmal.ini
MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

[dmdba@jydm3 wy]$ cat dmmal.ini
MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

对3个数据库都要启用mal_ini参数

SQL> sp_set_para_value(2,'MAL_INI',1);
DMSQL executed successfully
used time: 7.465(ms). Execute id is 23.

复制数据库初始化
如果是第一次使用复制数据库,需要对复制数据库执行初始化操作。通过执行系统函数SP_INIT_REP_SYS(create_flag)来初始化复制数据库。其主要作用是创建复制用户(SYSREP/SYSREP)和创建复制数据库上需要的系统表。SP_INIT_REP_SYS 的参数create_flag为1时表示创建用户和系统表,为0时表示删除用户和系统表。

开始初始化:

SQL> SP_INIT_REP_SYS(1);
DMSQL executed successfully
used time: 115.960(ms). Execute id is 30.
SQL> conn SYSREP/SYSREP

Server[LOCALHOST:5236]:mode is normal, state is open
login used time: 9.684(ms)
SQL> select table_name from user_tables;

LINEID     TABLE_NAME       
---------- -----------------
1          RPS_GROUPS
2          RPS_INSTANCES
3          RPS_REPLICATIONS
4          RPS_TABMAPS
5          RPS_FAULT_HISTORY
6          RPS_CONFLICTS
7          RPS_TIMERS

7 rows got

used time: 170.443(ms). Execute id is 31.

创建的7张复制系统表如下:
1) 复制组表
CREATE TABLE SYSREP.RPS_GROUPS (
NAME VARCHAR(128), // 复制组名
ID INT, // 复制组ID
DESC$ VARCHAR(1000), // 描述
CLUSTER PRIMARY (NAME)
);
2) 复制节点实例表
CREATE TABLE SYSREP.RPS_INSTANCES(
INST_NAME VARCHAR(128), // 复制节点实例名
GRP_ID INT, // 复制组ID
INST_ID INT, // 实例在复制组中编号
FAULT_TIMEOUT INT, // 故障超时处理值,以秒为单位,0为立即超时
VALID_FLAG CHAR(1), // 节点系统状态
FAULT_TIME DATETIME, // 节点故障开始时间
NET_VALID_FLAG CHAR(1), // 网络状态
NET_FAULT_TIME DATETIME, // 网络故障开始时间
CLUSTER PRIMAY KEY(GRP_ID, INST_NAME)
);
3) 复制关系表
CREATE TABLE SYSREP.RPS_REPLICATIONS(
REP_NAME VARCHAR(128), // 复制名
GRP_ID INT, // 复制组ID
REP_ID INT, // 复制ID,全局唯一
MINST_ID INT, // 主节点实例编号
SINST_ID INT, // 从节点实例编号
ARCH_DIR VARCHAR(256), // 主节点归档日志路径
FAULT_TIMEOUT INT, // 故障超时处理值,以秒为单位,0为立即超时
VALID_FLAG CHAR(1), // 复制关系状态
FAULT_TIME DATETIME, // 故障开始时间
SYNC_FLAG INTEGER //指定同步或异步复制
TIMER_NAME VARCHAR(128) //指定异步复制的定时器(同步复制没有此项)
DESC$ VARCHAR(1000), // 复制描述
CLUSTER PRIMARY KEY(GRP_ID, REP_NAME)
);
4) 复制映射表
CREATE TABLE SYSREP.RPS_TABMAPS(
REP_ID INT, //复制ID
MSCH_NAME VARCHAR(128), //主表模式名
MTAB_NAME VARCHAR(128), //主表名
MSCH_ID INT, //主表模式ID
MTAB_ID INT, //主表ID
SSCH_NAME VARCHAR(128), //从表模式名
STAB_NAME VARCHAR(128), //从表名
SSCH_ID INT, //从表模式ID
STAB_ID INT, //从表ID
READONLY_MODE INT, //映射模式1:只读模式,0:非只读模式
CLUSTER PRIMARY KEY(REP_ID, MTAB_ID, STAB_ID)
);
5) 复制故障历史表
CREATE TABLE SYSREP.REP_FAULT_HISTORY(
GRP_NAME VARCHAR(128), // 复制组
OBJ_NAME VARCHAR(128), // 故障节点或关系
FAULT_TYPE VARCHAR(128), // 故障类型描述
START_TIME DATETIME, // 故障开始时间
END_TIME DATETIME // 故障结束时间
);
6) 复制冲突历史表
CREATE TABLE SYSREP.RPS_CONFLICTS
(
SEQ_NO BIGINT // 冲突序号
REP_ID INT, // 对应复制号
INST_ID INT, // 产生冲突的节点编号
TABLE_ID INT, // 冲突表ID
TYPE TINYINT // 操作类型
OCC_TIME DATETIME, // 冲突产生时间
KEY_DATA VARCHAR(8000), // 冲突数据的PK值,如包含多个KEY值,则以逗号分隔。如键值超长则截断
);
7) 复制定时器表
CREATE TABLE SYSREP.RPS_TIMERS (
NAME VARCHAR(128), // 定时器名称
TYPE$ INT, // 定时类型,取值可参见SP_RPS_CREATE_TIMER
FERQ_INTERVAL INT, // 间隔天数
FREQ_SUB_INTERVAL INT, // 间隔的月/周(调度类型决定)数
FREQ_MINUTE_INTERVAL INT, // 间隔的分钟数
START_TIME TIME, // 开始时间
END_TIME TIME, // 结束时间
DURING_START_DATE DATETIME // 开始时间点
DURING_END_DATE DATETIME, // 结束时间点
NO_END_DATA_FLAG INTEGER //是否有结束日期(0:有结束日期;1:没有结束日期)
DESC$ VARCHAR(1000), // 定时器描述
CLUSTER PRIMARY KEY(REP_NAME)
);
配置模式级复制

启动3台服务器,启动的顺序不分先后。

[root@shard1 jydm]# systemctl stop DmServicejydm.service
[root@shard1 jydm]# systemctl start DmServicejydm.service

[root@jydm2 ~]# systemctl stop DmServicehy.service
[root@jydm2 ~]# systemctl start DmServicehy.service

[root@jydm3 ~]# systemctl stop DmServicewy.service
[root@jydm3 ~]# systemctl start DmServicewy.service

登录复制数据库(RPS jydm),保证服务器状态为OPEN,开始复制配置。

[dmdba@shard1 bin]$ ./disql sysdba/abcd

Server[LOCALHOST:5236]:mode is normal, state is open
login used time: 9.851(ms)
disql V7.1.6.46-Build(2018.02.08-89107)ENT 
Connected to: DM 7.1.6.46

创建复制组REP_GRP_hy2wy

SQL> SP_RPS_ADD_GROUP('REP_GRP_hy2wy', '主从同步复制');
DMSQL executed successfully
used time: 6.109(ms). Execute id is 55.

SQL> select * from SYSREP.RPS_GROUPS;

LINEID     NAME          ID          DESC$       
---------- ------------- ----------- ------------
1          REP_GRP_hy2wy 2           主从同步复制

used time: 1.182(ms). Execute id is 56.

开始设置

SQL> SP_RPS_SET_BEGIN('REP_GRP_hy2wy');
DMSQL executed successfully
used time: 0.530(ms). Execute id is 57.

添加复制关系

SQL> SP_RPS_ADD_REPLICATION ('REP_GRP_hy2wy', 'REPhy2wy', 'hy到wy的同步复制', 'hy', 'wy', NULL, '/dm_home/dmdba/dmdbms/dmreplog');
DMSQL executed successfully
used time: 2.623(ms). Execute id is 58.

添加模式级复制
添加复制映射, 注意这里用户名和表名要大写,否则会提示对象不存在

SQL> SP_RPS_ADD_SCH_MAP('REPhy2wy','hy','wy',0);
SP_RPS_ADD_SCH_MAP('REPhy2wy','hy','wy',0);
[-8713]:source table is not exists.
used time: 1.738(ms). Execute id is 0.

SQL> SP_RPS_ADD_SCH_MAP('REPhy2wy','HY','WY',0);
DMSQL executed successfully
used time: 3.126(ms). Execute id is 6.

提交设置

SQL> SP_RPS_SET_APPLY();
DMSQL executed successfully
used time: 00:00:05.041. Execute id is 7.
SQL>  select * from SYSREP.RPS_REPLICATIONS;

LINEID     REP_NAME GRP_ID      REP_ID      MINST_ID    SINST_ID    ARCH_DIR                       FAULT_TIMEOUT VALID_FLAG  FAULT_TIME                  SYNC_FLAG   TIMER_NAME DESC$           
---------- -------- ----------- ----------- ----------- ----------- ------------------------------ ------------- ----------- --------------------------- ----------- ---------- ----------------
1          REPhy2wy 2           3           5           6           /dm_home/dmdba/dmdbms/dmreplog -1            0           NULL                        1           NULL       hy到wy的同步复制

used time: 1.362(ms). Execute id is 8.
SQL> select * from SYSREP.RPS_INSTANCES;

LINEID     INST_NAME GRP_ID      INST_ID     FAULT_TIMEOUT VALID_FLAG  FAULT_TIME                  NET_VALID_FLAG NET_FAULT_TIME             
---------- --------- ----------- ----------- ------------- ----------- --------------------------- -------------- ---------------------------
1          hy        2           5           -1            0           NULL                        0              NULL
2          wy        2           6           -1            0           NULL                        0              NULL

used time: 0.981(ms). Execute id is 9.
SQL> select * from SYSREP.RPS_TABMAPS;

LINEID     REP_ID      MSCH_NAME MTAB_NAME MSCH_ID     MTAB_ID     SSCH_NAME STAB_NAME SSCH_ID     STAB_ID     READONLY_MODE
---------- ----------- --------- --------- ----------- ----------- --------- --------- ----------- ----------- -------------
1          3           HY        NULL      150995951   -1          WY        NULL      150995951   -1          0

used time: 1.178(ms). Execute id is 10.
SQL>

至此,模式级复制配置完成。注意一点,DM的复制配置必须在开始复制配置之前执行SP_RPS_SET_BEGIN,配置完成之后执行SP_RPS_SET_APPLY提交。

验证同步
先测试DML操作:在主库insert 数据:

SQL> insert into t1 values(1,'hy1');
affect rows 1

used time: 1.565(ms). Execute id is 6.
SQL> commit;
executed successfully
used time: 1.442(ms). Execute id is 7.
SQL> select * from t1;

LINEID     ID USERNAME
---------- -- --------
1          1  hy1

used time: 0.548(ms). Execute id is 8.

从库查询,同步成功:

SQL> select * from t1;

LINEID     ID USERNAME
---------- -- --------
1          1  hy1

used time: 2.538(ms). Execute id is 5.

在主库上的hy用户下创建一个测试表t2

SQL> create table t2 as select * from sysobjects;
executed successfully
used time: 12.763(ms). Execute id is 6.
SQL> select count(*) from t2;

LINEID     COUNT(*)            
---------- --------------------
1          1480

used time: 1.266(ms). Execute id is 7.

在从库上的wy用户查询这个表t2

SQL> select count(*) from t2;

LINEID     COUNT(*)            
---------- --------------------
1          1480

used time: 0.463(ms). Execute id is 8.

可以看到创建表的DDL语句已经同步到wy用户下。

因为我这里的复制从库是0级,就是非只读的,删除后重新添加1级,即只读模式在测试:

SQL> SP_RPS_SET_BEGIN('REP_GRP_hy2wy');
DMSQL executed successfully
used time: 0.408(ms). Execute id is 12.

SQL> SP_RPS_DROP_SCH_MAP('REPhy2wy','HY','WY');
DMSQL executed successfully
used time: 1.456(ms). Execute id is 13.

SQL> SP_RPS_ADD_SCH_MAP('REPhy2wy','HY','WY',1);
DMSQL executed successfully
used time: 2.820(ms). Execute id is 14.
SQL> SP_RPS_SET_APPLY();
DMSQL executed successfully
used time: 00:00:05.039. Execute id is 15.

再测试
从主库的hy用户中创建表t3

SQL> create table t3 as select * from sysobjects;
executed successfully
used time: 9.925(ms). Execute id is 9.
SQL> select count(*) from t3;

LINEID     COUNT(*)            
---------- --------------------
1          1480

used time: 0.861(ms). Execute id is 10.

在从库上的wy用户下查询表t3显示不存在

SQL> select count(*) from t3;
select count(*) from t3;
[-2106]:Error in line: 1
Invalid table or view name [T3].
used time: 0.774(ms). Execute id is 0.

从测试结果可以看到在只读模式下的模式级复制不能同步DDL操作。

DM7数据复制之表级复制

达梦数据复制(DATA REPLICATION)是一个分担系统访问压力、加快异地访问响应速度、提高数据可靠性的解决方案。将一个服务器实例上的数据变更复制到另外的服务器实例。可以用于解决大、中型应用中出现的因来自不同地域、不同部门、不同类型的数据访问请求导致数据库服务器超负荷运行、网络阻塞、远程用户的数据响应迟缓的问题。

重要概念
1. 数据库状态
服务器的状态,在不同的状态下,对能够进行的操作有不同的限制。详见数据守护部分。
2. 主服务器
发起复制操作的服务器,称为主服务器。
3. 从服务器
接收主服务器发送的数据并进行复制的服务器,称为从服务器。
4. 复制节点
涉及到复制的服务器,主服务和从服务的统称。一个节点既可以是主服务器也可以是从服务器。
5. 复制服务器(RPS)
在数据复制环境中,负责配置复制环境,定义复制关系的服务器。RPS有且仅有一台,它只负责配置和监控,并不参与到复制过程中。
6. 复制关系
复制关系指明主服务器和从服务器以何种方式进行复制。按照复制的方式,复制关系分为同步复制和异步复制。
7. 同步复制关系
主服务器数据更新立即复制到从服务器。
8. 异步复制关系
主服务器和从服务器在某段时间内数据可能是不同的,主服务器数据更新不会立刻同步到从服务器,而是在经过一段时间后才进行复制。异步复制的同步时机由指定的定时器确定。
9. 逻辑日志
记录产生数据变化的逻辑操作的日志。记录的逻辑操作包括INSERT、UPDATE、DELETE、TRUNCATE、ROLLBACK和COMMIT。
10. 复制源对象
主服务器上作为复制数据源的对象,可以是库、模式或表。在该对象上的操作都会被记录成逻辑日志,发送给从服务器进行复制操作。

11. 复制目标对象
从服务器上作为复制数据目标的对象。从服务器接收到逻辑日志后,将复制源对象的变化复制到复制目标对象中。

12. 复制对象映射
一对复制源对象和复制目标对象构成一个复制对象映射。构成映射的源对象和目标对象必须是同一类型的对象。根据对象的类型,复制映射分为库级、模式级和表级三个级别。其中表级要求源表和目标表结构完全一致,库级和模式级没有要求。库级和模式级复制映射会将其DDL也进行复制。复制映射包括只读模式和非只读模式。对于只读模式的映射,映射的目的表禁止用户更新。
13. 复制组
一组逻辑相关的复制关系可以构造成为复制组。通过复制组,可以构造出一对多复制、多对一复制、级联复制、对称复制、循环复制等复杂的逻辑复制环境。

体系构架
数据复制系统由以下部件构成:
1. 复制服务器;
2. 复制节点;
3. 各实例站点间通讯的MAL系统。

除了系统管理员通过复制服务器定义复制和处理异常外,其他部分的处理及主从服务器之间复制操作对于用户是透明的。整个复制环境的配置境况如下图所示。

在整个环境中有且仅有一台复制服务器(RPS),用户通过RPS定义复制及复制环境,但RPS并不参与到复制过程中。
DM7中,将复制逻辑日志按照配置归档到本站点指定目录称为本地归档,将日志的发送称为日志的远程归档。
复制节点上,与复制相关的配置文件有dmtimer.ini、dmllog.ini、dmrep.ini。各个配置文件在复制中的功能如下表所示

这些文件均是RPS依据用户配置通过MAL系统自动生成或修改的,管理员不需要手动进行管理。

在数据复制过程中,除了配置文件,其他的重要文件如下表。

这些文件都是流式文件,主服务器在执行过程中,逻辑日志先记录到逻辑日志文件中,并根据配置的信息,将逻辑日志分别分发归档到不同的逻辑日志归档文件中,并在恰当的时机将逻辑日志归档文件的内容发送给从服务器。

从服务器接收到一批数据就产生一个复制数据文件将数据存储其中,防止从服务器复制速度低导致复制数据的丢失。
逻辑日志文件大小限制为32M,两个文件交替使用。

归档路径内每个逻辑日志归档文件大小限制为32M,文件写满后增加新文件来存放新的记录。在dmllog.ini中有配置归档路径内所有文件总的空间限制,若达到限制的空间,则会删除之前的文件;若配置为无空间限制,则管理员可根据复制情况进行删除。

复制数据文件是从服务器一次接收的复制数据的临时文件,其大小不会超过32K;在其数据复制结束后会被自动删除。

配置数据复制在RPS上进行,与数据复制相关的过程如下:
1. SP_INIT_REP_SYS*
定义:
SP_INIT_REP_SYS(
CREATE_FLAG INT
);
功能说明:
创建或删除数据复制所需的系统表
参数说明:
CREATE_FLAG:为1表示创建复制所需系统表;为0表示删除这些系统表
返回值:

举例说明:
创建复制所需的系统表
SP_INIT_REP_SYS(1);

2. SP_RPS_ADD_GROUP
定义:
SP_RPS_ADD_GROUP(
GROUP_NAME VARCHAR(128),
GROUP_DESC VARCHAR(1000)
);
功能说明:
创建复制组
参数说明:
GROUP_NAME:创建的复制组名称
GROUP_DESC:复制组描述
返回值:

备注:
指示RPS创建一个新的复制组。如果已存在同名复制组则报错。
举例说明:
创建复制组REP_GRP_B2C
SP_RPS_ADD_GROUP(‘REP_GRP_B2C’,’主从同步复制’);

3. SP_RPS_DROP_GROUP
定义:
SP_RPS_DROP_GROUP(
GROUP_NAME VARCHAR(128)
);
功能说明:
删除复制组
参数说明:
GROUP_NAME:复制组名称
返回值:

举例说明:
删除复制组REP_GRP_B2C
SP_RPS_DROP_GROUP (‘REP_GRP_B2C’);

4. SP_RPS_ADD_REPLICATION
定义:
SP_RPS_ADD_REPLICATION(
GRP_NAME VARCHAR(128),
REP_NAME VARCHAR(128),
REP_DESC VARCHAR(1000),
MINSTANCE VARCHAR(128),
SINSTANCE VARCHAR(128),
REP_TIMER VARCHAR(128),
ARCH_PATH VARCHAR(256)
);
功能说明:
创建复制关系
参数说明:
GRP_NAME:复制组名
REP_NAME:复制名,必须在RPS上唯一
REP_DESC:复制描述
MINSTANCE:主节点实例名,必须在RPS的MAL中已配置
SINSTANCE:从节点实例名,必须在RPS的MAL中已配置
REP_TIMER:复制定时器名。借助定时器,可以设置复制数据的同步时机。如果是同步复制则为NULL
ARCH_PATH:主服务器上逻辑日志的完整归档路径。
返回值:

举例说明:
创建复制关系
SP_RPS_ADD_REPLICATION (‘REP_GRP_B2C’, ‘REPB2C’, ‘B到C的同步复制’, ‘B’, ‘C’, NULL, ‘{ DEFARCHPATH}\REPB2C’);

5. SP_RPS_DROP_REPLICATION
定义:
SP_RPS_DROP_REPLICATION (
REP_NAME VARCHAR(128)
);
功能说明:
删除复制关系
参数说明:
REP_NAME:复制名称
返回值:

举例说明:
删除复制关系
SP_RPS_DROP_REPLICATION (‘REPB2C’);

6. SP_RPS_SET_ROUTE_FAULT_TIMEOUT
定义:
SP_RPS_SET_ROUTE_FAULT_TIMEOUT (
REP_NAME VARCHAR(128),
TIMEOUTS INT
);
功能说明:
设置复制路径故障超时
参数说明:
REP_NAME:复制关系名。
TIMEOUTS:故障超时值,以秒为单位。0为立即超时;-1表示无超时限制返回值:

备注:
该接口用于设置复制路径故障处理策略。设置后,RPS如检测到复制路径产生故障,且故障持续超过设定的超时值后,则需要取消故障的复制关系。
举例说明:
设置复制路径故障超时
SP_RPS_SET_ROUTE_FAULT_TIMEOUT (‘REPB2C’,10);

7. SP_RPS_SET_INST_FAULT_TIMEOUT
定义:
SP_RPS_SET_INST_FAULT_TIMEOUT (
INST_NAME VARCHAR(128),
TIMEOUTS INT
);
功能说明:
设置复制节点故障超时
参数说明:
INST_NAME:复制节点实例名
TIMEOUTS:故障超时值,以秒为单位。0为立即超时;-1表示无超时限制
返回值:

举例说明:
设置复制节点故障超时
SP_RPS_SET_INST_FAULT_TIMEOUT (‘B’,10);

8. SP_RPS_ADD_TIMER
定义:
SP_RPS_ADD_TIMER(
TIMER_NAME VARCHAR(128),
TIMER_DESC VARCHAR(1000),
TYPE$ INT,
FERQ_INTERVAL INT,
FREQ_SUB_INTERVAL INT,
FREQ_MINUTE_INTERVAL INT,
START_TIME TIME,
END_TIME TIME,
DURING_START_DATE DATETIME,
DURING_END_DATE DATETIME,
NO_END_DATA_FLAG INT
);
功能说明:
设置复制关系的定时器
参数说明:
TIMER_NAME:定时器名
TIMER_DESC:定时器描述
TYPE$:定时器类型,取值如下:
1:执行一次
2:每日执行
3:每周执行
4:按月执行的第几天
5:按月执行的第一周
6:按月执行的第二周
7:按月执行的第三周
8:按月执行的第四周
9:按月执行的最后一周
FREQ_INTERVAL:间隔的月/周(调度类型决定)数
FREQ_SUB_INTERVAL: 间隔天数
FREQ_MINUTE_INTERVAL:间隔的分钟数
START_TIME:开始时间
END_TIME:结束时间
DURING_START_DATE:有效日期时间段的开始日期时间
DURING_END_DATE:有效日期时间段结束日期时间
NO_END_DATA_FLAG:结束日期是否无效标识,0表示结束日期有效,1表示无效
本过程的TYPE$、FERQ_INTERVAL、FREQ_SUB_INTERVAL、FREQ_MINUTE_INTERVAL、START_TIME、END_TIME、DURING_START_DATE、DURING_END_DATE和NO_END_DATA_FLAG分别与过程SP_ADD_TIMER的参数TYPE、FREQ_MONTH_WEEK_INTERVAL、FREQ_SUB_INTERVAL、FREQ_MINUTE_INTERVAL、START_TIME、END_TIME、DURING_START_DATE、DURING_END_DATE和NO_END_DATE_FLAG对应,其具体说明可参考过程SP_ADD_TIMER的说明。
返回值:

举例说明:
设置复制关系的定时器
SP_RPS_ADD_TIMER (‘TIMER1′,’按天计算’, 1, 1, 0, 1, CURTIME, ’23:59:59′, NOW, NULL, 1);

9. SP_RPS_REP_RESET_TIMER
定义:
SP_RPS_REP_RESET_TIMER(
REP_NAME VARCHAR(128),
TIMER_NAME VARCHAR(128)
);
功能说明:
重新设置复制关系的定时器
参数说明:
REP_NAME:复制名
TIMER_NAME:新的定时器名
返回值:

举例说明:
重新设置复制关系的定时器
SP_RPS_REP_RESET_TIMER (‘REPB2C’, ‘TIMER1’);

10. SP_RPS_ADD_TAB_MAP
定义:
SP_RPS_ADD_TAB_MAP(
REP_NAME VARCHAR(128),
MTAB_SCHEMA VARCHAR(128),
MTAB_NAME VARCHAR(128),
STAB_SCHEMA VARCHAR(128),
STAB_NAME VARCHAR(128),
READ_ONLY_MODE INT
);
功能说明:
添加表级复制映射
参数说明:
REP_NAME:复制关系名
MTAB_SCHEMA:主表模式名
MTAB_NAME:主表名
STAB_SCHEMA:从表模式名
STAB_NAME:从表名
READ_ONLY_MODE:只读复制模式,1表示只读模式,从表只接受复制更新,0表示非只读模式
返回值:

举例说明:
添加复制映射
SP_RPS_ADD_TAB_MAP(‘REPB2C’, ‘USER1’, ‘T1’, ‘USER2’, ‘T2’, 0);

11. SP_RPS_DROP_TAB_MAP
定义:
SP_RPS_DROP_TAB_MAP(
REP_NAME VARCHAR(128),
MTAB_SCHEMA VARCHAR(128),
MTAB_NAME VARCHAR(128),
STAB_SCHEMA VARCHAR(128),
STAB_NAME VARCHAR(128),
);
功能说明:
删除表级复制映射
参数说明:
REP_NAME:复制关系名
MTAB_SCHEMA:主表模式名
MTAB_NAME:主表名
STAB_SCHEMA:从表模式名
STAB_NAME:从表名
返回值:

举例说明:
删除表级复制映射
SP_RPS_DROP_TAB_MAP(‘REPB2C’, ‘USER1’, ‘T1’, ‘USER2’, ‘T2’);

12. SP_RPS_ADD_SCH_MAP
定义:
SP_RPS_ADD_SCH_MAP(
REP_NAME VARCHAR(128),
MSCH VARCHAR(128),
SSCH VARCHAR(128),
READ_ONLY_MODE INT
);
功能说明:
添加模式级复制映射
参数说明:
REP_NAME:复制关系名
MSCH:主模式名
SSCH: 从表模式名
READ_ONLY_MODE:只读复制模式,1表示只读模式,从表只接受复制更新,0表示非只读模式
返回值:

举例说明:
添加复制映射
SP_RPS_ADD_SCH_MAP(‘REPB2C’, ‘USER1’, ‘USER2’, 0);

13. SP_RPS_DROP_SCH_MAP
定义:
SP_RPS_DROP_SCH_MAP(
REP_NAME VARCHAR(128),
MSCH VARCHAR(128),
SSCH VARCHAR(128)
);
功能说明:
删除模式级复制映射
参数说明:
REP_NAME:复制关系名
MSCH:主模式名
SSCH:从模式名
返回值:

举例说明:
删除模式级复制映射
SP_RPS_DROP_SCH_MAP(‘REPB2C’, ‘USER1’, ‘USER2’);

14. SP_RPS_ADD_DB_MAP
定义:
SP_RPS_ADD_DB_MAP(
REP_NAME VARCHAR(128),
READ_ONLY_MODE INT
);
功能说明:
添加库级复制映射
参数说明:
REP_NAME:复制关系名
READ_ONLY_MODE:只读复制模式,1表示只读模式,从表只接受复制更新,0表示非只读模式
返回值:

举例说明:
添加库级复制映射
SP_RPS_ADD_DB_MAP(‘REPB2C’, 0);

15. SP_RPS_DROP_DB_MAP
定义:
SP_RPS_DROP_DB_MAP(
REP_NAME VARCHAR(128)
);
功能说明:
删除库级复制映射
参数说明:
REP_NAME:复制关系名
返回值:

举例说明:
删除库级复制映射
SP_RPS_DROP_DB_MAP(‘REPB2C’);

16. SP_RPS_SET_BEGIN
定义:
SP_RPS_SET_BEGIN(
GRP_NAME VARCHAR(128),
);
功能说明:
开始复制设置
参数说明:
GRP_NAME:复制组名
返回值:

备注:
开始对指定复制组进行属性设置。创建/删除复制关系与创建/删除复制映射等接口都必须在此接口调用后执行,否则会报错“错误的复制设置序列”。同一会话中也不能同时开始多个复制设置。
举例说明:
复制组REPB2C开始复制
SP_RPS_SET_BEGIN(‘ REP_GRP_B2C’);

17. SP_RPS_SET_APPLY
定义:
SP_RPS_SET_APPLY ();
功能说明:
提交复制设置,保存并提交本次设置的所有操作。如果需要继续设置,则必须重新调用SP_RPS_SET_BEGIN
参数说明:

返回值:

举例说明:
提交复制设置
SP_RPS_SET_APPLY ();
18. SP_RPS_SET_CANCEL
定义:
SP_RPS_SET_CANCEL ();
功能说明:
放弃复制设置,放弃本次设置的所有操作。如果需要重新设置,则必须再次调用SP_RPS_SET_BEGIN
参数说明:

返回值:

举例说明:
放弃复制设置
SP_RPS_SET_CANCEL();

DM 的数据复制可以在表级,模式级和库级进行配置,本篇我们看下表级数据复制的配置过程。
下面举一个简单的例子来说明数据复制的配置。
1. 准备工作
参与复制的复制实例的信息如下表所示。
数据库 实例名 IP地址 数据库端口号 MAL端口号 文件目录
复制数据库 jydm 10.10.10.180 5236 5241 /dm_home/dmdba/dmdbms/data/
主数据库 hy 10.10.10.184 5236 5242 /dm_home/dmdba/dmdbms/data/
从数据库 wy 10.10.10.185 5236 5243 /dm_home/dmdba/dmdbms/data/

假设主数据库上存在hy.t1表,从数据库上存在与主数据库hy.t1表结构完全相同的wy.t1表,现需要创建一个主数据库上hy.t1表到从数据库上wy.t1表的同步复制关系,其名称为REPHY2WY。

2. 参数设置
修改3台DM数据库的dm.ini 文件,添加如下内容:
数据库 dm.ini 设置
复制数据库 INSTANCE_NAME = jydm
PORT_NUM = 5236
MAL_INI = 1
主数据库 INSTANCE_NAME = hy
PORT_NUM = 5236
MAL_INI = 1
从数据库 INSTANCE_NAME = wy
PORT_NUM = 5236
MAL_INI = 1

配置dmmal.ini 文件
修改dmmal.ini文件,添加如下内容。Dmmal 配置文件默认没有,可以从示例目录下复制过来修改。

[root@shard1 ini_script]# pwd
/dm_home/dmdba/dmdbms/samples/ini_script
[root@shard1 ini_script]# ls -lrt
总用量 48
-rwxr-xr-x 1 dmdba dinstall  890 2月  14 2019 dmarch_example.ini
-rwxr-xr-x 1 dmdba dinstall 1966 2月  14 2019 dmdcr_cfg_example.ini
-rwxr-xr-x 1 dmdba dinstall  631 2月  14 2019 dmdcr_example.ini
-rwxr-xr-x 1 dmdba dinstall 1537 2月  14 2019 dminit_example.ini
-rwxr-xr-x 1 dmdba dinstall 2070 2月  14 2019 dmmal_example.ini
-rwxr-xr-x 1 dmdba dinstall 1277 2月  14 2019 dmmonitor_example.ini
-rwxr-xr-x 1 dmdba dinstall  288 2月  14 2019 dmmpp_example.ini
-rwxr-xr-x 1 dmdba dinstall 1679 2月  14 2019 dmtimer_example.ini
-rwxr-xr-x 1 dmdba dinstall 1241 2月  14 2019 dmwatch_example.ini
-rwxr-xr-x 1 dmdba dinstall 2146 2月  14 2019 dmwatcher_example.ini
-rwxr-xr-x 1 dmdba dinstall  522 2月  14 2019 dmwmon_example.ini
-rwxr-xr-x 1 dmdba dinstall  636 2月  14 2019 sqllog_example.ini


在每个数据库服务器上创建一个dmmal.ini文件,每个dmmal.ini 配置必须一致:

MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

[dmdba@shard1 jydm]$ cat dmmal.ini
MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

[dmdba@jydm2 hy]$ cat dmmal.ini
MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

[dmdba@jydm3 wy]$ cat dmmal.ini
MAL_CHECK_INTERVAL = 5
MAL_CONN_FAIL_INTERVAL = 5

[MAL_jydm]
MAL_INST_NAME = jydm
MAL_HOST = 10.10.10.180
MAL_PORT = 5241
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.180

[MAL_hy]
MAL_INST_NAME = hy
MAL_HOST = 10.10.10.184
MAL_PORT = 5242
MAL_INST_PORT = 5236 
MAL_INST_HOST = 10.10.10.184

[MAL_wy] 
MAL_INST_NAME =wy
MAL_HOST = 10.10.10.185
MAL_PORT = 5243
MAL_INST_PORT = 5236 
MAL_INST_HOST =10.10.10.185

对3个数据库都要启用mal_ini参数

SQL> sp_set_para_value(2,'MAL_INI',1);
DMSQL executed successfully
used time: 7.465(ms). Execute id is 23.

复制数据库初始化
如果是第一次使用复制数据库,需要对复制数据库执行初始化操作。通过执行系统函数SP_INIT_REP_SYS(create_flag)来初始化复制数据库。其主要作用是创建复制用户(SYSREP/SYSREP)和创建复制数据库上需要的系统表。SP_INIT_REP_SYS 的参数create_flag为1时表示创建用户和系统表,为0时表示删除用户和系统表。

开始初始化:

SQL> SP_INIT_REP_SYS(1);
DMSQL executed successfully
used time: 115.960(ms). Execute id is 30.
SQL> conn SYSREP/SYSREP

Server[LOCALHOST:5236]:mode is normal, state is open
login used time: 9.684(ms)
SQL> select table_name from user_tables;

LINEID     TABLE_NAME       
---------- -----------------
1          RPS_GROUPS
2          RPS_INSTANCES
3          RPS_REPLICATIONS
4          RPS_TABMAPS
5          RPS_FAULT_HISTORY
6          RPS_CONFLICTS
7          RPS_TIMERS

7 rows got

used time: 170.443(ms). Execute id is 31.

创建的7张复制系统表如下:
1) 复制组表
CREATE TABLE SYSREP.RPS_GROUPS (
NAME VARCHAR(128), // 复制组名
ID INT, // 复制组ID
DESC$ VARCHAR(1000), // 描述
CLUSTER PRIMARY (NAME)
);
2) 复制节点实例表
CREATE TABLE SYSREP.RPS_INSTANCES(
INST_NAME VARCHAR(128), // 复制节点实例名
GRP_ID INT, // 复制组ID
INST_ID INT, // 实例在复制组中编号
FAULT_TIMEOUT INT, // 故障超时处理值,以秒为单位,0为立即超时
VALID_FLAG CHAR(1), // 节点系统状态
FAULT_TIME DATETIME, // 节点故障开始时间
NET_VALID_FLAG CHAR(1), // 网络状态
NET_FAULT_TIME DATETIME, // 网络故障开始时间
CLUSTER PRIMAY KEY(GRP_ID, INST_NAME)
);
3) 复制关系表
CREATE TABLE SYSREP.RPS_REPLICATIONS(
REP_NAME VARCHAR(128), // 复制名
GRP_ID INT, // 复制组ID
REP_ID INT, // 复制ID,全局唯一
MINST_ID INT, // 主节点实例编号
SINST_ID INT, // 从节点实例编号
ARCH_DIR VARCHAR(256), // 主节点归档日志路径
FAULT_TIMEOUT INT, // 故障超时处理值,以秒为单位,0为立即超时
VALID_FLAG CHAR(1), // 复制关系状态
FAULT_TIME DATETIME, // 故障开始时间
SYNC_FLAG INTEGER //指定同步或异步复制
TIMER_NAME VARCHAR(128) //指定异步复制的定时器(同步复制没有此项)
DESC$ VARCHAR(1000), // 复制描述
CLUSTER PRIMARY KEY(GRP_ID, REP_NAME)
);
4) 复制映射表
CREATE TABLE SYSREP.RPS_TABMAPS(
REP_ID INT, //复制ID
MSCH_NAME VARCHAR(128), //主表模式名
MTAB_NAME VARCHAR(128), //主表名
MSCH_ID INT, //主表模式ID
MTAB_ID INT, //主表ID
SSCH_NAME VARCHAR(128), //从表模式名
STAB_NAME VARCHAR(128), //从表名
SSCH_ID INT, //从表模式ID
STAB_ID INT, //从表ID
READONLY_MODE INT, //映射模式1:只读模式,0:非只读模式
CLUSTER PRIMARY KEY(REP_ID, MTAB_ID, STAB_ID)
);
5) 复制故障历史表
CREATE TABLE SYSREP.REP_FAULT_HISTORY(
GRP_NAME VARCHAR(128), // 复制组
OBJ_NAME VARCHAR(128), // 故障节点或关系
FAULT_TYPE VARCHAR(128), // 故障类型描述
START_TIME DATETIME, // 故障开始时间
END_TIME DATETIME // 故障结束时间
);
6) 复制冲突历史表
CREATE TABLE SYSREP.RPS_CONFLICTS
(
SEQ_NO BIGINT // 冲突序号
REP_ID INT, // 对应复制号
INST_ID INT, // 产生冲突的节点编号
TABLE_ID INT, // 冲突表ID
TYPE TINYINT // 操作类型
OCC_TIME DATETIME, // 冲突产生时间
KEY_DATA VARCHAR(8000), // 冲突数据的PK值,如包含多个KEY值,则以逗号分隔。如键值超长则截断
);
7) 复制定时器表
CREATE TABLE SYSREP.RPS_TIMERS (
NAME VARCHAR(128), // 定时器名称
TYPE$ INT, // 定时类型,取值可参见SP_RPS_CREATE_TIMER
FERQ_INTERVAL INT, // 间隔天数
FREQ_SUB_INTERVAL INT, // 间隔的月/周(调度类型决定)数
FREQ_MINUTE_INTERVAL INT, // 间隔的分钟数
START_TIME TIME, // 开始时间
END_TIME TIME, // 结束时间
DURING_START_DATE DATETIME // 开始时间点
DURING_END_DATE DATETIME, // 结束时间点
NO_END_DATA_FLAG INTEGER //是否有结束日期(0:有结束日期;1:没有结束日期)
DESC$ VARCHAR(1000), // 定时器描述
CLUSTER PRIMARY KEY(REP_NAME)
);
配置表级复制

启动3台服务器,启动的顺序不分先后。

[root@shard1 jydm]# systemctl stop DmServicejydm.service
[root@shard1 jydm]# systemctl start DmServicejydm.service

[root@jydm2 ~]# systemctl stop DmServicehy.service
[root@jydm2 ~]# systemctl start DmServicehy.service

[root@jydm3 ~]# systemctl stop DmServicewy.service
[root@jydm3 ~]# systemctl start DmServicewy.service

登录复制数据库(RPS jydm),保证服务器状态为OPEN,开始复制配置。

[dmdba@shard1 bin]$ ./disql sysdba/abcd

Server[LOCALHOST:5236]:mode is normal, state is open
login used time: 9.851(ms)
disql V7.1.6.46-Build(2018.02.08-89107)ENT 
Connected to: DM 7.1.6.46

创建复制组REP_GRP_hy2wy

SQL> SP_RPS_ADD_GROUP('REP_GRP_hy2wy', '主从同步复制');
DMSQL executed successfully
used time: 16.792(ms). Execute id is 3.

SQL> select * from SYSREP.RPS_GROUPS;

LINEID     NAME          ID          DESC$       
---------- ------------- ----------- ------------
1          REP_GRP_hy2wy 1           主从同步复制

used time: 1.599(ms). Execute id is 4.

开始设置

SQL> SP_RPS_SET_BEGIN('REP_GRP_hy2wy');
DMSQL executed successfully
used time: 1.081(ms). Execute id is 6.

添加复制关系

SQL> SP_RPS_ADD_REPLICATION ('REP_GRP_hy2wy', 'REPhy2wy', 'hy到wy的同步复制', 'hy', 'wy', NULL, '/dm_home/dmdba/dmdbms/dmreplog');
DMSQL executed successfully
used time: 3.807(ms). Execute id is 7.

添加复制映射, 注意这里用户名和表名要大写,否则会提示对象不存在

SQL> SP_RPS_ADD_TAB_MAP('REPhy2wy', 'HY', 'T1', 'WY', 'T1', 0);
DMSQL executed successfully
used time: 4.495(ms). Execute id is 10.

提交设置

SQL> SP_RPS_SET_APPLY();
DMSQL executed successfully
used time: 00:00:05.038. Execute id is 12.
SQL> select * from SYSREP.RPS_REPLICATIONS;

LINEID     REP_NAME GRP_ID      REP_ID      MINST_ID    SINST_ID    ARCH_DIR                       FAULT_TIMEOUT VALID_FLAG  FAULT_TIME                  SYNC_FLAG   TIMER_NAME DESC$           
---------- -------- ----------- ----------- ----------- ----------- ------------------------------ ------------- ----------- --------------------------- ----------- ---------- ----------------
1          REPhy2wy 1           1           1           2           /dm_home/dmdba/dmdbms/dmreplog -1            0           NULL                        1           NULL       hy到wy的同步复制

used time: 0.534(ms). Execute id is 13.
SQL> select * from SYSREP.RPS_INSTANCES;

LINEID     INST_NAME GRP_ID      INST_ID     FAULT_TIMEOUT VALID_FLAG  FAULT_TIME                  NET_VALID_FLAG NET_FAULT_TIME             
---------- --------- ----------- ----------- ------------- ----------- --------------------------- -------------- ---------------------------
1          hy        1           1           -1            0           NULL                        0              NULL
2          wy        1           2           -1            0           NULL                        0              NULL

used time: 0.499(ms). Execute id is 14.
SQL> select * from SYSREP.RPS_TABMAPS;

LINEID     REP_ID      MSCH_NAME MTAB_NAME MSCH_ID     MTAB_ID     SSCH_NAME STAB_NAME SSCH_ID     STAB_ID     READONLY_MODE
---------- ----------- --------- --------- ----------- ----------- --------- --------- ----------- ----------- -------------
1          1           HY        T1        150995951   1297        WY        T1        150995951   1296        0

used time: 0.523(ms). Execute id is 15.
SQL> select * from SYSREP.RPS_FAULT_HISTORY;
no rows

used time: 1.136(ms). Execute id is 16.
SQL> select * from SYSREP.RPS_CONFLICTS;
no rows

used time: 1.336(ms). Execute id is 17.
SQL> select * from SYSREP.RPS_TIMERS;
no rows

used time: 0.987(ms). Execute id is 18.

至此,表复制完成。注意一点,DM的复制配置必须在开始复制配置之前执行SP_RPS_SET_BEGIN,配置完成之后执行SP_RPS_SET_APPLY提交。
验证同步
主库的逻辑日志:

[root@jydm2 dmreplog]# ls -lrt
总用量 4
-rw-r--r-- 1 dmdba dinstall 48 10月 21 08:24 llog_arch_file_20141021082409.log

主库对T1表插入数据:

[dmdba@jydm2 bin]$ ./disql hy/hy
Server[LOCALHOST:5236]:mode is normal, state is open
login used time: 6.047(ms)
disql V7.1.6.46-Build(2018.02.08-89107)ENT 
Connected to: DM 7.1.6.46
SQL> select * from t1;
no rows

used time: 0.998(ms). Execute id is 4.
S SQL> insert into t1 values(2,'hy2');
affect rows 1

used time: 0.777(ms). Execute id is 8.
SQL> commit;
executed successfully
used time: 1.141(ms). Execute id is 9.
SQL> select * from t1;

LINEID     ID USERNAME
---------- -- --------
1          1  hy
2          2  hy2

used time: 0.403(ms). Execute id is 10.

从库查询: 同步成功,主库之前的数据无法同步过来,只对后来操作的数据有效

[dmdba@jydm3 bin]$ ./disql wy/wy

Server[LOCALHOST:5236]:mode is normal, state is open
login used time: 5.844(ms)
disql V7.1.6.46-Build(2018.02.08-89107)ENT 
Connected to: DM 7.1.6.46
SQL> select * from t1;     

LINEID     ID USERNAME
---------- -- --------
1          1  hy
2          2  hy2

used time: 0.618(ms). Execute id is 9.

在主库中更新记录

SQL> update t1 set username='hy1' where id=1;
affect rows 1

used time: 1.427(ms). Execute id is 11.
SQL> commit;
executed successfully
used time: 0.869(ms). Execute id is 12.
SQL> select * from t1;

LINEID     ID USERNAME
---------- -- --------
1          1  hy1
2          2  hy2

used time: 0.339(ms). Execute id is 13.

查看从库记录

SQL> select * from t1; 

LINEID     ID USERNAME
---------- -- --------
1          1  hy1
2          2  hy2

used time: 1.272(ms). Execute id is 12.

主库删除T1表的所有数据:

SQL> truncate table t1;
executed successfully
used time: 3.283(ms). Execute id is 14.

从库的所有数据也删除了

SQL> select * from t1;
no rows

used time: 0.793(ms). Execute id is 15.

整个复制的环境中,逻辑日志仅存在主库中。
我们配置的是同步的复制,如果想改成异步同步可以添加个计时器,比如:
SP_RPS_ADD_TIMER(‘hy2wy_TIMER’,’从hy到wy定时复制’,1,0,0,0,’23:18:33′,NULL,’2019-12-18 23:18:33′,NULL,1);
SP_RPS_REP_RESET_TIMER(‘REPhy2wy’,’hy2wy_TIMER’);

若需要删除复制组,则该复制组不能处于配置阶段,即该组的配置已经提交或取消。
监控数据复制
配置完成后复制服务器RPS虽然不参与复制的具体执行,但是在复制过程中,还是建议保持RPS的运行来对复制进行监控。
复制系统内,状态分为复制节点的状态和复制关系的状态。具体内容见下表。

复制节点的系统状态在SYSREP.RPS_INSTANCES中的VALID_FLAG字段表示;网络状态在SYSREP.RPS_INSTANCES表中NET_VALID_FLAG的字段表示。
复制关系的状态在SYSREP.RPS_REPLICATIONS中的VALID_FLAG字段表示。

SQL> select * from sysrep.rps_replications;

LINEID     REP_NAME GRP_ID      REP_ID      MINST_ID    SINST_ID    ARCH_DIR                       FAULT_TIMEOUT VALID_FLAG  FAULT_TIME                  SYNC_FLAG   TIMER_NAME DESC$           
---------- -------- ----------- ----------- ----------- ----------- ------------------------------ ------------- ----------- --------------------------- ----------- ---------- ----------------
1          REPhy2wy 1           1           1           2           /dm_home/dmdba/dmdbms/dmreplog -1            0           NULL                        1           NULL       hy到wy的同步复制

used time: 1.339(ms). Execute id is 23.
SQL> select * from SYSREP.RPS_INSTANCES;

LINEID     INST_NAME GRP_ID      INST_ID     FAULT_TIMEOUT VALID_FLAG  FAULT_TIME                  NET_VALID_FLAG NET_FAULT_TIME             
---------- --------- ----------- ----------- ------------- ----------- --------------------------- -------------- ---------------------------
1          hy        1           1           -1            0           NULL                        0              NULL
2          wy        1           2           -1            0           NULL                        0              NULL

used time: 0.574(ms). Execute id is 24.

复制系统的配置信息可以通过在复制RPS上查询系统表来实现。在RPS上,复制相关的信息都在SYSREP模式中。
复制的监视按复制组为单位进行,RPS每隔1分钟轮询探查所有的复制组,在每个复制组内,依次探测各个复制节点,要求其返回复制节点本身的状态和其所涉及的复制的状态。
这里需要特别说明的是节点的系统异常状态是指该节点在复制环境中的状态,是一个推测值。当RPS无法得到节点的返回消息,其他节点的返回消息中所有涉及到该节点的复制关系都是异常时,RPS就认为该节点系统异常。
若复制结点或复制关系发生异常,这些异常都会记录在SYSREP.RPS_FAULT_HISTORY表中。若其END_TIME字段为NULL,表示该故障还没有结束,管理员需尽快检查复制节点的状态及其网络连接。

SQL> select * from SYSREP.RPS_CONFLICTS;
no rows

used time: 1.336(ms). Execute id is 17.

DM7并没有特意设置对错误历史的管理接口,管理员可以通过对SYSREP.RPS_FAULT_HISTORY表的删除和查询来实现错误记录的管理。
至此,复制环境配置完成。以上的例子只是一个最简单的复制环境。复制的配置灵活,在同一个复制组内,一个主服务器可以有多个从服务器,一个复制节点可以既是主服务器又是从服务器。管理员可以根据实际需要,配置出对称、一对多、多对一、级联、循环的复制环境。
在配置过程中或配置完成后,可以对复制的配置进行修改。修改包括复制组、复制关系、复制对象的删除和复制关系属性的修改。这些修改操作都必须在开始复制SP_RPS_SET_BEGIN和提交复制SP_RPS_SET_APPLY之间进行。若需要删除复制组,则该复制组不能处于配置阶段,即该组的配置已经提交或取消。
添加一个定时器,将同步复制修改为异步复制

SQL> SP_RPS_ADD_TIMER('hy2wy_TIMER','从hy到wy定时复制',1,0,0,0,'23:18:33',NULL,'2019-12-18 23:18:33',NULL,1);
SP_RPS_ADD_TIMER('hy2wy_TIMER','从hy到wy定时复制',1,0,0,0,'23:18:33',NULL,'2019-12-18 23:18:33',NULL,1);
[-8702]:group not set begin.
used time: 33.874(ms). Execute id is 0.

提示复制组设置没有开始所以不能进行修改

SQL> SP_RPS_SET_BEGIN('REP_GRP_hy2wy');
DMSQL executed successfully
used time: 0.481(ms). Execute id is 26.

设置时间开始时间为2019-12-18 23:38:33

SQL> SP_RPS_ADD_TIMER('hy2wy_TIMER','从hy到wy定时复制',1,0,0,0,'23:38:33',NULL,'2019-12-18 23:38:33',NULL,1);
DMSQL executed successfully
used time: 13.217(ms). Execute id is 29.
SQL> SP_RPS_REP_RESET_TIMER('REPhy2wy','hy2wy_TIMER');
DMSQL executed successfully
used time: 0.790(ms). Execute id is 30.
SQL> SP_RPS_SET_APPLY();
DMSQL executed successfully
used time: 24.494(ms). Execute id is 31.

现在在主库中插入数据

SQL> select * from t1;

LINEID     ID USERNAME
---------- -- --------
1          1  hy

used time: 2.296(ms). Execute id is 4.
SQL> insert into t1 values(2,'hy2');
affect rows 1

used time: 1.519(ms). Execute id is 5.
SQL> commit;
executed successfully
used time: 1.430(ms). Execute id is 6.
SQL> select * from t1;

LINEID     ID USERNAME
---------- -- --------
1          1  hy
2          2  hy2

used time: 0.512(ms). Execute id is 8.

在从库中查询记录

SQL> select * from t1;

LINEID     ID USERNAME
---------- -- --------
1          1  hy

used time: 0.337(ms). Execute id is 8.
SQL> select sysdate;

LINEID     SYSDATE                    
---------- ---------------------------
1          2019-12-18 23:38:37.570259

used time: 0.263(ms). Execute id is 9.

可以看到在时间2019-12-18 23:38:37.570259时间点表数据还没有同步到从库

SQL> select sysdate;

LINEID     SYSDATE                    
---------- ---------------------------
1          2019-12-18 23:39:05.629576

used time: 0.432(ms). Execute id is 12.
SQL> select * from t1;

LINEID     ID USERNAME
---------- -- --------
1          1  hy
2          2  hy2

used time: 0.458(ms). Execute id is 13.

可以看到在时间2019-12-18 2019-12-18 23:39:05.629576时间点表数据已经同步到从库

删除复制映射

SQL> SP_RPS_DROP_TAB_MAP('REPhy2wy', 'HY', 'T1', 'WY', 'T1');
DMSQL executed successfully
used time: 1.485(ms). Execute id is 36.

修改复制的错误超时时间,超时的时间单位是秒

SQL> SP_RPS_SET_ROUTE_FAULT_TIMEOUT('REPhy2wy', 60);
DMSQL executed successfully
used time: 0.791(ms). Execute id is 37.

删除复制关系

SQL> SP_RPS_DROP_REPLICATION('REPhy2wy');
DMSQL executed successfully
used time: 1.807(ms). Execute id is 38. 

删除整个复制组

SQL> SP_RPS_DROP_GROUP('REP_GRP_hy2wy');
DMSQL executed successfully
used time: 1.807(ms). Execute id is 39. 

删除数据复制所使用的用户和系统表

SQL> SP_INIT_REP_SYS(0);
DMSQL executed successfully
used time: 160.803(ms). Execute id is 51.
SQL> select * from SYSREP.RPS_INSTANCES;
select * from SYSREP.RPS_INSTANCES;
[-2103]:Error in line: 1
Invalid schema name [SYSREP].
used time: 0.735(ms). Execute id is 0.

另外,在配置或修改配置时想要取消操作,可以使用如下系统过程结束配置。

SQL> SP_RPS_SET_CANCEL();
DMSQL executed successfully
used time: 0.749(ms). Execute id is 40.

DM并行查询

倘若没有并行查询技术,一个串行执行的查询语句只能利用CPU或者磁盘设备中的一个,而不能利用整个计算机的处理能力。并行查询技术的出现,使得单个SQL语句能利用多个CPU和磁盘设备的处理能力。其优势在于可以通过多个线程来处理查询任务,从而提高查询的效率。

达梦数据库为具有多个CPU的数据库服务器提供并行查询的功能,以优化查询任务的性能。数据库服务器只有具有多个CPU,才能使用并行执行查询操作,来提高查询任务的速度。

达梦数据库通过三个步骤来完成并行查询:首先,确定并行任务数;其次,确定并行工作线程数;最后,执行查询。并行查询相关参数见下表:
参数名 缺省值 属性 说明
MAX_PARALLEL_DEGREE 1 动态,会话级 用来设置默认并行任务个数。取值范围:1~128。缺省值1,表示无并行任务。当PARALLEL_POLICY值为1时该参数值才有效。

parallel_policy 0 静态 用来设置并行策略。取值范围:0、1和2,缺省为0。其中,0表示不支持并行;1表示自动并行模式;2表示手动并行模式。

PARALLEL_THRD_NUM 10 静态 用来设置并行工作线程个数。取值范围:1~1024。

当开启自动并行(PARALLEL_POLICY=1)时,参数MAX_PARALLEL_DEGREE生效,控制并行查询最多使用的线程数。MAX_PARALLEL_DEGREE缺省值为1,表示不并行。此时若指定参数对应的HINT “PARALLEL”,则使用HINT值;

当开启手动并行(PARALLEL_POLICY=2)时,参数MAX_PARALLEL_DEGREE失效,用户需要在语句中使用此参数对应的HINT “PARALLEL”指定语句的并行度,否则不并行。

1.在INI参数中设置默认值
INI参数MAX_PARALLEL_DEGREE设置最大并行任务个数。取值范围:1~128。缺省值1,表示无并行任务,此参数仅在PARALLEL_POLICY值为1时才有效。
例如,在INI参数中将MAX_PARALLEL_DEGREE设置为3的格式如下:
MAX_PARALLEL_DEGREE 3

先查看max_parallel_degree的缺省值

SQL> select sf_get_para_value(1,'MAX_PARALLEL_DEGREE');

LINEID     SF_GET_PARA_VALUE(1,'MAX_PARALLEL_DEGREE')
---------- ------------------------------------------
1          1

used time: 150.207(ms). Execute id is 197.

下面的查询将查看dm.ini文件中设置的max_parallel_degree参数值

SQL> select * from v$dm_ini where para_name='MAX_PARALLEL_DEGREE';

LINEID     PARA_NAME           PARA_VALUE MIN_VALUE MAX_VALUE MPP_CHK SESS_VALUE FILE_VALUE DESCRIPTION                      PARA_TYPE
---------- ------------------- ---------- --------- --------- ------- ---------- ---------- -------------------------------- ---------
1          MAX_PARALLEL_DEGREE 1          1         128       N       1          1          Maximum degree of parallel query SESSION

used time: 50.228(ms). Execute id is 198.

下面的查询将查看内存中的max_parallel_degree参数值

SQL> select * from v$parameter where name='MAX_PARALLEL_DEGREE';

LINEID     ID          NAME                TYPE    VALUE SYS_VALUE FILE_VALUE DESCRIPTION
---------- ----------- ------------------- ------- ----- --------- ---------- --------------------------------
1          274         MAX_PARALLEL_DEGREE SESSION 1     1         1          Maximum degree of parallel query

used time: 7.440(ms). Execute id is 199.

现在执行下面的命令来同时修改内存与dm.ini文件中的max_parallel_degree参数为3

SQL> call sp_set_para_value(1,'MAX_PARALLEL_DEGREE',3);
DMSQL executed successfully
used time: 7.183(ms). Execute id is 200.

执行下面的查询可以看到max_parallel_degree参数修改为3了

SQL> select sf_get_para_value(1,'MAX_PARALLEL_DEGREE');

LINEID     SF_GET_PARA_VALUE(1,'MAX_PARALLEL_DEGREE')
---------- ------------------------------------------
1          3

used time: 5.544(ms). Execute id is 201.

从查询返回的sess_value与file_value都为3可以确定max_parallel_degree在dm.ini文件中已经被修改了

SQL> select * from v$dm_ini where para_name='MAX_PARALLEL_DEGREE';

LINEID     PARA_NAME           PARA_VALUE MIN_VALUE MAX_VALUE MPP_CHK SESS_VALUE FILE_VALUE DESCRIPTION                      PARA_TYPE
---------- ------------------- ---------- --------- --------- ------- ---------- ---------- -------------------------------- ---------
1          MAX_PARALLEL_DEGREE 3          1         128       N       3          3          Maximum degree of parallel query SESSION

used time: 6.910(ms). Execute id is 202.

从查询返回的sys_value为3可以在内存中max_parallel_degree也已经被修改了。

SQL> select * from v$parameter where name='MAX_PARALLEL_DEGREE';

LINEID     ID          NAME                TYPE    VALUE SYS_VALUE FILE_VALUE DESCRIPTION
---------- ----------- ------------------- ------- ----- --------- ---------- --------------------------------
1          274         MAX_PARALLEL_DEGREE SESSION 3     3         3          Maximum degree of parallel query

used time: 6.335(ms). Execute id is 203.

然后,使用一般的SQL语句查询即可执行并行查询,不需要使用HINT。如:

SQL> explain SELECT * FROM SYSOBJECTS;

1   #NSET2: [0, 1694, 396]
2     #LOCAL COLLECT: [0, 1694, 396]; op_id(1) n_grp_by (0) n_cols(0) n_keys(0) for_sync(FALSE)
3       #PRJT2: [0, 1694, 396]; exp_num(17), is_atom(FALSE)
4         #CSCN2: [0, 1694, 396]; SYSINDEXSYSOBJECTS(SYSOBJECTS as SYSOBJECTS)

used time: 0.951(ms). Execute id is 0.

执行计划中的LOCAL COLLECT 代表:本地并行下数据收集处理,代替LOCAL GATHER。

2.在SQL语句中使用“PARALLEL”关键字特别指定
当PARALLEL_POLICY=2时,需要在SQL语句中通过“PARALLEL”HINT指定并行度,否则不并行。若PARALLEL_POLICY=1,则SQL语句中使用的“PARALLEL”HINT总是优先于MAX_PARALLEL_DEGREE参数设置。“PARALLEL”关键字的用法是在数据查询语句的SELECT关键字后,增加HINT子句来实现。

HINT语法格式如下:
/*+ PARALLEL([< 表名>] < 并行任务个数>) */

例如,下面的例子中,即使已经设置了MAX_PARALLEL_DEGREE默认值3,但实际使用的为PARALLEL指定的任务个数4:

SQL> explain SELECT /*+ PARALLEL(4) */ * FROM SYSOBJECTS;

1   #NSET2: [0, 1694, 396]
2     #LOCAL COLLECT: [0, 1694, 396]; op_id(1) n_grp_by (0) n_cols(0) n_keys(0) for_sync(FALSE)
3       #PRJT2: [0, 1694, 396]; exp_num(17), is_atom(FALSE)
4         #CSCN2: [0, 1694, 396]; SYSINDEXSYSOBJECTS(SYSOBJECTS as SYSOBJECTS)

used time: 0.967(ms). Execute id is 0.

另外,每个语句中仅能设置一次并行任务个数,如果设置了多次,则以最后一次设置为准,而且任务个数在全语句中生效。

例如,下面的例子中,使用的并行任务个数为2。

SQL> call sp_set_para_value(1,'MAX_PARALLEL_DEGREE',1);
DMSQL executed successfully
used time: 6.554(ms). Execute id is 211.
SQL> select sf_get_para_value(1,'MAX_PARALLEL_DEGREE');

LINEID     SF_GET_PARA_VALUE(1,'MAX_PARALLEL_DEGREE')
---------- ------------------------------------------
1          1

used time: 5.569(ms). Execute id is 212.

SQL> explain SELECT /*+ PARALLEL(1) *//*+ PARALLEL(2) */ * FROM SYSOBJECTS;

1   #NSET2: [0, 1694, 396]
2     #LOCAL COLLECT: [0, 1694, 396]; op_id(1) n_grp_by (0) n_cols(0) n_keys(0) for_sync(FALSE)
3       #PRJT2: [0, 1694, 396]; exp_num(17), is_atom(FALSE)
4         #CSCN2: [0, 1694, 396]; SYSINDEXSYSOBJECTS(SYSOBJECTS as SYSOBJECTS)

used time: 1.067(ms). Execute id is 0.

这种方式能够为单条查询语句设置额外的并行任务个数,以此来提高某些特殊查询任务的性能。

在执行并行查询任务之前,您需要指定完成该任务的并行工作线程数。值得注意的是,实际使用的线程数并非总是等于并行工作线程数。并行工作线程数是在INI参数中设定的,实际使用并行工作线程数是根据系统的实际状况确定的。
1. 并行工作线程数,在INI参数中设定
首先,使用PARALLEL_POLICY参数来设置并行策略。取值范围:0、1和2,默认值0。其中,0表示不支持并行;1表示自动并行模式;2表示手动并行模式。

当开启本地并行(PARALLEL_POLICY>0)时,使用PARALLEL_THRD_NUM指定本地并行查询使用的线程数,取值范围为1~1024,缺省值为10。需要注意的是,若PARALLEL_POLICY=1,如果PARALLEL_THRD_NUM=1, 则按照CPU个数创建并行线程。

例如,设置并行策略PARALLEL_POLICY为2,即手动设置并行工作线程数;同时,设置并行工作线程数PARALLEL_THRD_NUM为4个。

SQL> call sp_set_para_value(2,'PARALLEL_POLICY',2);
DMSQL executed successfully
used time: 6.942(ms). Execute id is 223.
SQL> call sp_set_para_value(2,'PARALLEL_THRD_NUM',4);
DMSQL executed successfully
used time: 6.871(ms). Execute id is 224.

当然,并非所有的查询都适合使用并行查询。大量占用CPU 周期的查询最适合采用并行查询的功能。例如,大型表的连接查询、大量数据的聚合和大型结果集的排序等都很适合采用并行查询。对于简单查询(常用于事务处理应用程序)而言,执行并行查询所需的额外协调工作会大于潜在的性能提升。所以,数据库管理员在确定是否需要使用并行策略的时候,需要慎重。

2. 实际使用的线程数,达梦数据库会根据每个并行查询操作自动检测
实际使用线程数是数据库在查询计划执行时初始化的时候确定的。也就是说,这不需要用户去干预,而是系统根据并行任务数和实际空闲的并行工作线程数来确定的。此操作所依据的条件如下:首先,检测达梦数据库是否运行在具有多个CPU的计算机上。只有具有多个CPU 的计算机才能使用并行查询。这是一个硬性的限制条件。其次,检测可用的空闲工作线程是否足够。并行查询到底采用多少线程数,除了跟操作的复杂程度相关外,还跟当时的服务器状态相关,如是否有足够的可用的空闲工作线程数量等。每个并行查询操作都要求一定的工作线程数量才能够执行;而且执行并行计划比执行串行计划需要更多的线程,所需要的线程数量也会随着任务个数的提高而增加。当无法满足特定并行查询执行的线程要求时,数据库引擎就会自动减少任务个数,甚至会放弃并行查询而改为串行计划。所以,即使同一个操作在不同时候可能会采用不同的线程数。

例如,即使设置并行工作线程数为4。而实际使用的线程数可能只有3个,或者更少。

使用手动并行模式时,只需要在INI参数中设置好如下2个参数,然后执行并行SQL查询语句时,需手动指定当前并行任务个数。若不指定,将不使用并行。设置的2个参数如下:
PARALLEL_POLICY 2
PARALLEL_THRD_NUM 4

使用自动并行模式时,一般指定如下三个参数:
MAX_PARALLEL_DEGREE 3
PARALLEL_POLICY 1
PARALLEL_THRD_NUM 10
另外,当PARALLEL_POLICY为0时,即使有并行任务,也不支持并行。

然后,执行语法格式类似“SELECT * FROM SYSOBJECTS;”的并行SQL语句即可,本条语句使用默认并行任务数3。

当然,如果单条查询语句不想使用默认并行任务数,可以通过在SQL语句中增加HINT,通过“PARALLEL”关键字来特别指定。此时,执行的并行SQL语句格式为“SELECT /*+ PARALLEL(SYSOBJECTS 4) */ * FROM SYSOBJECTS;”,本条语句使用的并行任务数为4。

DM7闪回与闪回查询

闪回
当用户操作不慎导致错误的删改数据时,非常希望有一种简单快捷的方式可以恢复数据。闪回技术,就是为了用户可以迅速处理这种数据逻辑损坏的情况而产生的。

闪回技术主要是通过回滚段存储的UNDO记录来完成历史记录的还原。设置ENABLE_FLASHBACK为1后,开启闪回功能。DM会保留回滚段一段时间,回滚段保留的时间代表着可以闪回的时间长度。由UNDO_RETENTION参数指定。

SQL> select sf_get_para_value(1,'ENABLE_FLASHBACK');

LINEID     SF_GET_PARA_VALUE(1,'ENABLE_FLASHBACK')
---------- ---------------------------------------
1          0

used time: 204.313(ms). Execute id is 62.
SQL> select sf_get_para_value(1,'UNDO_RETENTION');

LINEID     SF_GET_PARA_VALUE(1,'UNDO_RETENTION')
---------- -------------------------------------
1          90

used time: 6.236(ms). Execute id is 63.

下面修改动态参数ENABLE_FLASHBACK,scope=1同时修改内存和dm.ini文件

SQL> call sp_set_para_value(1,'ENABLE_FLASHBACK',1);
DMSQL executed successfully
used time: 13.216(ms). Execute id is 64.
SQL> select sf_get_para_value(1,'ENABLE_FLASHBACK');

LINEID     SF_GET_PARA_VALUE(1,'ENABLE_FLASHBACK')
---------- ---------------------------------------
1          1

used time: 5.703(ms). Execute id is 65.

回滚段保留的时间缺省值为90秒,我们要修改它为1天

SQL> select sf_get_para_value(1,'UNDO_RETENTION');

LINEID     SF_GET_PARA_VALUE(1,'UNDO_RETENTION')
---------- -------------------------------------
1          90

used time: 6.236(ms). Execute id is 63.

SQL> call sp_set_para_value(1,'UNDO_RETENTION',86400);                            
DMSQL executed successfully
used time: 7.155(ms). Execute id is 74.
SQL> select sf_get_para_value(1,'UNDO_RETENTION');

LINEID     SF_GET_PARA_VALUE(1,'UNDO_RETENTION')
---------- -------------------------------------
1          86400

used time: 5.877(ms). Execute id is 75.

开启闪回功能后,DM会在内存中记录下每个事务的起始时间和提交时间。通过用户指定的时刻,查询到该时刻的事务号,结合当前记录和回滚段中的UNDO记录,就可以还原出特定事务号的记录。即指定时刻的记录状态。从而完成闪回查询。闪回查询功能完全依赖于回滚段管理,对于DROP等误操作不能恢复。闪回特性可应用在以下方面:
1. 自我维护过程中的修复:当一些重要的记录被意外删除,用户可以向后移动到一个时间点,查看丢失的行并把它们重新插入现在的表内恢复;

2. 用于分析数据变化:可以对同一张表的不同闪回时刻进行链接查询,以此查看变化的数据。

闪回查询
当系统INI参数ENABLE_FLASHBACK置为1时,闪回功能开启,可以进行闪回查询。MPP环境不支持闪回查询。

SQL> select sf_get_para_value(1,'ENABLE_FLASHBACK');

LINEID     SF_GET_PARA_VALUE(1,'ENABLE_FLASHBACK')
---------- ---------------------------------------
1          1

used time: 5.703(ms). Execute id is 65.

[root@shard1 jydm]# strings dm.ini | grep flash
ENABLE_FLASHBACK            =  1                    #Whether to enable flashback function

闪回查询子句
闪回查询子句的语法,是在数据查询语句(参考第4章)的基础上,为FROM子句增加了闪回查询子句。
语法格式
< 闪回查询子句>::=WHEN |

参数
1.time_exp 一个日期表达式,一般用字符串方式表示
2.trxid 指定事务ID号

语句功能
用户通过闪回查询子句,可以得到指定表过去某时刻的结果集。指定条件可以为时刻,或事务号

使用说明
1.闪回查询只支持普通表(包括加密表与压缩表)、临时表和堆表,不支持水平分区表、垂直分区表、列存储表、外部表与视图;

2.闪回查询中trxid的值,一般需要由闪回版本查询(见下节)的伪列来确定。实际使用中多采用指定时刻的方式。

例1闪回查询特定时刻的PERSON_TYPE表。
查询PERSON_TYPE表。

SQL> SELECT * FROM PERSON.PERSON_TYPE;

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表

used time: 15.321(ms). Execute id is 78.

在插入数据之前记录时间,在闪回查询时使用

SQL> select sysdate;

LINEID     SYSDATE                    
---------- ---------------------------
1          2019-12-01 23:34:12.761683

used time: 0.480(ms). Execute id is 79.

SQL> INSERT INTO PERSON.PERSON_TYPE(NAME) VALUES('防损员');
affect rows 1

used time: 0.615(ms). Execute id is 80.
SQL> INSERT INTO PERSON.PERSON_TYPE(NAME) VALUES('保洁员');
affect rows 1

used time: 0.562(ms). Execute id is 81.
SQL> commit;
executed successfully
used time: 16.237(ms). Execute id is 82.



SQL> SELECT * FROM PERSON.PERSON_TYPE;

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表
5          7             防损员
6          8             保洁员

6 rows got

used time: 0.626(ms). Execute id is 83.

使用闪回查询取得2019-12-01 23:34:12时刻的数据。此时刻在插入数据的操作之前,可见此时的结果集不应该有2019-12-01 23:34:12时刻以后插入的数据。

SQL> SELECT * FROM PERSON.PERSON_TYPE WHEN TIMESTAMP '2019-12-01 23:34:12';

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表

used time: 1.416(ms). Execute id is 84.

在2019-12-01 23:39:26时刻删除数据,并提交。

SQL> select sysdate;

LINEID     SYSDATE                    
---------- ---------------------------
1          2019-12-01 23:39:26.865328

used time: 0.580(ms). Execute id is 85.

SQL> DELETE FROM PERSON.PERSON_TYPE WHERE PERSON_TYPEID > 5;
affect rows 2

used time: 1.797(ms). Execute id is 86.
SQL> commit;
executed successfully
used time: 19.834(ms). Execute id is 87.

SQL> SELECT * FROM PERSON.PERSON_TYPE;

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表
5          5             防损员
used time: 0.691(ms). Execute id is 88.

使用闪回查询得到删除前的数据。

SQL> SELECT * FROM PERSON.PERSON_TYPE WHEN TIMESTAMP '2019-12-01 23:39:26';

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表
5          5             防损员
6          6             保洁员

6 rows got

used time: 1.262(ms). Execute id is 89.

闪回查询指定TRXID的PERSON_TYPE表。
要获得TRXID信息,需要通过闪回版本查询的伪列VERSIONS_ENDTRXID。

在2019-12-01 23:45:27 时刻修改数据,并提交。

SQL> select sysdate;

LINEID     SYSDATE                    
---------- ---------------------------
1          2019-12-01 23:48:27.983996

used time: 0.509(ms). Execute id is 90.

SQL> SELECT * FROM PERSON.PERSON_TYPE;

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表
5          9             防损员
6          10            保洁员

6 rows got

used time: 0.515(ms). Execute id is 97.

SQL> UPDATE PERSON.PERSON_TYPE SET NAME='保安员' WHERE PERSON_TYPEID=9;
affect rows 1

used time: 1.460(ms). Execute id is 99.
SQL> commit;
executed successfully
used time: 16.640(ms). Execute id is 100.
SQL> UPDATE PERSON.PERSON_TYPE SET NAME='收银员' WHERE PERSON_TYPEID=9;
affect rows 1

used time: 1.851(ms). Execute id is 101.
SQL> commit;
executed successfully
used time: 16.781(ms). Execute id is 102.

SQL> SELECT * FROM PERSON.PERSON_TYPE;

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表
5          9             收银员
6          10            保洁员

6 rows got

used time: 0.516(ms). Execute id is 103.

进行闪回版本查询,确定TRXID。

SQL> SELECT VERSIONS_ENDTRXID, NAME FROM PERSON.PERSON_TYPE VERSIONS BETWEEN TIMESTAMP '2019-12-01 23:48:27.983996' AND SYSDATE;

LINEID     VERSIONS_ENDTRXID    NAME    
---------- -------------------- --------
1          NULL                 采购经理
2          NULL                 采购代表
3          NULL                 销售经理
4          NULL                 销售代表
5          NULL                 收银员
6          NULL                 保洁员
7          749195               保安员

7 rows got

used time: 1.384(ms). Execute id is 104.

根据TRXID确定版本。

SQL> SELECT * FROM PERSON.PERSON_TYPE WHEN TRXID 749195;

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表
5          9             保安员
6          10            保洁员

6 rows got

used time: 1.261(ms). Execute id is 105.

第二次更新的事务ID为749195,那么第一次更新的事务ID为749194

SQL> SELECT * FROM PERSON.PERSON_TYPE WHEN TRXID 749194;

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表
5          9             防损员
6          10            保洁员

6 rows got

闪回版本查询
语法格式
< 闪回版本查询子句>::=VERSIONS BETWEEN |

参数
1.time_exp 日期表达式,一般用字符串方式表示。time_exp1表示起始时间,time_exp2表示结束时间

2. trxid 指定事务ID号,整数表示。trxid1表示起始trxid,trxid2表示结束trxid

使用说明
1.闪回版本查询支持普通表(包括加密表与压缩表)、临时表和堆表,不支持水平分区表、垂直分区表、列存储表、外部表与视图;

2.支持伪列,作为闪回版本查询的辅助信息。
伪列 说明
VERSIONS_START{TRXID|TIME} 起始TRXID或时间戳
VERSIONS_END{TRXID|TIME} 提交TRXID或时间戳。如果该值为NULL,表示行版本仍然是当前版本
VERSIONS_OPERATION 在行上的操作(I=Insert,D=Delete,U=Update)

语句功能
用户通过闪回版本查询子句,可以得到指定表过去某个时间段内,事务导致记录变化的全部记录。指定条件可以为时刻,或事务号。

例1 闪回版本查询指定时间段内,PERSON_TYPE表的记录变化

SQL> select sysdate;

LINEID     SYSDATE                    
---------- ---------------------------
1          2019-12-02 00:00:18.221877

used time: 0.662(ms). Execute id is 107.

在2019-12-02 00:00:18时刻修改数据,并提交。

SQL> UPDATE PERSON.PERSON_TYPE SET NAME='打字员' WHERE PERSON_TYPEID=9;
affect rows 1

used time: 1.758(ms). Execute id is 110.
SQL> commit;
executed successfully
used time: 16.964(ms). Execute id is 111.
SQL> 
SQL> UPDATE PERSON.PERSON_TYPE SET NAME='卫生员' WHERE PERSON_TYPEID=9;
affect rows 1

used time: 1.268(ms). Execute id is 112.
SQL> commit;
executed successfully
used time: 15.983(ms). Execute id is 113.
SQL> SELECT * FROM PERSON.PERSON_TYPE;

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表
5          9             卫生员
6          10            保洁员

6 rows got

used time: 0.669(ms). Execute id is 114.

进行闪回版本查询,获得指定时间段内变化的记录。

SQL> SELECT VERSIONS_ENDTRXID, NAME FROM PERSON.PERSON_TYPE VERSIONS BETWEEN TIMESTAMP '2019-12-02 00:00:17' AND SYSDATE;

LINEID     VERSIONS_ENDTRXID    NAME    
---------- -------------------- --------
1          NULL                 采购经理
2          NULL                 采购代表
3          NULL                 销售经理
4          NULL                 销售代表
5          NULL                 卫生员
6          NULL                 保洁员
7          749197               打字员

7 rows got

used time: 1.412(ms). Execute id is 115.

第二次更新的事务ID为749197

SQL> SELECT * FROM PERSON.PERSON_TYPE WHEN TRXID 749197;

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表
5          9             打字员
6          10            保洁员

6 rows got

used time: 1.371(ms). Execute id is 120.

第一次更新的事务ID为749196

SQL> SELECT * FROM PERSON.PERSON_TYPE WHEN TRXID 749196;

LINEID     PERSON_TYPEID NAME    
---------- ------------- --------
1          1             采购经理
2          2             采购代表
3          3             销售经理
4          4             销售代表
5          9             收银员
6          10            保洁员

6 rows got

used time: 0.585(ms). Execute id is 121.

闪回事务查询
闪回事务查询提供系统视图V$FLASHBACK_TRX_INFO供用户查看在事务级对数据库所做的更改。根据视图信息,可以确定如何还原指定事务或指定时间段内的修改。

使用说明
系统视图名为V$FLASHBACK_TRX_INFO,定义如下所示。

SQL> desc V$FLASHBACK_TRX_INFO

LINEID     NAME             TYPE$         NULLABLE
---------- ---------------- ------------- --------
1          START_TRXID      BIGINT        Y        事务中第一个DML的TRXID
2          START_TIMESTAMP  DATETIME(6)   Y        事务中第一个DML的时间戳
3          COMMIT_TRXID     BIGINT        Y        提交事务的TRXID
4          COMMIT_TIMESTAMP DATETIME(6)   Y        提交事务时的时间戳
5          LOGIN_USER       VARCHAR(256)  Y        拥有事务的用户
6          UNDO_CHANGE#     INTEGER       Y        记录修改顺序序号
7          OPERATION        CHAR(1)       Y        DML操作类型 D:删除;U:修改;I:插入;N:更新插入(专门针对CLUSTER PRIMARY KEY的插入);C:事务提交;P:预提交记录;O:default
8          TABLE_NAME       VARCHAR(256)  Y        DML 修改的表     
9          TABLE_OWNER      VARCHAR(256)  Y        DML修改表的拥有者      
10         ROW_ID           BIGINT        Y        DML修改行的ROWID
11         UNDO_SQL         VARCHAR(3900) Y        撤销DML操作的SQL语句

11 rows got

used time: 88.801(ms). Execute id is 122.

查询指定时间之后的事务信息,可为闪回查询操作提供参考

SQL> SELECT * FROM V$FLASHBACK_TRX_INFO WHERE COMMIT_TIMESTAMP > '2019-12-01 23:13:28';

LINEID     START_TRXID          START_TIMESTAMP             COMMIT_TRXID         COMMIT_TIMESTAMP            LOGIN_USER UNDO_CHANGE# OPERATION TABLE_NAME TABLE_OWNER ROW_ID               UNDO_SQL
---------- -------------------- --------------------------- -------------------- --------------------------- ---------- ------------ --------- ---------- ----------- -------------------- --------
1          749189               2019-12-01 23:13:28.000000  749190               2019-12-01 23:33:57.588000  SYSDBA     16           C         NULL       NULL        NULL                 NULL

used time: 1.437(ms). Execute id is 126.

Proudly powered by WordPress | Indrajeet by Sus Hill.