写点什么

两次数据库迁移记录(mysql→tidb,tidb→tidb)

  • 2024-03-08
    北京
  • 本文字数:5716 字

    阅读完需:约 19 分钟

作者: tidb 菜鸟一只原文来源:https://tidb.net/blog/0c92fe80

背景

见上次写的 sysbench 压测文章,专栏 - 通过 Sysbench 在低配置低数据基础上分别压测 MySQL 和 TiDB,实际结果 TiDB 出乎我的想象。 | TiDB 社区


我们有个项目,最开始时提供的是一个主从 mysql 数据库,两台 16C64G 的主机(还有个预发环境也是 mysql 主从,2 个 4C8G 主机),后来经过上面压测之后,切换成了三台 16C64G 的云主机,混合部署的 tidb 集群,压测记录见上面的文章,但是,虽然混合部署的 tidb 集群性能相比原来的主从 mysql 数据库性能要好很多,但是压测效果还是很差,后来对机器上给的号称高性能磁盘的通过 fio 进行 io 测试后发现,还是 io 性能不过关,于是要求另换了 3 台带 ssd 的物理机来安装 tidb 集群。


备注:fio 性能测试命令示例

磁盘顺序读

fio --bs=8k --ioengine=libaio --direct=1 --rw=read --numjobs=16 --iodepth=256 --time_based --runtime=60 --group_reporting --size=10G --name=fio-seqr-vdb --filename=/data/fio_seqw

磁盘随机读

fio --bs=8k --ioengine=libaio --direct=1 --rw=randread --numjobs=16 --iodepth=256 --time_based --runtime=60 --group_reporting --size=10G --name=fio-randr-vdb --filename=/data/fio_seqr

磁盘顺序写

fio --bs=8k --ioengine=libaio --direct=1 --rw=write --numjobs=16 --iodepth=256 --time_based --runtime=60 --group_reporting --size=10G --name=fio-seqw-vdb --filename=/data/fio_randr

磁盘随机写

fio --bs=8k --ioengine=libaio --direct=1 --rw=randwrite --numjobs=16 --iodepth=256 --time_based --runtime=60 --group_reporting --size=10G --name=fio-randw-vdb --filename=/data/fio_randw

磁盘随机读写

fio --bs=8k --ioengine=libaio --direct=1 --rw=randrw --rwmixread=70 --numjobs=16 --iodepth=256 --time_based --runtime=60 --group_reporting --size=10G --name=fio-randrw-vdb --filename=/data/fio_randrw


另:如果已安装 tiup,可以通过 tiup cluster check –enable-disk 命令来针对目标磁盘的 io 进行预检查。


以下是带 ssd 的物理机部署的集群和云主机部署集群的 sysbench 压测对比记录



最终导致了两次数据库的迁移,下面记录下两次迁移的执行过程。

迁移过程

1. 首次迁移过程(MySQL 主从到 tidb)

1.1 选择迁移方式

由于我们的迁移是从 mysql 主从到 tidb,且数据量较小,选择了通过 dm 进行迁移。

1.2 安装和部署 dm

1.2.1 安装 dm 超级简单,通过 tiup 一句命令即可完成,


tiup install dm dmctl


1.2.2 部署 dm 则只需要先生成一个 dm_topology.yaml


global:  user: "tidb"  ssh_port: 22  deploy_dir: "/data/dm-deploy"  data_dir: "/data/dm-data"
server_configs: master: log-level: info worker: log-level: info
master_servers: - host: 10.11.141.160 name: master1 ssh_port: 22 port: 8261 config: log-level: infoworker_servers: - host: 10.11.141.160 ssh_port: 22 port: 8262 config: log-level: infomonitoring_servers: - host: 10.11.141.160 ssh_port: 22 port: 9090grafana_servers: - host: 10.11.141.160 port: 3000alertmanager_servers: - host: 10.11.141.160 ssh_port: 22 web_port: 9093

复制代码


然后通过 tiup 安装即可


tiup dm deploy dm-smk v6.5.5 ./dm_topology.yaml –user tidb -p


1.2.3 创建上游数据库 source


生成 mysql-141.yaml


source-id: "mysql-141"
from: host: "10.11.141.141" user: "root" password: "+ZKZYcFtNc1lwtlRaR6UoEAnq7ffgs1EyIiQcCzOqhcUuYkfNKI+Lhu80yU=" port: 3306
复制代码


注:数据库密码可以通过 tiup dmctl –encrypt “ 您的密码 ” 来生成,避免明文保存


执行命令创建 source,tiup dmctl –master-addr=10.11.141.160:8261 operate-source create mysql-141.yaml


1.2.4 创建同步任务


生成 smkdm-task.yaml


name: smkdmtask-mode: all
target-database: host: "10.12.141.117" port: 3806 user: "root" password: "X/ZGqrGswhoadLgZAMyGKEBz7mtamUz9TwgrczXGOZzTT6U="
mysql-instances: - source-id: "mysql-141" block-allow-list: "ba-rule1"
block-allow-list: ba-rule1: do-dbs: ["citizencard-biz","citizencarddb","citizencard-seata"]
复制代码


执行命令创建同步任务,tiup dmctl –master-addr 10.11.141.160:8261 start-task smkdm-task.yaml


查询任务状态,tiup dmctl –master-addr 10.11.141.160:8261 query-status smkdm


1.2.5 确定同步已实时同步,可以通过 sync_diff_inspector 进行数据比对


生成 sync.toml


# Diff Configuration.
######################### Global config #########################
# 检查数据的线程数量,上下游数据库的连接数会略大于该值check-thread-count = 12
# 如果开启,若表存在不一致,则输出用于修复的 SQL 语句。export-fix-sql = true
# 只对比表结构而不对比数据check-struct-only = false
# 如果开启,会跳过校验上游或下游不存在的表。skip-non-existing-table = true
######################### Datasource config #########################[data-sources][data-sources.mysql1] # mysql1 是该数据库实例唯一标识的自定义 id,用于下面 task.source-instances/task.target-instance 中 host = "10.11.141.141" port = 3306 user = "root" password = "111222333" # 设置连接上游数据库的密码,可为明文或 Base64 编码。
#(可选)使用映射规则来匹配上游多个分表,其中 rule1 和 rule2 在下面 Routes 配置栏中定义 #route-rules = ["rule1", "rule2"] #route-rules = ["rule2"][data-sources.tidb0] host = "10.12.141.117" port = 3806 user = "root" password = "222333444" # 设置连接下游数据库的密码,可为明文或 Base64 编码。
#(可选)使用 TLS 连接 TiDB # security.ca-path = ".../ca.crt" # security.cert-path = ".../cert.crt" # security.key-path = ".../key.crt"
#(可选)使用 TiDB 的 snapshot 功能,如果开启的话会使用历史数据进行对比 # snapshot = "386902609362944000" # 当 snapshot 设置为 "auto" 时,使用 TiCDC 在上下游的同步时间点,具体参考 <https://github.com/pingcap/tidb-tools/issues/663> # snapshot = "auto"
########################### Routes ############################ 如果需要对比大量的不同库名或者表名的表的数据,或者用于校验上游多个分表与下游总表的数据,可以通过 table-rule 来设置映射关系# 可以只配置 schema 或者 table 的映射关系,也可以都配置[routes][routes.rule1] # rule1 是该配置的唯一标识的自定义 id,用于上面 data-sources.route-rules 中schema-pattern = "citizencard*" # 匹配数据源的库名,支持通配符 "*" 和 "?"table-pattern = "*" # 匹配数据源的表名,支持通配符 "*" 和 "?"target-schema = "citizencard*" # 目标库名target-table = "*" # 目标表名
[routes.rule2]schema-pattern = "citizencard*" # 匹配数据源的库名,支持通配符 "*" 和 "?"table-pattern = "*" # 匹配数据源的表名,支持通配符 "*" 和 "?"target-schema = "citizencard*" # 目标库名target-table = "*" # 目标表名
######################### Task config ########################## 配置需要对比的*目标数据库*中的表[task] # output-dir 会保存如下信息 # 1 sql:检查出错误后生成的修复 SQL 文件,并且一个 chunk 对应一个文件 # 2 log:sync-diff.log 保存日志信息 # 3 summary:summary.txt 保存总结 # 4 checkpoint:a dir 保存断点续传信息 output-dir = "./output"
# 上游数据库,内容是 data-sources 声明的唯一标识 id source-instances = ["mysql1"]
# 下游数据库,内容是 data-sources 声明的唯一标识 id target-instance = "tidb0"
# 需要比对的下游数据库的表,每个表需要包含数据库名和表名,两者由 `.` 隔开 # 使用 ? 来匹配任意一个字符;使用 * 来匹配任意;详细匹配规则参考 golang regexp pkg: https://github.com/google/re2/wiki/Syntax target-check-tables = ["citizencard*.*"]
#(可选)对部分表的额外配置,其中 config1 在下面 Table config 配置栏中定义 target-configs = ["config1"]
######################### Table config ########################## 对部分表进行特殊的配置,配置的表必须包含在 task.target-check-tables 中[table-configs.config1] # config1 是该配置的唯一标识自定义 id,用于上面 task.target-configs 中# 目标表名称,可以使用正则来匹配多个表,但不允许存在一个表同时被多个特殊配置匹配。target-tables = [ "`citizencard-biz`.cc_request_result_log"]#(可选)指定检查的数据的范围,需要符合 sql 中 where 条件的语法range = "id<2"#(可选)指定用于划分 chunk 的列,如果不配置该项,sync-diff-inspector 会选取一些合适的列(主键/唯一键/索引)#index-fields = ["col1","col2"]#(可选)忽略某些列的检查,例如 sync-diff-inspector 目前还不支持的一些类型(json,bit,blob 等),# 或者是浮点类型数据在 TiDB 和 MySQL 中的表现可能存在差异,可以使用 ignore-columns 忽略检查这些列ignore-columns = ["",""]#(可选)指定划分该表的 chunk 的大小,若不指定可以删去或者将其配置为 0。#chunk-size = 0#(可选)指定该表的 collation,若不指定可以删去或者将其配置为空字符串。#collation = ""
复制代码


./sync_diff_inspector –config=./sync.toml 执行比对


注:sync_diff_inspector 可通过如下连接下载


https://download.pingcap.org/tidb-community-toolkit-v6.5.8-linux-amd64.tar.gz


查看比对结果无异常后


1.2.6 正式切换


切换数据库需要停止业务,选择一个晚上,提前报备,切换数据库


切换步骤


  1. 首先停止同步 tiup dmctl –master-addr 10.11.141.160:8261 pause-task smkdm

  2. 修改生成应用对应的数据库连接

  3. 重启应用

  4. 验证业务正常,完成切换

第二次切换过程(tidb 到 tidb)

1.1 选择迁移方式

由于我们的迁移是从 tidb 到 tidb,也很简单,选择通过 br+ticdc 进行迁移。

1.2 部署 br 并迁移全量数据

1.2.1 准备外部存储,这里我们用 minio 来当外部存储


wget https://dl.min.io/server/minio/release/linux-amd64/miniochmod +x minio# 配置访问 minio 的 access-key access-screct-idexport HOST_IP='172.16.6.122' # 替换为实际上游集群 ipexport MINIO_ROOT_USER='minio'export MINIO_ROOT_PASSWORD='miniostorage'# 创建数据目录,  其中 backup 为 bucket 的名称mkdir -p data/backup# 启动 minio, 暴露端口在 6060./minio server ./data --address :6060 &
复制代码


对应 s3 地址为:s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://10.11.142.246:6060&force-path-style=true


1.2.2 上游关闭 gc


SET GLOBAL tidb_gc_enable=FALSE;


1.2.3 上游通过 backup 备份数据


BACKUP DATABASE * TO ‘s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://10.11.142.246:6060&force-path-style=true’ RATE_LIMIT = 120 MB/SECOND;


记录备份完成时的 checkpoint


Destination | Size | BackupTS | Queue Time | Execution Time


s3://backup 1940403955 447850504815116289 2024-02-20 15:28:18 2024-02-20 15:28:18


1.2.4 下游通过 restore 恢复数据


RESTORE DATABASE * FROM ‘s3://backup?access-key=minio&secret-access-key=miniostorage&endpoint=http://10.11.142.246:6060&force-path-style=true’;


| Destination | Size | BackupTS | Queue Time | Execution Time |


s3://backup 1940403955 447850504815116289 447850554199638017 2024-02-20 15:31:24 2024-02-20 15:31:24


1.2.5 通过 sync-diff-inspector 校验数据


类似第一迁移,唯一的区别是需要指定上游的 snapshot


snapshot = “447850504815116289” # 配置为实际的备份时间点

1.3 部署 ticdc 同步增量数据

1.3.1 部署 ticdc 超级简单,直接生成 scale-out.yml


cdc_servers:  - host: 10.11.141.160    gc-ttl: 86400    data_dir: "/data/cdc-data"
复制代码


通过 tiup 一句 scale-out 命令即可完成,注意这里还是在上游部署的 ticdc


tiup cluster scale-out tidb-smk scale-out.yml -p


1.3.2 创建同步任务


tiup cdc cli changefeed create –server=http://10.11.141.160:8300 –sink-uri=“mysql://root:NzRiKjE1dzJwRF5aLVIrc0Uw\@10.11.142.247:4000” –changefeed-id=“upstream-to-downstream” –start-ts=“447850504815116289”


1.3.3 查看同步状态


tiup cdc cli changefeed list –server=http://10.11.141.160:8300


1.3.4 开启上游 gc


SET GLOBAL tidb_gc_enable=TRUE;


1.3.5 正式切换


切换数据库需要停止业务,选择一个晚上,提前报备,切换数据库


切换步骤


  1. 首先停止业务

  2. 停止 cdc 同步

  3. 修改应用连接数据库配置并重启应用

  4. 验证业务正常,完成切换


备注:停止 cdc 同步过程


检查cdc同步时间点--确定晚于停止应用时间
tiup cdc cli changefeed list --server=http://10.11.141.160:8300
# 停止旧集群到新集群的 changefeedtiup cdc cli changefeed pause -c "upstream-to-downstream" --server=http://10.11.141.160:8300
# 查看 changefeed 状态tiup cdc cli changefeed list
复制代码

总结

tidb 的官方文档已经非常详细,基本按照文档进行迁移不会出啥问题。


另外还是建议大家在创建数据库之前就对机器和数据库的配置进行测试和确定,以免跟我一样反复的进行数据库的迁移和切换。


发布于: 刚刚阅读数: 3
用户头像

TiDB 社区官网:https://tidb.net/ 2021-12-15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
两次数据库迁移记录(mysql→tidb,tidb→tidb)_迁移_TiDB 社区干货传送门_InfoQ写作社区