本文指導您如何使用MaterializedMySQL在ClickHouse與MySQL之間進行數據交換。
概述
為了強化實時數倉的能力,ClickHouse推出了MaterializedMySQL數據庫引擎,用於將MySQL服務器中的表映射到ClickHouse中,將ClickHouse服務看作MySQL副本,它讀取Binlog並執行DDL和DML請求。實現了基於MySQL Binlog機制的業務數據庫實時同步功能。
前提條件
- 數據源MySQL(RDS)集群和目標ClickHouse集群必須在同一個VPC。
- 如果MySQL(RDS)有白名單限制,需要添加Clickhouse集群地址白名單。
- MaterializeMySQL表引擎用戶必須具備MySQL庫的RELOAD、REPLICATION SLAVE、REPLICATION CLIENT以及SELECT PRIVILEGE權限。
創建數據庫
語法
CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] ENGINE = MaterializeMySQL('host:port', ['database' | database], 'user', 'password') [SETTINGS ...]
參數說明:
host:port
:鏈接的MySQL地址。database
:鏈接的MySQL數據庫。user
:鏈接的MySQL用戶。password
:鏈接的MySQL用戶密碼。
表引擎和新增字段
使用MaterializeMySQL數據庫引擎時,在目的ClickHouse集群上使用ReplacecingMergeTree新建表,同時在表上新增_sign和_version列,用於標記數據行更新和刪除狀態。
_version
:事務計數器,UInt64類型。_sign
:刪除標記,TypeInt8類型,可選值如下:- 1:行未刪除
- -1:行已刪除
支持的類型對應
MySQL | ClickHouse |
---|---|
TINY | Int8 |
SHORT | Int16 |
INT24 | Int32 |
LONG | UInt32 |
LONG | UInt64 |
FLOAT | Float32 |
DOUBLE | Float64 |
DECIMAL,NEWDECIMAL | Decimal |
DATE,NEWDATE | Date |
DATETIME,TIMESTAMP | DateTime |
DATETIME2,TIMESTAMP2 | DateTime64 |
STRING | String |
VARCHAR,VAR_STRING | String |
BLOB | String |
BIT | UInt64 |
SET | UInt64 |
ENUM | Enum16 |
JSON | String |
YEAR | String |
TIME | String |
GEOMETRY | String |
其他的MySQL數據類型將全部都轉換為字符串,同時以上的所有類型均支持可為空。
使用細則
DDL查詢
MySQL DDL查詢被轉換成相應的ClickHouse DDL查詢(ALTER, CREATE, DROP, RENAME)。如果ClickHouse不能解析某些DDL查詢,該查詢將被忽略。
數據復制
MaterializeMySQL不支持直接插入、刪除和更新查詢。但是支持如下形式:
- MySQL INSERT查詢被轉換為INSERT with _sign=1。
- MySQL DELETE查詢被轉換為INSERT with _sign=-1。
- MySQL UPDATE query被轉換成INSERT with _sign=-1和INSERT with _sign=1。
從MaterializeMySQL表進行選擇
- 如果在SELECT查詢中沒有指定_version,則使用FINAL修飾符。因此只有帶有MAX(_version)的行被選中。
- 如果在SELECT查詢中沒有指定_sign,則默認使用WHERE _sign=1。因此,被刪除的行不包含在結果集中。
指數轉換
- MySQL主鍵和索引子句通過ClickHouse表中的元組轉換為順序。
- ClickHouse只有一個物理順序,由order by子句決定。要創建一個新的物理秩序,請使用物化視圖。
說明
- 帶有
_sign=-1
的行不會從表中物理刪除。 - MaterializeMySQL引擎不支持級聯
UPDATE/DELETE
查詢。 - 復制很容易被破壞。
- 禁止對數據庫和表進行手動操作。
- MaterializeMySQL受optimize_on_insert設置的影響,當MySQL服務器中的一個表發生變化時,數據被合並到MaterializeMySQL數據庫中相應的表中。
雲數據庫ClickHouse自主研發功能
說明 exclude_tables和include_tables兩個配置項不能同時使用。
同步表名單配置
如果配置了同步表名單,則只有表名單內的表會被同步。通過include_tables參數指定字符串參數類型,匹配正則表達式。配置參考如下。
Creating a Database CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] ENGINE = MaterializeMySQL('host:port', ['database' | database], 'user', 'password') SETTINGS include_tables ='a,b,c...';
參數值字符串和支持解析規則:
- *:替換除/包括空字符串以外的任意數量的任何字符。
- ?:替換任意單個字符。
- {N..M} :替換N到M范圍內的任何數字,包括兩個邊界。
排除表名單配置
排除同步表名單內的表不進行同步。通過exclude_tables參數指定字符串參數類型,匹配正則表達式。配置參考如下。
Creating a Database CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] ENGINE = MaterializeMySQL('host:port', ['database' | database], 'user', 'password') SETTINGS exclude_tables ='a,b,c...';
參數值字符串和支持解析規則:
- *:替換除/包括空字符串以外的任意數量的任何字符。
- ?:替換任意單個字符。
- {N..M} :替換N到M范圍內的任何數字,包括兩個邊界。
修改同步配置
MaterializedMySQL引擎所有的配置項都可以進行修改,且動態生效。語法如下:
ALTER database db_name MODIFY SETTING exclude_tables|include_tables = '*';
跳過同步錯誤
MaterializedMySQL引擎新增了skip_error_count參數,可以通過設置參數的值來確定跳過同步過程中的錯誤數。參數值含義如下:
- -9223372036854775808~-1:跳過所有錯誤。
- 0:不跳過任何一個錯誤。
- 1~9223372036854775807:跳過對應數字的錯誤。
語法如下:
Creating a Database CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] ENGINE = MaterializeMySQL('host:port', ['database' | database], 'user', 'password') SETTINGS skip_error_count = -1;
跳過不支持的表結構
MaterializedMySQL引擎新增了skip_nonsupport參數,用來自動忽略MaterializedMySQL引擎目前無法同步的MySQL表。
參數值含義如下:
說明 目前無法同步的表主要有兩種:無主鍵表和create as select語法創建的表。
- 0:表示關閉該參數,不跳過不支持的表結構。
- 1:表示開啟該參數,跳過不支持的表結構。
語法如下:
Creating a Database CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] ENGINE = MaterializeMySQL('host:port', ['database' | database], 'user', 'password') SETTINGS skip_nonsupport = 1;
注意 該參數優先級高於skip_error_count參數,如果設置了skip_nonsupport,skip_error_count不再生效。
示例1
創建同步庫
CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] ENGINE = MaterializeMySQL('host:port', ['database' | database], 'user', 'password') SETTINGS include_tables ='a,b,c...', exclude_tables ='e,f,g...',
示例2
在MySQL中查詢
mysql> CREATE DATABASE db; mysql> CREATE TABLE db.test (a INT PRIMARY KEY, b INT); mysql> INSERT INTO db.test VALUES (1, 11), (2, 22); mysql> DELETE FROM db.test WHERE a=1; mysql> ALTER TABLE db.test ADD COLUMN c VARCHAR(16); mysql> UPDATE db.test SET c='Wow!', b=222; mysql> SELECT * FROM test;
+---+------+------+ | a | b | c | +---+------+------+ | 2 | 222 | Wow! | +---+------+------+
在ClickHouse與MySQL服務器交換數據
創建數據庫和表:
CREATE DATABASE mysql ENGINE = MaterializeMySQL('localhost:3306', 'db', 'user', '***'); SHOW TABLES FROM mysql;
┌─name─┐
│ test │ └────┘
插入數據:
SELECT * FROM mysql.test;
┌─a─┬──b-─┐ │ 1 │ 11 │ │ 2 │ 22 │ └──-┴────┘
刪除數據后,添加列並更新:
SELECT * FROM mysql.test;
┌─a─┬───b─┬─c────┐ │ 2 │ 222 │ Wow! │ └─-─┴───-─┴─-────┘