SymmetricDS文档翻译-【Chapter 3. 详细配置(Configuration)[section B]】

SymmetricDS文档翻译--【Chapter 3. 详细配置(Configuration)[section B]】

3.4 Table Triggers

SymmetricDS使用数据库触发器捕获要同步的数据。SymmetricDS的触发器定义在TRIGGER表中。SymmetricDS使用里面的一行记录生成一个数据库触发器。仅仅当一个触发器指定一个有效的Route的时候,这个触发器才会被SymmetricDS自动生成,这个ROUTE的source_node_group_id必须对应当前节点的group id。

TRIGGER表的source_table_name列可以包含通配符(“*”),因此TRIGGER表中的一个行可以定义对多个表的同步操作。系统表和任意以SymmetricDS表前缀开始的表将会被排除在外。也可以提供一个通配符符号的列表。如果有多个通配符符号,可以用逗号确定界限。一个通配符符号可以以感叹号(”!”)开始,以表明一个要排除的匹配。符号总是从左到右被匹配。如果一个表已经存在一个触发器,那张表将不会被通配符匹配中(明确定义的触发器比通配符创建的触发器有更高的优先级)。

当判断一个数据变化是否发生的时候,默认情况下,触发器将记录数据变化,即使数据以相同的值被更新一次。例如,如果一行中的一个列以这个列的值被更新了一次,一个数据变化将会被捕获。有一些全局的属性,trigger.update.capture.changed.data.only.enabled(默认是false),这允许你重载这个行为。当设置为true时,SymmetricDS将仅捕获真正改变过的数据(当一个列的新的数据不等于旧的数据的时候)。

Important

属性trigger.update.capture.changed.data.only.enabled目前仅在MySQL,DB2,SQL Server和Oracle方言中被支持。

下面的SQL语句定义了一个触发器,这个触发器将捕获表item的数据,不管是插入,更新还是删除。Trigger被分配到一个名叫“item”的channel上。

insert into SYM_TRIGGER (trigger_id, source_table_name,
          channel_id, last_update_time, create_time)
                 values ('item', 'item', 'item', current_timestamp, current_timestamp); 

Important

注意,很多的数据库允许定义同一类型的多个触发器。每一个数据库定义触发器的触发顺序是不同的。如果除了SymmetricDS安装在你表上的触发器,你还有其他的触发器,请咨询你的数据库文档确定这样的顺序是否有问题。

3.4.1 Linking Triggers

TRIGGER_ROUTER表用来定义你想要的配置的Trigger和Router的组合。Trigger和Router之间的关系是多对多,因此这个表作为一个连接表用来定义有效的Trigger-Router组合和在Trigger-Router级别的配置信息。

有三个重要的控制可以配置到一个特定的Trigger-Router组合:Enabled,Initial Loads 和Ping Back。这些参数的定义可以在TRIGGER_ROUTER表中找到。

3.4.1.1 Enable/Disable Trigger Router

每一个Trigger-Router组合可以在需要的时候被启用或者关闭。默认是开启的,但是,如果你因为某种原因,你想定义Trigger Router组合被激活的优先级,你可以设置enabled标识为0。这将导致trigger-router映射被发送到所有的节点,但是trigger-router映射将不会被认为被激活或者开启以捕获数据变化或者路由数据。

3.4.1.2. Enabling “Ping Back”

默认地,SymmetricDS避免循环数据的变化。当一个触发器触发的时候,SymmetricDS记录数据变化的始发节点的id到source_node_id列中。在route的过程中,如果route导致数据发送回数据变化的始发节点,默认地,数据不会被route。如果你希望数据能够被route回数据变化的始发节点,你可以为特定的trigger-router组合重新设置ping_back_enabled列的值。这将使router具有将数据发送回数据变化始发节点的能力。

3.4.2. Large Objects

TRIGGER表中还有两个Lob类型相关的设置:

use_stream_lobs

指定在触发触发器时,是捕获lob类型的数据,还是在提取数据时使用回调用流的方式访问源表中Lob类型的列。值为1表明通过回调读取源数据;值为0时,触发器会直接捕获Lob类型的数据。

Use_capture_lobs

给SymmetricDS一个暗示,触发器是否捕获Lob类型的数据。如果被设置为1,在触发器捕获数据和为初始负载选择数据时将尽一切努力使用Lob相关的工具提取和存储数据库中的数据。

3.4.3. External Select

 

偶尔,当一个触发器被触发的时候,你可能发现你需要捕获和保存的一部分数据出现在另一张表上。Route数据的时候,这些数据通常被用来确定数据要被route的位置。Trigger表定义包含一个可选的external_select列,这个列被用来指定被捕获的数据。一旦数据被捕获,捕获的数据在Route期间在DATA表的external_data字段中可以获取。针对这类情况,使用一个SQL Select语句,这个Select语句将返回external_select中你需要route的数据条目。Section3.6.7 “Utilizing External Select when Routing”有一个使用externalselect的例子。

3.4.4. Dead Trigger

有时候,在决定初始加载什么数据的时候可能需要额外增加触发器。这些触发器,就是Dead Trigger,它们需要被配置,但是不捕获任何的数据变化。一个“dead”触发器是一个不捕获数据变化的触发器。也就是说,一个触发器的sync_on_insert,sync_on_update和sync_on_delete属性都被设置为false。它将被包含在数据到目标节点的初始负载中。

你为什么需要一个Dead Trigger? 举个例子,一个Dead Trigger可以被加载只读的查找表(lookup table),也可以被用来加载一个需要被样例数据或默认数据填充的表。另一个用处是恢复单向同步的表的数据负载。例如,一个分销商店记录的交易信息,这些交易信息被单向同步到*数据库。如果分销商店需要从*数据库恢复所有的交易信息,这些交易信息可以作为在那个方向上的Dead Trigger建立的初始负载的一部分从*数据库发送到分销商店。

下面的SQL语句建立了一个非同步的dead Trigger,在初始负载的过程中,这个Trigger发送“corp”节点组的交易信息表的数据到“store”节点组。

insert into sym_trigger (TRIGGER_ID,SOURCE_CATALOG_NAME,
                         SOURCE_SCHEMA_NAME,SOURCE_TABLE_NAME,CHANNEL_ID,
                         SYNC_ON_UPDATE,SYNC_ON_INSERT,SYNC_ON_DELETE,
                         SYNC_ON_INCOMING_BATCH,NAME_FOR_UPDATE_TRIGGER,
                         NAME_FOR_INSERT_TRIGGER,NAME_FOR_DELETE_TRIGGER,
                         SYNC_ON_UPDATE_CONDITION,SYNC_ON_INSERT_CONDITION,
                         SYNC_ON_DELETE_CONDITION,EXTERNAL_SELECT,
                         TX_ID_EXPRESSION,EXCLUDED_COLUMN_NAMES,
                         CREATE_TIME,LAST_UPDATE_BY,LAST_UPDATE_TIME) 
              values ('SALE_TRANSACTION_DEAD',null,null, 'SALE_TRANSACTION','transaction',
                         0,0,0,0,null,null,null,null,null,null,null,null,null,
                         current_timestamp,'demo',current_timestamp); 
              
            insert into sym_router (ROUTER_ID,TARGET_CATALOG_NAME,TARGET_SCHEMA_NAME,
                         TARGET_TABLE_NAME,SOURCE_NODE_GROUP_ID,TARGET_NODE_GROUP_ID,ROUTER_TYPE,
                         ROUTER_EXPRESSION,SYNC_ON_UPDATE,SYNC_ON_INSERT,SYNC_ON_DELETE,
                         CREATE_TIME,LAST_UPDATE_BY,LAST_UPDATE_TIME) 
              values ('CORP_2_STORE',null,null,null, 'corp','store',null,null,1,1,1,
                         current_timestamp,'demo',current_timestamp); 
              
            insert into sym_trigger_router (TRIGGER_ID,ROUTER_ID,INITIAL_LOAD_ORDER,
                         INITIAL_LOAD_SELECT,CREATE_TIME,LAST_UPDATE_BY,LAST_UPDATE_TIME) 
              values ('SALE_TRANSACTION_DEAD','CORP_2_REGION',100,null,
                         current_timestamp,'demo',current_timestamp); 

3.4.5. Changing Triggers

一个Trigger的信息可以使用SQL语句更新来改变同步的表现。SymmetricDS将在每天晚上查找Trigger表的变化,也可以在任何时候运行Sync Trigger Job来进行更新。例如,将表price_changes放到price channel中,可以使用下面的语句完成:

update SYM_TRIGGER
          set channel_id = 'price',
            last_update_by = 'jsmith',
            last_update_time = current_timestamp
          where source_table_name = 'price_changes';

所有改变的配置应该在注册节点集中管理。启动时,改变的配置将被同步到所有的客户端节点。当Trigger的变化到达客户端节点的时候,Sync Trigger Job将会自动运行。

触发器的变化将会在Sync Trigger Job运行后才生效。不想等Sync Trigger Job晚上运行,你也可以通过JMX调用syncTrigger()方法或者简单的重新启动SymmetricDS服务。一个完整的Trigger变化的记录被保存在表TRIGGER_HIST中,这个在Section 4.3.5 “Sync Triggers Job”中讨论。