使用 Canal 向 OceanBase 数据库增量迁移数据 
===================================================



您可以使用 Canal 向 OceanBase 数据库增量迁移数据。Canal 是一个开源的 MySQL 数据库 Binlog 的增量订阅和消费组件，基于 MySQL 数据库的增量日志解析，可以用于数据同步。关于 Canal 的详细信息，参考 Canal 的 [GitHub 仓库](https://github.com/alibaba/canal)。

Canal 的工作流程如下：

![](https://intranetproxy.alipay.com/skylark/lark/0/2021/png/21256616/1623931214127-4c63dbb8-445d-40c4-b4b8-82ef27c004ee.png)

其中 Canal Client Adapter 支持 Logger、Rdb、HBase、Kudu 和 Elasticsearch。本文档使用 Rdb。其他可选的配置如下：

* Canal Server 支持单机模式和 HA 模式。

  

* Canal Connector 支持 TCP 和 MQ 两种类型。MQ 目前支持 Kafka、RabbitMQ 和 RocketMQ。

  

* Rdb 版的 Client Adapter 支持按表同步和整库同步。

  




操作步骤 
-------------------------

按照以下步骤向 OceanBase 数据库增量迁移数据：

1. 部署 Canal。

   部署 Canal Server 参考 [Canal 快速上手](https://github.com/alibaba/canal/wiki/QuickStart) 文档。
   

2. 同步 Canal Client Adapter Rdb。

   同步 Canal Client Adapter Rdb 参考 [同步 Rdb](https://github.com/alibaba/canal/wiki/Sync-RDB) 文档。
   **说明**

   

   OceanBase 数据库兼容 MySQL 协议，您可以直接按照 MySQL 配置 Adapter。
   




示例 
-----------------------

以 TCP 类型的 Connetors 为例，按照以下步骤向 OceanBase 数据库增量迁移数据：

1. 将 `plugin` 目录下的 RDB 和 TCP Connector 对应的 JAR 包添加到 `lib` 目录下。

   

2. 修改启动配置文件` conf/application.yml`。

   ```yaml
   # spring 服务相关配置
   server:
     port: 8081
   spring:
     jackson:
       date-format: 'yyyy-MM-dd HH:mm:ss'
       time-zone: GMT+8
       default-property-inclusion: non_null
   
   # canal 相关配置
   canal.conf:
     # 指定 Canal Connector 类型
     mode: tcp
     flatMessage: true
     # 集群模式下的 zookeeper 地址，如果配置了单机地址则以单机为准
     zookeeperHosts:
     syncBatchSize: 1000
     retries: 0
     timeout:
     accessKey:
     secretKey:
     # Canal Connector 数据消费配置
     consumerProperties:
       canal.tcp.server.host: 127.0.0.1:11111
       canal.tcp.zookeeper.hosts:
       canal.tcp.batch.size: 500
       canal.tcp.username:
       canal.tcp.password:
     # 适配器列表
     canalAdapters:
       - instance: example   # canal instance 名
         groups:
           - groupId: g1     # 适配器分组 ID
             outerAdapters:  # 分组内适配器列表
               - name: rdb   # 指定适配器为 RDB 类型
                 key: mysql1 # 适配器标识 key，与表映射配置中 outerAdapterKey 对应
                 properties:
                   jdbc.driverClassName: com.mysql.jdbc.Driver
                   jdbc.url: jdbc:mysql://127.0.0.1:2883/ob_db?useUnicode=true
                   jdbc.username: username@tenant_name#deploy_name
                   jdbc.password: password
   ```

   

   其中，`outerAdapters` 中的 `rdb` 数据源表示目标数据库。OceanBase 数据库用户名的格式详情，参考 [通过 MySQL 客户端连接 OceanBase 租户](../../7.developer-guide-1/2.connect-to-the-oceanbase-database/1.connect-to-an-oceanbase-tenant-by-using-a-mysql-client.md)。
   

3. 配置表映射。

   Adapter 服务在启动时，会加载对应类型 Adapter 的配置目录（本例的配置目录为 `conf/rdb/`）下的所有配置文件。

   表映射有两种配置形式：按表映射同步和整库同步。

   **按表映射同步：** 

   ```yaml
   dataSourceKey: defaultDS        # 源数据源的 Key, 对应上面配置的 srcDataSources 中的值
   destination: example            # Cannal Server 的 Instance 名
   outerAdapterKey: mysql1         # Adapter Key, 对应上面配置 outAdapters 中的 Key
   concurrent: true                # 是否按主键 Hash 并行同步, 并行同步的表必须保证主键不会更改及主键不能为其他同步表的外键
   dbMapping:
     database: mysql_db            # 源数据源的 Database/Schema
     table: mysql_tbl              # 源数据源表名
     targetTable: ob_db.ob_tbl     # 目标数据源的库名.表名
     targetPk:                     # 主键映射
       id: id                      # 如果是复合主键可以换行映射多个
     mapAll: true                 # 是否整表映射, 要求源表和目标表字段名一模一样 (如果 targetColumns 也配置了映射,则以 targetColumns 配置为准)
   #  targetColumns:                # 字段映射, 格式: 目标表字段: 源表字段, 如果字段名一样源表字段名可不填
   #    id:
   #    name:
   #    role_id:
   #    c_time:
   #    test1: 
   ```

   

   其中，`targetTable` 格式为"库名.表名"，实际测试中只能直接使用表名，此处需要进一步确认。

   **按整库同步：** 

   ```yaml
   dataSourceKey: defaultDS
   destination: example
   outerAdapterKey: mysql1
   concurrent: true
   dbMapping:
     mirrorDb: true
     database: mysql_db
   ```

   

4. 执行以下命令，启动 RDB。

   ```bash
   bin/startup.sh
   ```

   

   服务日志位于 `logs` 目录。
   



