TiDB 作為 MySQL Slave 實現實時數據同步


由於 TiDB 本身兼容絕大多數的 MySQL 語法,所以對於絕大多數業務來說,最安全的切換數據庫方式就是將 TiDB 作為現有數據庫的從庫接在主 MySQL 庫的后方,這樣對業務方實現完全沒有侵入性下使用 TiDB 對現有的業務進行備份,應對未來數據量或者並發量增長帶來的單點故障風險,如需上線 TiDB,也只需要簡單的將業務的主 MySQL 地址指向 TiDB 即可。

下面我們詳細介紹了如何將 MySQL 的數據遷移到 TiDB,並將 TiDB 作為 MySQL 的 Slave 進行數據同步。

這里我們假定 MySQL 以及 TiDB 服務信息如下:

+------------------+-------------+----------------------------------------+
| Name             | Address     | Port   |   User    | Password          |
+------------------+-------------+----------------------------------------+
| MySQL            |  127.0.0.1  | 3306   |   root    |                   |
| TiDB             |  127.0.0.1  | 4000   |   root    |                   |
+------------------+-------------+--------+-----------+-------------------+

使用 checker 進行 Schema 檢查

在遷移之前,我們可以使用 TiDB 的 checker 工具,checker 是我們開發的一個小工具,用於檢測目標 MySQL 庫中的表的表結構是否支持無縫的遷移到 TiDB,TiDB 支持絕大多數的 MySQL 常用的原生數據類型,所以大多數情況 checker 的返回應該是 ok。如果 check 某個 table schema 失敗,表明 TiDB 當前並不支持,我們不能對該 table 里面的數據進行遷移。 checker 包含在 TiDB 工具集里面,我們可以直接下載。

下載 TiDB 工具集

Linux

# 下載 tool 壓縮包
wget http://download.pingcap.org/tidb-tools-latest-linux-amd64.tar.gz
wget http://download.pingcap.org/tidb-tools-latest-linux-amd64.sha256


# 檢查文件完整性,返回 ok 則正確
sha256sum -c tidb-tools-latest-linux-amd64.sha256

# 解開壓縮包
tar -xzf tidb-tools-latest-linux-amd64.tar.gz
cd tidb-tools-latest-linux-amd64

使用 checker 檢查的一個示范

  • 在 MySQL 的 test database 里面創建幾張表,並插入數據:
USE test;
CREATE TABLE t1 (id INT, age INT, PRIMARY KEY(id)) ENGINE=InnoDB;
CREATE TABLE t2 (id INT, name VARCHAR(256), PRIMARY KEY(id)) ENGINE=InnoDB;


INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
INSERT INTO t2 VALUES (1, "a"), (2, "b"), (3, "c");
  • 使用 checker 檢查 test database 里面所有的 table
./bin/checker -host 127.0.0.1 -port 3306 -user root test
2016/10/27 13:11:49 checker.go:48: [info] Checking database test
2016/10/27 13:11:49 main.go:37: [info] Database DSN: root:@tcp(127.0.0.1:3306)/test?charset=utf8
2016/10/27 13:11:49 checker.go:63: [info] Checking table t1
2016/10/27 13:11:49 checker.go:69: [info] Check table t1 succ
2016/10/27 13:11:49 checker.go:63: [info] Checking table t2
2016/10/27 13:11:49 checker.go:69: [info] Check table t2 succ
  • 使用 checker 檢查 test database 里面某一個 table

這里,假設我們只需要遷移 table t1 。

./bin/checker -host 127.0.0.1 -port 3306 -user root test t1
2016/10/27 13:13:56 checker.go:48: [info] Checking database test
2016/10/27 13:13:56 main.go:37: [info] Database DSN: root:@tcp(127.0.0.1:3306)/test?charset=utf8
2016/10/27 13:13:56 checker.go:63: [info] Checking table t1
2016/10/27 13:13:56 checker.go:69: [info] Check table t1 succ
Check database succ!

一個無法遷移的 table 例子

我們在 MySQL 里面創建如下表:

CREATE TABLE t_error (
  c timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

使用 checker 進行檢查,會報錯,表明我們沒法遷移 t_error 這張表。

./bin/checker -host 127.0.0.1 -port 3306 -user root test t_error
2016/10/27 13:19:28 checker.go:48: [info] Checking database test
2016/10/27 13:19:28 main.go:37: [info] Database DSN: root:@tcp(127.0.0.1:3306)/test?charset=utf8
2016/10/27 13:19:28 checker.go:63: [info] Checking table t_error
2016/10/27 13:19:28 checker.go:67: [error] Check table t_error failed with err: line 1 column 56 near ") ON UPDATE CURRENT_TIMESTAMP(3)
) ENGINE=InnoDB DEFAULT CHARSET=latin1"
github.com/pingcap/tidb/parser/yy_parser.go:111:
github.com/pingcap/tidb/parser/yy_parser.go:124:
/home/jenkins/workspace/WORKFLOW_TOOLS_BUILDING/go/src/github.com/pingcap/tidb-tools/checker/checker.go:122:  parse CREATE TABLE `t_error` (
  `c` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 error
/home/jenkins/workspace/WORKFLOW_TOOLS_BUILDING/go/src/github.com/pingcap/tidb-tools/checker/checker.go:114:
2016/10/27 13:19:28 main.go:68: [error] Check database test with 1 errors and 0 warnings.

使用 mydumper / myloader 全量導入數據

我們使用 mydumper 從 MySQL 導出數據,然后用 myloader 將其導入到 TiDB 里面。

注意,雖然我們也支持使用 MySQL 官方的 mysqldump 工具來進行數據的遷移工作,但相比於 mydumper / myloader ,性能會慢很多,對於大量數據的遷移會花費很多時間,這里我們並不推薦。

mydumper / myloader 是一個更強大的數據遷移工具,具體可以參考 https://github.com/maxbube/mydumper 。

下載 Binary

Linux

# 下載 mydumper 壓縮包
wget http://download.pingcap.org/mydumper-linux-amd64.tar.gz
wget http://download.pingcap.org/mydumper-linux-amd64.sha256

# 檢查文件完整性,返回 ok 則正確
sha256sum -c mydumper-linux-amd64.sha256

# 解開壓縮包
tar -xzf mydumper-linux-amd64.tar.gz
cd mydumper-linux-amd64

從 MySQL 導出數據

我們使用 mydumper 從 MySQL 導出數據,如下:

./bin/mydumper -h 127.0.0.1 -P 3306 -u root -t 16 -F 128 -B test -T t1,t2 -o ./var/test

上面,我們使用 -B test 表明是對 test 這個 database 操作,然后用 -T t1,t2表明只導出 t1 , t2 兩張表。

-t 16 表明使用 16 個線程去導出數據。 -F 128 是將實際的 table 切分成多大的 chunk,這里就是 128MB 一個 chunk。

注意:在阿里雲一些需要 super privilege 的雲上面, mydumper 需要加上 --no-locks 參數,否則會提示沒有權限操作。

給 TiDB 導入數據

我們使用 myloader 將之前導出的數據導入到 TiDB。

./bin/myloader -h 127.0.0.1 -P 4000 -u root -t 16 -q 1 -d ./var/test

這里 -q 1 表明每個事務包含多少個 query,默認是 1000,我們這里使用 1 就可以了。

導入成功之后,我們可以用 MySQL 官方客戶端進入 TiDB,查看:

mysql -h127.0.0.1 -P4000 -uroot

mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1             |
| t2             |
+----------------+

mysql> select * from t1;
+----+------+
| id | age  |
+----+------+
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+

mysql> select * from t2;
+----+------+
| id | name |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 | c    |
+----+------+

使用 syncer 增量導入數據實現數據和 MySQL 實時同步

上面我們介紹了如何使用 mydumper / myloader 將 MySQL 的數據全量導入到 TiDB,但如果后續 MySQL 的數據有更新,我們仍然希望快速導入,使用全量的方式就不合適了。

TiDB 提供 syncer 工具能方便的將 MySQL 的數據增量的導入到 TiDB 里面。

syncer 也屬於 TiDB 工具集,如何獲取可以參考。

假設我們之前已經使用 mydumper / myloader 導入了 t1 和 t2 兩張表的一些數據,現在我們希望這兩張表的任何更新,都是實時的同步到 TiDB 上面。

MySQL 開啟 binlog

在使用 syncer 之前,我們必須保證:

  • MySQL 開啟 binlog 功能,參考 Setting the Replication Master Configuration
  • Binlog 格式必須使用 row format,這也是 MySQL 5.7 之后推薦的 binlog 格式,可以使用如下語句打開:

bash SET GLOBAL binlog_format = ROW;

獲取同步 position

我們通過 show master status 得到當前 binlog 的 position, syncer 的初始同步位置就是從這個地方開始。

show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |     1280 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

我們將 position 相關的信息保存到一個 syncer.meta 文件里面,用於 syncer 的同步:

# cat syncer.meta
binlog-name = "mysql-bin.000003"
binlog-pos = 1280

注意: syncer.meta 只需要第一次使用的時候配置,后續 syncer 同步新的 binlog 之后會自動將其更新到最新的 position。

啟動 syncer

syncer 的配置文件 config.toml :

log-level = "info"

server-id = 101

# meta 文件地址
meta = "./syncer.meta"
worker-count = 1
batch = 1

pprof-addr = ":10081"

[from]
host = "127.0.0.1"
user = "root"
password = ""
port = 3306

[to]
host = "127.0.0.1"
user = "root"
password = ""
port = 4000

啟動 syncer :

./bin/syncer -config config.toml

2016/10/27 15:22:01 binlogsyncer.go:226: [info] begin to sync binlog from position (mysql-bin.000003, 1280)
2016/10/27 15:22:01 binlogsyncer.go:130: [info] register slave for master server 127.0.0.1:3306
2016/10/27 15:22:01 binlogsyncer.go:552: [info] rotate to (mysql-bin.000003, 1280)
2016/10/27 15:22:01 syncer.go:549: [info] rotate binlog to (mysql-bin.000003, 1280)

在 MySQL 插入新的數據

INSERT INTO t1 VALUES (4, 4), (5, 5);

登錄到 TiDB 查看:

mysql -h127.0.0.1 -P4000 -uroot -p
mysql> select * from t1;
+----+------+
| id | age  |
+----+------+
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
|  4 |    4 |
|  5 |    5 |
+----+------+

syncer 每隔 30s 會輸出當前的同步統計,如下

2016/10/27 15:22:31 syncer.go:668: [info] [syncer]total events = 1, insert = 1, update = 0, delete = 0, total tps = 0, recent tps = 0, binlog name = mysql-bin.000003, binlog pos = 1280.
2016/10/27 15:23:01 syncer.go:668: [info] [syncer]total events = 2, insert = 2, update = 0, delete = 0, total tps = 0, recent tps = 0, binlog name = mysql-bin.000003, binlog pos = 1538.

可以看到,使用 syncer ,我們就能自動的將 MySQL 的更新同步到 TiDB。

 

轉自:http://www.zuimoban.com/jiaocheng/mysql/11005.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM