一、拓扑
在写配置之前稍微“抱怨”一下TIDB对机器的要求,如果没有云主机或者公司提供的环境做测试,想在自己笔记本上面搭建TIDB的环境还是有点吃力的。本来想在自己的笔记本环境下用sysbench对单机的mysql和tidb做一次简单的压测,然后发现压力一上来主机就扛不住了,TIDB也随之崩了。
拓扑环境:
172.1.1.101 TIDB1/PD1 monitor 中控 dm-work1
172.1.1.102 TIDB2/PD2 dm-work2
172.1.1.103 TIKV1
172.1.1.104 TIKV2
172.1.1.106 TIKV3
172.1.1.107 PD dm-master dm-monitor
上游mysql:
实例1:172.1.1.21:3306
实例2:172.1.1.21:3307
实例1现有的表:user.information/user.log,store.store_bj/store.store_sz/store.store_tj,log.messages
实例2现有的表:user.information/user.log,store.store_sh/store_sz,log.messages
同步需求
1、不合并 user 库。
将实例 1 中的 user 库同步到下游 TiDB 的 user_north 库中。
将实例 2 中的 user 库同步到下游 TiDB 的 user_east 库中。
2、将上游 store 库同步到下游 store 库中,且同步过程中不合并表。
实例 1和实例 2 中都存在 store_sz 表,且这两个 store_sz 表分别被同步到下游的 store_suzhou 表和 store_shenzhen 表中
任何情况下都不删除 store 库的任何数据。
3、log 库需要被过滤掉。
二、配置过程
在使用DM的过程中需要注意一下对上游数据库的要求,主要有版本要求、binlog配置的要求(比如binlog_format/binlog_row_image等)、上游数据库中dm用户的权限要求(REPLICATION SLAVE,REPLICATION CLIENT,RELOAD,SELECT)。
部署dm
###############
1. 中控机安装依赖包
# su - root
# yum -y install epel-release git curl sshpass
# yum -y install python2-pip
2. 中控机创建tidb用户,为tidb添加sudo权限
# useradd -m -d /home/tidb tidb
修改tidb用户密码
# passwd tidb
配置 tidb 用户sudo权限
# visudo
--添加以下内容
tidb ALL=(ALL) NOPASSWD: ALL
3. tidb用户创建ssh key
# su - tidb
$ ssh-keygen -t rsa
--提示时直接敲几次回车即可。
4. 在中控机器上下载 TiDB-Ansible
tidb用户
# su - tidb
$ cd /home/tidb/
下载最新dm版本
$ wget http://download.pingcap.org/dm-ansible-latest.tar.gz
解压
$ tar -xzvf dm-ansible-latest.tar.gz
$ mv dm-ansible-latest dm-ansible
5. 在中控机器上安装 Ansible 及其依赖
$ cd /home/tidb/tidb-ansible/
$ sudo pip install -r ./requirements.txt
验证ansible版本:
$ ansible --version
6、配置hosts.ini
[tidb@tidb01 dm-ansible]$ more hosts.ini
[servers]
172.1.1.101
172.1.1.102
172.1.1.107
[all:vars]
username = tidb
7、为集群集群创建用户配置ssh互信和下载文件
ansible-playbook -i hosts.ini create_users.yml -u root -k
ansible-playbook local_prepare.yml
$ cd /home/tidb/dm-ansible
$ ansible -i inventory.ini all -m shell -a 'whoami'
$ ansible -i inventory.ini all -m shell -a 'whoami' -b
9、配置inventory文件
##配置说明详见官方文档,主要还是dm-worker的配置,一个mysql实例对应一个dm-worker,在配置过程中主要还是注意拓扑的配置,密码记得用dmctl加密,同时最好启动dm_portal的图形配置功能,不然后续的任务配置真的很繁琐。另外提一点和配置不相干的话,之前一直以为purge-expires和purge-interval的单位是天,看了文档才知道purge-expires的单位是小时,interval的单位是秒钟~~
[tidb@tidb01 dm-ansible]$ more inventory.ini
## DM modules
[dm_master_servers]
dm_master ansible_host=172.1.1.107
[dm_worker_servers]
dm-worker1 ansible_host=172.1.1.101 source_id="mysql-replica-01" server_id=101 mysql_host=172.1.1.21 mysql_user=dm
_user mysql_password=xGlHW/69swrw67TY2hGGb0DoIFg= mysql_port=3306
dm-worker2 ansible_host=172.1.1.102 source_id="mysql-replica-02" server_id=102 mysql_host=172.1.1.21 mysql_user=dm
_user mysql_password=xGlHW/69swrw67TY2hGGb0DoIFg= mysql_port=3307
[dm_portal_servers]
dm_portal ansible_host=172.1.1.107
## Monitoring modules
[prometheus_servers]
prometheus ansible_host=172.1.1.107
[grafana_servers]
grafana ansible_host=172.1.1.107
[alertmanager_servers]
alertmanager ansible_host=172.1.1.107
## Global variables
[all:vars]
cluster_name = dm-test-cluster
ansible_user = tidb
dm_version = latest
deploy_dir = /data1/dm/delay
grafana_admin_user = "admin"
grafana_admin_password = "admin"
12、部署DM和启动
$ ansible-playbook deploy.yml
$ ansible-playbook start.yml
./dmctl --master-addr 172.1.1.107:8261进入dmctl,使用query-status查看状态,没报错就是正常了~ 另外关注一下dm-worker的信息,不要看到没报错就认为OK,显示少了dm-worker都不知道~
同步任务配置
##非常初步的配置,很多都使用了默认数据,管它呢,现在先搞清楚怎么配置table-routing/binlog event filter和黑白名单在说~ PS:不太会用简书,贴出来太丑了~估计格式都变了
[tidb@tidb01 conf]$ cat my_test.yaml
name: dm_log_user_store # global unique
task-mode: all # full/incremental/all
is-sharding: false
meta-schema: "dm_meta"
remove-meta: false
enable-heartbeat: false
target-database:
host: "172.1.1.101"
port: 4000
user: "root"
password: ""
mysql-instances:
-
source-id: "mysql-replica-01"
route-rules: ["instance-3306-user-rules","instance-3306-store-rules"]
filter-rules: ["log-filter-rules", "store-filter-rules"]
black-white-list: "log-ignored"
loader-config-name: "global"
syncer-config-name: "global"
-
source-id: "mysql-replica-02"
route-rules: ["instance-3307-user-rules","instance-3307-store-rules"]
filter-rules: ["log-filter-rules", "store-filter-rules"]
black-white-list: "log-ignored"
loader-config-name: "global"
syncer-config-name: "global"
routes:
instance-3306-user-rules:
schema-pattern: "user"
target-schema: "user_north"
instance-3307-user-rules:
schema-pattern: "user*"
target-schema: "user_east"
instance-3306-store-rules:
schema-pattern: "store"
table-pattern: "store_sz"
target-schema: "store"
target-table: "store_suzhou"
instance-3307-store-rules:
schema-pattern: "store"
table-pattern: "store_sz"
target-schema: "store"
target-table: "store_shenzhen"
filters:
log-filter-rules:
schema-pattern: "user"
table-pattern: "log"
events: ["truncate table", "drop table","delete"]
action: Ignore
store-filter-rules:
schema-pattern: "store"
events: ["truncate table", "drop table","delete","drop database"]
action: Ignore
black-white-list:
log-ignored:
ignore-dbs: ["log"]
mydumpers:
global:
mydumper-path: "./bin/mydumper"
threads: 4
chunk-filesize: 64
skip-tz-utc: true
extra-args: "-B test -T t1,t2 --no-locks"
loaders:
global:
pool-size: 16
dir: "./dumped_data"
syncers:
global:
worker-count: 16
batch: 100
三、遇到的问题
配置不当产生的问题
问题1:只能看到一个dm-worker
原因:不仔细导致,在inventory配置的时候把两个实例使用同样的dm-worker名了,修改后重新deploy解决。
问题2:启动时候各种报错,明明配置内容没问题就是启动不了
特别特别特别大的坑!!! 对齐格式的时候不要用tab,要用空格补全!要用空格补全!要用空格补全!
操作产生的问题
问题1:不能停止task,这里卡了我好久,明明有这个任务的存在就是不能停止
原因:手贱~ 多敲了一个分号!
四、思考
做完了这个测试时候就在想,在start一个任务之后使用stop停止,之后又使用start启动,会不会又来一次全量的导出导入呢?
做了测试之后发现不会重新做全量的导入和导出,我猜应该是因为有dm_log_user_store_loader_checkpoint和dm_log_user_store_syncer_checkpoint表的存在吧,这些表记录了导入导出的元数据信息。但是如果把我这两个表破drop后呢?这个时候就发现dumped_data.dm_log_user_store的那一堆sql文件创建时间被更新了,说明做了导出,并且下游数据变多了说明数据做了导入,其实这个时候下游数据和上游数据已经不一致了(测试表没创建pk)。找了一下相关资料,从原理中理解了问题的所在:
load处理单元导入ddl的流程:
获取{db}-schema-create.sql/{db}.{table}-schema.sql文件列表
根据文件名字进行库表的过滤判断black-white-list
获取创建库、表的语句
替换ddl,router-rules
执行语句
因为使用的默认参数的导出,mydumper部分没有配置~,导出的create table/create schema这些sql文件都只有create、没有drop参数~ 如果我想要实现类似oracle中impdp的table_exist_action=replace的功能,估计需要通过设置mydump的扩展参数实现,目前还没做测试~~到时候发测试结果
-