基於Canal實現MySQL 8.0 資料庫資料同步

2023-04-23 18:01:35

前言

伺服器說明

主機名稱 作業系統 說明
192.168.11.82 Ubuntu 22.04 主庫所在伺服器
192.168.11.28 Oracle Linux Server 8.7 從庫所在伺服器

版本說明

MySQL版本:MySQL_8.0.32
Canal版本:Canal_1.1.7
           //我的canal安裝部署在192.168.11.82上,當然你也可以部署在其它的伺服器上
Java版本:1.8.0.362

設定MySQL8.0資料庫

修改MySQL組態檔

1、Ubuntu系統下MySQL組態檔位置
cd /etc/mysql/mysql.conf.d
vi mysqld.cnf
2、CentOS系統下MySQL組態檔位置
vi /etc/my.cnf
3、新增如下設定,開啟MySQL binlog功能
# 服務編號, 與其它節點不衝突即可
server_id=1
log_bin=binlog
binlog_format=ROW

Canal簡介

關於canal簡介,這裡就不再闡述,具體可以參看官方檔案介紹,地址如下:

https://github.com/alibaba/canal/wiki/簡介

主庫伺服器操作

啟動MySQL8.0資料庫

systemctl start mysql  或者
systemctl start mysqld.service
Ubuntu 使用前者

建立賬號密碼

mysql> CREATE USER canal IDENTIFIED BY 'canal';  
mysql> GRANT SELECT, SHOW VIEW, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
mysql> FLUSH PRIVILEGES;

canal資料同步伺服器操作

建立canal資料夾

cd /usr/local
mkdir canal
cd canal
mkdir canal-package canal-adapter canal-deployer

安裝canal deployer和canal adapter

官網下載地址

https://github.com/alibaba/canal/releases/tag/canal-1.1.7-alpha-2


只需要下載標紅框的兩個檔案即可。複製到canal-package資料夾下。
解壓

tar -zxvf canal.adapter-1.1.7-SNAPSHOT.tar.gz -C /usr/local/canal/canal-adapter
tar -zxvf canal.deployer-1.1.7-SNAPSHOT.tar.gz -C /usr/local/canal/canal-deployer

設定和啟動canal-deployer

設定canal-deployer

由於此次同步為MySQL資料庫間的資料同步,所以只需修改 instance.properties 即可。

cd /usr/local/canal/canal-deployer/conf/example
vi instance.properties

修改內容如下:

# 修改說明
第一個框:主庫所在伺服器IP
第二個框:主庫資料庫賬號密碼
第三個框:規則如下:
instance.properties中同步資料表預設為同步資料庫下所有的表資訊,具體設定如圖第三個框:
# 若需要同步某幾張表,可以參考如下設定:
# 同步某資料庫test1下的user表,test2資料庫下的所有表,所有庫下所有表資料
canal.instance.filter.regex=test1.user,test2\\..*,.*\\..*

啟動canal-deployer

cd /usr/local/canal/canal-deployer/bin
./startup.sh

檢視紀錄檔確定是否啟動成功

cd /usr/local/canal/canal-deployer/logs/example
cat example.log

我遇到的幾個錯誤情況,僅供參考:
canal-deployer啟動之後,如果在 logs 資料夾下沒有 example 檔案,參考如下情況說明:
1、檢視 /usr/local/canal/canal-deployer/bin 資料夾下,是否存在.pid的檔案。
2、檢視logs資料夾下的canal資料夾下的canal_stdout.log檔案,命令如下:

cat /usr/local/canal/canal-deployer/logs/canal/canal_stdout.log

若出現如下資訊:

解決方案:(在此強烈建議系統中只安裝jdk8或者jdk11,切不可採用jenv管理jdk,安裝多個版本)

cd /usr/local/canal/canal-deployer/bin
./stop.sh
vi startup.sh
# 刪除報錯資訊包含的引數(該錯誤資訊可能會出現多次,出現哪個刪除哪個即可)
./startup.sh

重新啟動:

cd /usr/local/canal/canal-deployer/bin
./startup.sh

直到出現以下資訊:

# 開啟紀錄檔檔案
cat /usr/local/canal/canal-deployer/logs/example/example.log
# 出現以下資訊說明canal-deployer啟動成功
 [destination = example , address = /192.168.11.82:3306 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> find start position successfully, EntryPosition[included=false,journalName=binlog.000040,position=65224673,serverId=1,gtid=,timestamp=1682062760000] cost : 1331ms , the next step is binlog dump

設定canal-adapter

修改組態檔

cd /usr/local/canal/canal-adapter/conf
vi application.yml
server:
  port: 8081
spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    default-property-inclusion: non_null

canal.conf:
  mode: tcp #tcp kafka rocketMQ rabbitMQ
  flatMessage: true
  zookeeperHosts:
  syncBatchSize: 1000
  retries: -1
  timeout:
  accessKey:
  secretKey:
  consumerProperties:
    # canal tcp consumer
    # 修改位置1:Canal-deployer所在主機IP
    canal.tcp.server.host: 127.0.0.1:11111
    canal.tcp.zookeeper.hosts:
    canal.tcp.batch.size: 500
    canal.tcp.username:
    canal.tcp.password:
    # kafka consumer
    kafka.bootstrap.servers: 127.0.0.1:9092
    kafka.enable.auto.commit: false
    kafka.auto.commit.interval.ms: 1000
    kafka.auto.offset.reset: latest
    kafka.request.timeout.ms: 40000
    kafka.session.timeout.ms: 30000
    kafka.isolation.level: read_committed
    kafka.max.poll.records: 1000
    # rocketMQ consumer
    rocketmq.namespace:
    rocketmq.namesrv.addr: 127.0.0.1:9876
    rocketmq.batch.size: 1000
    rocketmq.enable.message.trace: false
    rocketmq.customized.trace.topic:
    rocketmq.access.channel:
    rocketmq.subscribe.filter:
    # rabbitMQ consumer
    rabbitmq.host:
    rabbitmq.virtual.host:
    rabbitmq.username:
    rabbitmq.password:
    rabbitmq.resource.ownerId:
# 修改位置:新增源庫設定資訊,此處為同步同庫下所有表資訊
  srcDataSources:
    defaultDS:
      url: jdbc:mysql://192.168.11.82:3306/mynet?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
      username: ymliu
      password: ymliu2023

  canalAdapters:
  - instance: example # canal instance Name or mq topic name
    groups:
    - groupId: g1
      outerAdapters:
      - name: logger
      - name: rdb
        key: mysql1
        properties:
          jdbc.driverClassName: com.mysql.jdbc.Driver
          jdbc.url: jdbc:mysql://192.168.11.28:3306/mynet?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
          jdbc.username: ymliu
          jdbc.password: ymliu2023
          druid.stat.enable: false
          druid.stat.slowSqlMillis: 1000
#      - name: rdb
#        key: oracle1
#        properties:
#          jdbc.driverClassName: oracle.jdbc.OracleDriver
#          jdbc.url: jdbc:oracle:thin:@localhost:49161:XE
#          jdbc.username: mytest
#          jdbc.password: m121212
#      - name: rdb
#        key: postgres1
#        properties:
#          jdbc.driverClassName: org.postgresql.Driver
#          jdbc.url: jdbc:postgresql://localhost:5432/postgres
#          jdbc.username: postgres
#          jdbc.password: 121212
#          threads: 1
#          commitSize: 3000
#      - name: hbase
#        properties:
#          hbase.zookeeper.quorum: 127.0.0.1
#          hbase.zookeeper.property.clientPort: 2181
#          zookeeper.znode.parent: /hbase
#      - name: es
#        hosts: 127.0.0.1:9300 # 127.0.0.1:9200 for rest mode
#        properties:
#          mode: transport # or rest
#          # security.auth: test:123456 #  only used for rest mode
#          cluster.name: elasticsearch
#      - name: kudu
#        key: kudu
#        properties:
#          kudu.master.address: 127.0.0.1 # ',' split multi address
#      - name: phoenix
#        key: phoenix
#        properties:
#          jdbc.driverClassName: org.apache.phoenix.jdbc.PhoenixDriver
#          jdbc.url: jdbc:phoenix:127.0.0.1:2181:/hbase/db
#          jdbc.username:
#          jdbc.password:

修改canal-adapter/conf/rdb資料夾下的yml檔案

cd /usr/local/canal/canal-adapter/conf/rdb
vi mytest_user.yml
同步資料庫下的某張表,例如同步mytest資料庫下的user表,操作如下:
dataSourceKey: defaultDS        # 源資料來源的key, 對應上面設定的srcDataSources中的值
destination: example            # cannal的instance或者MQ的topic
groupId: g1                     # 對應MQ模式下的groupId, 只會同步對應groupId的資料
outerAdapterKey: mysql1         # adapter key, 對應上面設定outAdapters中的key
concurrent: true                # 是否按主鍵hash並行同步, 並行同步的表必須保證主鍵不會更改及主鍵不能為其他同步表的外來鍵!
dbMapping:
  database: test                # 源資料來源的database/schema
  table: user                   # 源資料來源表名
  targetTable: test.user        # 目標資料來源的庫名.表名
  targetPk:                     # 主鍵對映
    id: id                      # 如果是複合主鍵可以換行對映多個
  mapAll: true                  # 是否整表對映, 要求源表和目標表欄位名一模一樣 (如果targetColumns也設定了對映, 則以targetColumns設定為準)
  #targetColumns:               # 欄位對映, 格式: 目標表欄位: 源表欄位, 如果欄位名一樣源表欄位名可不填
  #  id:
  #  name:
  #  role_id:
  #  c_time:
  #  test1: 
同步資料庫下所有表資料,例如:同步mytest資料庫下所有表資料,操作如下:
dataSourceKey: defaultDS
destination: example
groupId: g1
outerAdapterKey: mysql1
concurrent: true
dbMapping:
  mirrorDb: true
  database: test          # 該資料庫名稱修改為你的資料庫名稱

啟動canal-adapter

cd /usr/local/canal/canal-adapter/bin
./startup.sh

出現錯誤,排查方式同canal-deployer
檢視紀錄檔資訊

cd /usr/local/canal/canal-adapter/logs/adapter
cat adapter.log

補充說明:

1、只有canal-adapter成功啟動並正確連線canal-deployer後,canal-deployer才會讀取binlog資訊。/usr/local/canal/canal-deployer/conf/example 資料夾下才會出現meta.dat檔案。
2、canal-adapter啟動以後會出現127.0.0.1:3306/canal_manage連線失敗資訊,該資訊是因為我們沒有安裝啟動前端頁面所致,可以忽略,不影響資料同步。
3、以上所有內容均為自己實操結果。