
# 基于GDS的跨集群互联互通
#### 功能描述
在"基于Foreign Table的数据处理"的基础上，通过GDS进行数据中转，实现多个集群之间的数据同步。
#### 使用场景
- 将数据从一个集群同步到另外一个集群，支持全量数据同步、过滤条件数据同步。
- 目前互联互通仅支持以下使用方式，除以下语句外，其他类型的语法均不支持。
  - INSERT INTO 内表 SELECT ... FROM 互联互通外表1 \[WHERE\];
  
  - INSERT INTO 互联互通表 SELECT \* FROM 内表1 \[JOIN 内表2 \| WHERE\];
  
  - SELECT ... FROM 互联互通表;
   
 
#### 注意事项
- 创建的互联互通外表与其对应的远端表的列名和类型名要完全一致，且远端表的类型为行存表或列存表。
- 执行同步语句时，要确保本地集群、远端集群的待同步表已存在。
- 使用期间，两个集群的状态应为Normal。
- 两个集群都需要具备基于GDS的跨集群互联互通功能。
- 建议两端集群的数据库编码保持一致，否则可能出现报错或者收到的数据为乱码。
- 两端集群所指定的数据库兼容类型要保持一致，否则可能报错或乱码。
- 确保执行数据同步的相关用户对待同步表有相应的访问权限。
- 互联互通外表只能用于跨集群数据同步场景，其他场景可能出错或无效。
- 互联互通外表不支持复杂的列上表达式，不支持复杂语法，包括join、排序、游标、with、集合等。
- 不下推的SQL语句无法使用本特性进行数据同步，否则会报错。
- 不支持EXPLAIN计划、逻辑集群。
- 不支持除了simple模式以外的JDBC模式。
- 当本地集群同步数据到远端集群时，只支持内表查询。
- Foreign Server的syncsrv选项指定的GDS不支持SSL模式。
- 数据同步结束时只校验数据行数，不校验数据内容。
- 业务最大并发数不能大于GDS启动参数-t的一半，同时也不能大于max_active_statements，否则可能会导致业务超时失败。
- 互联互通在扩容期间因数据存在跨group重分布，数据同步性能会暂时下降，扩容结束后性能恢复。
 
#### 使用前准备
- 配置两个集群互连。
- 规划部署GDS服务器，确保所有的GDS服务器可以和上面配置的两个集群所有节点网络连通，即GDS服务器的安全组入方向要放通对应的GDS端口（例如5000）和DWS端口（默认8000）。部署GDS请参考[安装配置和启动GDS](https://support.huaweicloud.com/migration-dws/dws_15_0023.html)。
  ![](https://support.huaweicloud.com/migration-dws/public_sys-resources/note_3.0-zh-cn.png)
  启动GDS时，可指定任意目录作为数据中转的目录，例如/opt，启动命令示例如下：
  ```
  /opt/gds/bin/gds -d /opt -p 192.168.0.2:5000 -H 192.168.0.1/24 -l /opt/gds/bin/gds_log.txt -D -t 2
  ```
  
 
#### 操作步骤
假设远端集群的待同步表名称是tbl_remote，用于数据同步的用户是user_remote，该用户须对表tbl_remote有访问权限；假设本地集群的待同步表名称是tbl_local。
1. 创建server。
   
   ```
   CREATE SERVER server_remote FOREIGN DATA WRAPPER GC_FDW OPTIONS(
     address '192.168.178.207:8000',
     dbname 'db_remote',
     username 'user_remote',
     password 'xxxxxxxx',
     syncsrv 'gsfs://192.168.178.129:5000|gsfs://192.168.178.129:5000'
   );
   ```
   - server_remote为server名称，供互联互通外表使用。
   
   - address为远端集群CN的IP地址和端口，仅允许填写一个地址。
   
   - dbname为远端集群的数据库名。
   
   - username为连接远端集群使用的用户名，注意该用户不能为系统管理员。
   
   - password为连接远端集群使用的用户名的密码。
   
   - syncsrv为GDS Server的IP地址和端口，如果有多个地址使用\|分割，与GDS外表的location类似。
     ![](https://support.huaweicloud.com/migration-dws/public_sys-resources/note_3.0-zh-cn.png)
     DWS会对syncsrv所设置的GDS地址进行网络连接测试：
     - 只能判断本地执行集群与GDS的网络情况，无法判断远端集群与GDS的网络情况，需要注意报错提示。
     
     - 在移除不可用GDS后，从中选择不会导致业务hang的、数目适当的GDS进行数据同步。
       
   
   
   
   
2. 创建互联互通外表。 
   ```
   CREATE FOREIGN TABLE ft_tbl(
     col_1    type_name,
     col_2    type_name,
     …
   ) SERVER server_remote OPTIONS (
     schema_name 'schema_remote',
     table_name 'tbl_remote',
     encoding 'utf8'
   );
   ```
   - schema_name为远端集群表所属schema，如果该option缺省，则schema_name预设为该外表所在的schema。
   
   - table_name为远端集群表名，如果该option缺省，则table_name预设为该外表的表名。
   
   - encoding为远端集群的编码，如果该option缺省，则编码使用本地集群数据库的默认编码。
   
   
   ![](https://support.huaweicloud.com/migration-dws/public_sys-resources/note_3.0-zh-cn.png)
   - 选项schema_name、table_name大小写敏感，必须与远端schema、table的名字大小写保持一致。
   
   - 互联互通外表的列不允许带任何约束。
   
   - 互联互通外表的列名、列类型必须与远端集群的表tbl_remote的列名和列类型完全一致。
   
   - SERVER须设置为[步骤1]中新建的server，必须包含syncsrv属性。
    
   
   
3. 使用互联互通外表进行数据同步。 
   - 本地集群是目标集群时，发起数据同步业务： 全列全量数据同步：
     ```
     INSERT INTO tbl_local SELECT * FROM ft_tbl;
     ```
     全列过滤条件数据同步：
     ```
     INSERT INTO tbl_local SELECT * FROM ft_tbl WHERE col_2 = XX;
     ```
     部分列全量数据同步：
     ```
     INSERT INTO tbl_local (col_1) SELECT col_1 FROM ft_tbl;
     ```
     部分列过滤条件数据同步：
     ```
     INSERT INTO tbl_local (col_1) SELECT col_1 FROM ft_tbl WHERE col_2 = XX;
     ```
     
   
   - 本地集群是源集群时，发起数据同步业务： 单表数据同步：
     ```
     INSERT INTO ft_tbl SELECT * FROM tbl_local;
     ```
     join结果集数据同步：
     ```
     INSERT INTO ft_tbl SELECT * FROM tbl_local1 join tbl_local2 ON XXX;
     ```
     
   
   
   ![](https://support.huaweicloud.com/migration-dws/public_sys-resources/note_3.0-zh-cn.png)
   - 如遇到报错连接失败，请检查server的信息确认两个集群是否已经相互连通。
   
   - 如遇到报错GDS连接失败，请检查syncsrv指定的GDS Server是否都已经启动，且与两个集群所有节点可以网络连通。
   
   - 如遇到报错表不存在，请检查外表的option信息是否正确。
   
   - 如遇到报错列不存在，请检查外表的列名是否与源表一致。
   
   - 如遇到报错列重复定义，请检查是否相应列名超长，若超长建议使用AS别名精简。
   
   - 如遇到报错无法解析列类型，请检查语句中是否有列上表达式。
   
   - 如遇到报错列信息不匹配，请检查外表的列信息是否与远端集群对应表的列信息一致。
   
   - 如遇到报错语法不支持，请检查是否使用了Join、distinct、排序等复杂用法。
   
   - 如遇到乱码，请检查两端数据库的实际编码是否一致。
   
   - 当本地集群是源集群时，存在极小的概率出现数据成功同步到远端集群，但是本地集群返回执行失败的情况，针对这种情况建议校验同步数据记录数。
   
   - 当本地集群是源集群时，通过事务块、子事务等控制的数据同步，需要总事务提交后才能查询到数据同步结果。
    
   
   
4. 删除互联互通外表。 
   ```
   DROP FOREIGN TABLE ft_tbl;
   ```
   
   
 
