Symmetric 同步Oracle数据库

# 基本系统安装就不多说了

- 主机信息
1. dr001 192.168.3.30
2. dr003 192.168.3.32

- 源用的是当前最新的CentOS 7.7 更新到了最新

- 还是准备下PL SQL或者navicat等工具吧

- Oracle比MySQL特殊,需要commit提交下

# Java环境配置

- 之前安装的sdfs的rpm包是打包了jre的环境的,但是我们还是自己装个jdk吧
/usr/share/sdfs/bin/jre/bin/java

yum install java-1.8.0-openjdk-devel

- 设置JAVA_HOME,选择jdk1.8做为默认的JDK
vim /root/.bashrc
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64
export JRE_HOME=$JAVA_HOME/jre
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH


# 安装Oracle 就先用11g吧

- 监听开启
默认安装完就是开启的
lsnrctl start                    //开启监听程序

lsnrctl status

- db.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl

使用jdbc连接oracle时url有三种格式
格式一: Oracle JDBC Thin using an SID(最常用的方式):
jdbc:oracle:thin:@host:port:SID
Example: jdbc:oracle:thin:@localhost:1521:orcl

jdbc:表示采用jdbc方式连接数据库
oracle:表示连接的是oracle数据库
thin:表示连接时采用thin模式(oracle中有两中模式 还有一种是DataSource方式)
jdbc:oralce:thin:是一个jni方式的命名@表示地址1521和orcl表示端口和数据库名
@192.168.3.98:1521:orcl整个是一快
也就是说是这样[jdbc]:[oracle]:[thin]:[@192.168.3.98:1521:orcl]

- 创建用户和表空间(主备站点都需要创建)

主站:
su - oracle
mkdir -p /home/oracle/data

备站:
su - oracle
mkdir -p /data

/*第1步:创建临时表空间  */
主站:
create temporary tablespace SIMON_TEMP  
tempfile 'C:\simon\user_temp.dbf'
size 50m  
autoextend on  
next 50m maxsize 20480m  
extent management local;  

备站:
create temporary tablespace SIMON_TEMP  
tempfile 'C:\simon\user_temp.dbf'
size 50m  
autoextend on  
next 50m maxsize 20480m  
extent management local;  

/*第2步:创建数据表空间  */
主站:
create tablespace SIMON_DATA  
logging  
datafile 'C:\simon\user_data.dbf'
size 50m  
autoextend on  
next 50m maxsize 20480m  
extent management local;  

备站:
create tablespace SIMON_DATA  
logging  
datafile '/data/user_data.dbf'
size 50m  
autoextend on  
next 50m maxsize 20480m  
extent management local;  

/*第3步:创建用户并指定表空间  */
create user simon identified by "123456"
default tablespace SIMON_DATA  
temporary tablespace SIMON_TEMP;

/*第4步:给用户授予权限  */
grant connect,resource,dba to simon;

- 创建表
select tablespace_name,sum(bytes)/1024/1024 from dba_data_files group by tablespace_name;

-- 登录验证
[oracle@oracle11g02 ~]$ sqlplus

SQL*Plus: Release 11.2.0.1.0 Production on Sat Oct 27 13:17:07 2018

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Enter user-name: simon
Enter password:

-- 表操作

// 创建表
CREATE TABLE STUDENT
(
 STUID VARCHAR2(255) NOT NULL,
 STUNAME VARCHAR2(255) NOT NULL
);

// 查看当前用户的表
select table_name from user_tables;

INSERT INTO STUDENT VALUES ('100', 'zhang3');
INSERT INTO STUDENT VALUES ('101', 'li4');
INSERT INTO STUDENT VALUES ('102', 'LiLi');

select * from STUDENT;


- 在ORACLE建表时的SQL中表名用引号括起来了,则以后对此表的所有操作都必须把此表名用引号括起来,否则报“表不存在”。

-- 所以上面在创建表的时候,表名不要双引号搞起来


# navicat是神器啊

- navicat的SQL脚本默认存放路径
C:\Users\Administrator\Documents\Navicat\Oracle\servers\dr001\SIMON
SELECT "SIMON"."item".*, ROWID "NAVICAT_ROWID" FROM "SIMON"."item";
SELECT "SIMON"."item".* FROM "SIMON"."item";
SELECT * FROM ALL_TABLES WHERE TABLE_NAME = 'item';


# 部署symmetric-server-3.7.25

- 与之前mysql的略有不同,symmetric放到了/opt目录下

重点:修改示例程序engines目录下properties文件中的数据库配置,properties文件名自定义即可,有几个配置文件,symmetric就会读几个配置。

- (主备都可执行,看下面具体数据同步情况)创建测试数据
C:\symmetric-server\bin\dbimport --engine symserver --format XML C:\symmetric-server\samples\create_sample.xml

select table_name from user_tables;

- (仅主节点执行)初始化顶级节点sun的系统表结构:创建创建一些SymmetricDS需要的系统表 -> 在执行命令之后会在数据库nbp中创建多张以sym_ 开头的SymmetricDS的系统表
重点:所有子节点在服务启动后,会根据顶级节点自动创建。
C:\symmetric-server\bin\symadmin --engine symserver create-sym-tables

select table_name from user_tables;

- (不建议直接运行脚本,下面一步步动作分解来)插入核心配置和测试数据这个脚本不要直接运行 要拆开来看
C:\symmetric-server\bin\dbimport --engine symserver C:\symmetric-server\samplesinsert_sample.sql

- 核心配置
------------------------------------------------------------------------------
-- Sample Symmetric Configuration 这里插入的核心配置信息,需要一条条来搞
------------------------------------------------------------------------------

重点:核心配置是在主节点上搞的才有效,所以下面是sunserver上操作的

- 创建创建一些SymmetricDS需要的系统表 -> 在执行命令之后会在数据库nbp中创建多张以sym_ 开头的SymmetricDS的系统表
C:\symmetric-server\bin\symadmin --engine symserver create-sym-tables


--- 下面这些如果看之前不爽的话,可以强制清空掉
delete from sym_trigger_router;
delete from sym_trigger;
delete from sym_node_host;


delete from sym_router;
delete from sym_channel where channel_id in ('sale_transaction', 'item');
delete from sym_node_group_link;
delete from sym_node_group;
delete from sym_node_host;
delete from sym_node_identity;
delete from sym_node_security;
delete from sym_node;

重点:下面都是在主站操作
(1)配置节点组。 这里的sunserver和sunclient就是主备站点配置的group.id
注意: 配置信息都是根据group_id来配置的
insert into sym_node_group (node_group_id, description) values ('sunserver', 'Oracle数据主站');
insert into sym_node_group (node_group_id, description) values ('sunclient', 'Oracle数据备站1');
select * from sym_node_group;

(2)配置各节点组间的数据同步模式。有push(推)和wait(等待||拉)两种,由data_event_action制定,其中w(wait for pull)代表拉,p代表推(push)
注意: 配置信息都是根据group_id来配置的`
1. 数据从sunclient推送到sunserver
insert into sym_node_group_link (source_node_group_id, target_node_group_id, data_event_action) values ('sunclient', 'sunserver', 'P');
2. 数据从sunserver发起拉取操作,拉取对象是sunclient
insert into sym_node_group_link (source_node_group_id, target_node_group_id, data_event_action) values ('sunserver', 'sunclient', 'W');


insert into sym_node_group_link (source_node_group_id, target_node_group_id, data_event_action) values ('sunserver', 'sunclient', 'P');
insert into sym_node_group_link (source_node_group_id, target_node_group_id, data_event_action) values ('sunclient', 'sunserver', 'W');


上面两句其实最后效果是一致的,确定数据走向是 sunclient -> sunserver




(3)配置各个节点信息。这里只要配置sunserver的节点信息就可,其他子节点sunclient在注册节点后,会自动生成系统表并且插入数据
1. 先创建node,这里指定node_id是000,node_group_id在config.properties中已经指定是sunserver,external_id也指定为000
insert into sym_node (node_id, node_group_id, external_id, sync_enabled) values ('000', 'sunserver', '000', 1);

insert into sym_node (node_id, node_group_id, external_id, sync_enabled) values ('001', 'sunclient', '001', 1);

重点:sync_url后续会被自动写成'http://localhost:8080/sync/symserver' -> config.properties中指定即使在主站也要这么写:sync.url=http://192.168.3.83:8080/sync/symserver
config.properties中的配置是会直接写入到sym_node表中的,并且会覆盖之

2. node的登录验证信息创建,应该就是设置密码为123456吧
insert into sym_node_security (node_id,node_password,registration_enabled,registration_time,initial_load_enabled,initial_load_time,initial_load_id,initial_load_create_by,rev_initial_load_enabled,rev_initial_load_time,rev_initial_load_id,rev_initial_load_create_by,created_at_node_id)
values
('000','123456',0,current_timestamp,0,current_timestamp,null,null,0,null,null,null,'000');







INSERT INTO sym_node_security (
    node_id,
    node_password,
    registration_enabled,
    registration_time,
    initial_load_enabled,
    initial_load_time,
    initial_load_id,
    initial_load_create_by,
    rev_initial_load_enabled,
    rev_initial_load_time,
    rev_initial_load_id,
    rev_initial_load_create_by,
    created_at_node_id
)
VALUES
    (
        '000',
        '123456',
        0,
        CURRENT_TIMESTAMP,
        0,
        CURRENT_TIMESTAMP,
        NULL,
        NULL,
        0,
        NULL,
        NULL,
        NULL,
        '000'
    );



oracle和mysql有所不同,需要commit一下提交生效下

3. 这个就是创建node_id的记录,上面就是000(注意表是不一样的哦)
insert into sym_node_identity values ('000');





(4)配置数据通道表。 重点:有外键关联的表,一定要定义在同一通道中,才能进行关联同步。
channel_id:这个只是channel的一个名字而已 这条语句相当于就是创建了一个通道
insert into sym_channel (channel_id, processing_order, max_batch_size, enabled, description) values('bus_info', 1, 100000, 1, '信息同步通道');



INSERT INTO sym_channel (
    channel_id,
    processing_order,
    max_batch_size,
    enabled,
    description
)
VALUES
    (
        'bus_info',
        1,
        100000,
        1,
        '信息同步通道'
    );




(5)定义触发器。在这里定义需要同步库中的哪些表,注意有外键关联的表,通道值要相同。sym_trigger中的excluded_column_names字段,可以设置不想同步的表字段,这里并没有体现。
1. trigger001和trigger002是触发器的名字,用来后面跟路由做关联
insert into sym_trigger (trigger_id,source_table_name,channel_id,last_update_time,create_time) values('trigger001','item_selling_price','bus_info',current_timestamp,current_timestamp);

INSERT INTO sym_trigger (
    trigger_id,
    source_table_name,
    channel_id,
    last_update_time,
    create_time
)
VALUES
    (
        't1',
        'C1',
        'bus_info',
        CURRENT_TIMESTAMP,
        CURRENT_TIMESTAMP
    );





insert into sym_trigger (trigger_id,source_table_name,channel_id,last_update_time,create_time) values('trigger002','item','bus_info',current_timestamp,current_timestamp);

INSERT INTO sym_trigger (
    trigger_id,
    source_table_name,
    channel_id,
    RELOAD_CHANNEL_ID,
    last_update_time,
    create_time
)
VALUES
    (
        't2',
        'C2',
        'bus_info',
        'bus_info',
        CURRENT_TIMESTAMP,
        CURRENT_TIMESTAMP
    );
    
    


(6)配置数据路由。配置数据同步时数据的走向,即从哪个节点向哪个节点同步。其中ROUTER_TYPE='column'就是指明由需同步的表中某列的值来决定数据流向,具体的条件则来表达式决定:ROUTER_EXPRESSION='org_code=:EXTERNAL_ID' 默认ROUTER_TYPE='default'就好。
1. ROUTER_TYPE决定了数据的流向,默认就用"default"啦
insert into sym_router (router_id,source_node_group_id,target_node_group_id,router_type,create_time,last_update_time)
values('client_2_server','sunclient','sunserver','default',current_timestamp,current_timestamp);

INSERT INTO sym_router (
    router_id,
    source_node_group_id,
    target_node_group_id,
    router_type,
    create_time,
    last_update_time
)
VALUES
    (
        'StoC',
        'sunserver',
        'sunclient',
        'default',
        CURRENT_TIMESTAMP,
        CURRENT_TIMESTAMP
    );
    
    

(7)最后建立触发器与路由的关联。SymmetricDS中定义的触发器只有被路由关联后,SymmetricDS才会为这个表自动生成相应的触发器。
insert into sym_trigger_router (trigger_id,router_id,initial_load_order,last_update_time,create_time) values('trigger001','client_2_server', 200, current_timestamp, current_timestamp);




INSERT INTO sym_trigger_router (
    trigger_id,
    router_id,
    initial_load_order,
    last_update_time,
    create_time
)
VALUES
    (
        'C',
        'StoC',
        3,
        CURRENT_TIMESTAMP,
        CURRENT_TIMESTAMP
    );








insert into sym_trigger_router (trigger_id,router_id,initial_load_order,last_update_time,create_time) values('trigger002','client_2_server', 200, current_timestamp, current_timestamp);

INSERT INTO sym_trigger_router (
    trigger_id,
    router_id,
    initial_load_order,
    last_update_time,
    create_time
)
VALUES
    (
        'trigger002',
        'client_2_server',
        3,
        CURRENT_TIMESTAMP,
        CURRENT_TIMESTAMP
    );




------------------------------------------------------------------------------
-- Sample Data 这部分就是插入测试数据,后面自己也可以加入一些,问题不大
------------------------------------------------------------------------------

重点:基于上面配置,数据流向是sunclient往sunserver同步数据数据,所以下面测试数据的插入在sunclient上完成







                                                                    sunclient上做
                                                                    
                                                                    
                                                                    


(1)创建数据表结构
chmod +x C:\symmetric-server\bin\*
/opt/symmetric-client1/bin\dbimport --engine symclient1 --format XML /opt/symmetric-client1/samples/create_sample.xml

(2)直接在nbp数据库里面插入测试数据,Oracle比MySQL特殊,需要commit提交下
insert into item (item_id, name) values (11000001, 'Wang');
insert into item_selling_price (item_id, store_id, price, cost) values (11000001, '001',0.20, 0.10);
insert into item_selling_price (item_id, store_id, price, cost) values (11000001, '002',0.30, 0.20);
insert into sale_transaction (tran_id, store_id, workstation, day, seq) values (900, '001', '3', '2012-12-01', 90);
insert into sale_return_line_item (tran_id, item_id, price, quantity, returned_quantity) values (900, 11000001, 0.20, 1, 0);


# 启动服务

- 主节点操作

(1)执行注册节点命令
C:\symmetric-server\bin\symadmin --engine symserver open-registration sunclient 001

......
......
Opened registration for node group of 'sunclient' external ID of '001'

1. engine是本地config里面定义的名字,一个config对应一个engine,而sunclient是192.168.3.192(client端)的group.id
2. 命令行里面指定的001就是客户端config中配置的external ID

(2)执行注入节点命令(只是主节点本地的reload,此时客户端不一定要处于开启状态)
C:\symmetric-server\bin\symadmin --engine symserver reload-node 001


- 启动服务

1. 先启动子节点
C:\symmetric-server\bin\sym --engine symclient1 --port 7070

2. 再启动父节点
C:\symmetric-server\bin\sym --engine symserver --port 8080


# 关于配置修改的说明
- 1. 重点:如果上来配置就有问题的话,则最好把sunclient节点先取消注册,然后重新注册下节点,然后注入下

- 2. 如果是下面这些语句忘了加了,目前是通过reload-node来搞定的,后面如果动态修改的话,能不能动态生效
insert into sym_trigger_router (trigger_id,router_id,initial_load_order,last_update_time,create_time) values('trigger001','client_2_server', 200, current_timestamp, current_timestamp);
insert into sym_trigger_router (trigger_id,router_id,initial_load_order,last_update_time,create_time) values('trigger002','client_2_server', 200, current_timestamp, current_timestamp);

还有目前数据是要有修改才能够去自动发起同步,能不能有手动同步操作


# trigger规则修改测试(目前用删除规则再增加规则来模拟)
- sunserver:删除触发器和路由关联
delete from sym_trigger_router;
select * from sym_trigger_router;

- sunclient:修改数据(这步如果后面不reload的话,是不会同步数据的)
SELECT "SIMON"."item".* FROM "SIMON"."item";
update "SIMON"."item" set "name"='aaabbb' where "item_id"='10000';
commit;

- sunserver:重新加入触发器和路由关联
insert into sym_trigger_router (trigger_id,router_id,initial_load_order,last_update_time,create_time) values('trigger001','client_2_server', 200, current_timestamp, current_timestamp);
insert into sym_trigger_router (trigger_id,router_id,initial_load_order,last_update_time,create_time) values('trigger002','client_2_server', 200, current_timestamp, current_timestamp);
commit;

[symserver] - ConfigurationChangedDataRouter - About to sync the trigger001 trigger because a change was detected by the config data router
[symserver] - ConfigurationChangedDataRouter - About to sync the trigger002 trigger because a change was detected by the config data router

- sunclient:加入数据测试数据,此时新增的数据会同步,但是原来老的数据不会同步
insert into "SIMON"."item" ("item_id", "name") values (11000003, 'test003');
commit;

- 两边重启下相应的group节点即可让表的所有数据重新同步一次 -> 在触发器和路由关联前的改变数据也能够被同步过去了
C:\symmetric-server\bin\symadmin --engine symserver reload-node 000
C:\symmetric-server\bin\symadmin --engine symclient1 reload-node 001


# 表结构增加字段测试(官方文档)
https://www.symmetricds.org/docs/how-to/sync-schema-ddl-changes

官网的说明:
Add Column
Be careful defining a column with a "default" value or "not null". Some database systems will update each row of the table with the default value,
causing all the data to be captured. Either avoid using a "default" or temporarily disable the data capture system while adding the column.
A new column that is not nullable can create problems for clients that haven't received the schema update.
During data synchronization, if a node receives data that is missing a new column, the value for that column is loaded as null.
If the new column is not nullable, the database will reject it and the batch will be in error. Leave new columns nullable until the schema changes roll out completely.

解读:增加字段的时候要注意"default"和"not null"不能有,否则就要特殊处理

- 基本SQL操作
SELECT "SIMON"."item".* FROM "SIMON"."item";

-- 查看表结构
desc "SIMON"."item";

-- 增加字段
ALTER TABLE "SIMON"."item" add (port varchar2(255) default '9000' not null);

-- 删除字段
ALTER TABLE "SIMON"."item" drop column port;

- 这个可以成功
ALTER TABLE "SIMON"."item" add (port varchar2(255));

- 重点:这个也可以成功(这个就是和MySQL的最大区别所在)
ALTER TABLE "SIMON"."item" add (port varchar2(255) default '9000' not null);

- 索引同步
C:\symmetric-server\bin\symadmin --engine symclient1 sync-triggers

- send-schema即可 甚至都不需要去重启sunserver服务
C:\symmetric-server\bin\symadmin send-schema --node 000 item

C:\symmetric-server\bin\symadmin send-schema --node 001 C

重启下sunserver当然是更充分的条件
C:\symmetric-server\bin\symadmin --engine symserver reload-node 000

drop table item_selling_price;
drop table item;


# 表结构删除字段测试
ALTER TABLE "SIMON"."item" drop column port;
select * from sym_data where event_type='S';  -> 这里不会有任何改变

C:\symmetric-server\bin\symadmin --engine symclient1 sync-triggers
......
[symclient1] - MariaDBSymmetricDialect - Creating SYM_ON_I_FOR_TRGGR002_SNCLNT trigger for nbp.item
[symclient1] - MariaDBSymmetricDialect - Creating SYM_ON_U_FOR_TRGGR002_SNCLNT trigger for nbp.item
[symclient1] - MariaDBSymmetricDialect - Creating SYM_ON_D_FOR_TRGGR002_SNCLNT trigger for nbp.item
......

sym_data没反应

sym_trigger_hist有反应 -> select * from sym_trigger_hist;

INSERT INTO ""."" ("TRIGGER_HIST_ID", "TRIGGER_ID", "SOURCE_TABLE_NAME", "SOURCE_CATALOG_NAME", "SOURCE_SCHEMA_NAME",
"NAME_FOR_UPDATE_TRIGGER", "NAME_FOR_INSERT_TRIGGER", "NAME_FOR_DELETE_TRIGGER", "TABLE_HASH", "TRIGGER_ROW_HASH",
"TRIGGER_TEMPLATE_HASH", "COLUMN_NAMES", "PK_COLUMN_NAMES", "LAST_TRIGGER_BUILD_REASON", "ERROR_MESSAGE", "CREATE_TIME", "INACTIVE_TIME")
VALUES ('39', 'trigger002', 'item', NULL, NULL, 'SYM_ON_U_FOR_TRGGR002_SNCLNT', 'SYM_ON_I_FOR_TRGGR002_SNCLNT',
'SYM_ON_D_FOR_TRGGR002_SNCLNT', '264429217', '372516982', '-2118530966', :"COLUMN_NAMES", :"PK_COLUMN_NAMES", 'S',
 NULL, TO_TIMESTAMP(' 2019-11-13 16:39:11:992000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), NULL);

LAST_TRIGGER_BUILD_REASON: S
CREATE_TIME: 2019-11-13 16:39:11:992000

- 索引同步
C:\symmetric-server\bin\symadmin --engine symclient1 sync-triggers

- send-schema即可 甚至都不需要去重启sunserver服务
C:\symmetric-server\bin\symadmin send-schema --node 000 item

重启下sunserver当然是更充分的条件
C:\symmetric-server\bin\symadmin --engine symserver reload-node 000


# 测试新表创建的同步

- 表创建之后,肯定是不会自动同步创建过去的,这个时候需要send-schema一下,这样表会被同步过去,但是表里面的数据的同步还是要后面添加trigger

select table_name from user_tables;

CREATE TABLE test002
(
 STUID VARCHAR2(255) NOT NULL,
 STUNAME VARCHAR2(255) NOT NULL
);

SELECT * FROM ALL_TABLES WHERE TABLE_NAME like 'item';


- 定义触发器。在这里定义需要同步库中的哪些表,注意有外键关联的表,通道值要相同。sym_trigger中的excluded_column_names字段,可以设置不想同步的表字段,这里并没有体现。
1. trigger003是触发器的名字,用来后面跟路由做关联
insert into sym_trigger (trigger_id,source_table_name,channel_id,last_update_time,create_time) values('trigger003','test001','bus_info',current_timestamp,current_timestamp);

2. 建立触发器与路由的关联。SymmetricDS中定义的触发器只有被路由关联后,SymmetricDS才会为这个表自动生成相应的触发器。
insert into sym_trigger_router (trigger_id,router_id,initial_load_order,last_update_time,create_time) values('trigger003','client_2_server', 200, current_timestamp, current_timestamp);

- send-schema即可 甚至都不需要去重启sunserver服务
C:\symmetric-server\bin\symadmin send-schema --node 001 C1

貌似上面send-schema不行,需要reload-node一下,表才会被创建出来
C:\symmetric-server\bin\symadmin --engine symclient reload-node 001




create table C1 as
select rownum as id,
               to_char(sysdate + rownum/24/3600, 'yyyy-mm-dd hh24:mi:ss') as inc_datetime,
               trunc(dbms_random.value(0, 100)) as random_id,
               dbms_random.string('x', 20) random_string
          from dual
        connect by level <= 1000;







insert into "C1"
  (ID, INC_DATETIME,RANDOM_ID,RANDOM_STRING)
  select rownum as id,
         to_char(sysdate + rownum / 24 / 3600, 'yyyy-mm-dd hh24:mi:ss') as inc_datetime,
         trunc(dbms_random.value(0, 100)) as random_id,
         dbms_random.string('x', 20) random_string
    from dual
  connect by level <= 1000;





































猜你喜欢

转载自www.cnblogs.com/2689116388-com/p/12912256.html
今日推荐