怎样把tidb单表10亿数据量的表迁移到同库另外一张相同字段的分区表中

【 TiDB 使用环境】生产环境 /测试/ Poc
【 TiDB 版本】6.5
【复现路径】
【遇到的问题:问题现象及影响】tidb已经存在的一张10亿数据量的表,没有建分区,想迁移到相同字段带分区的另外一张表中
【资源配置】
【附件:截图/日志/监控】

insert into xxx select * from yyy

需要考虑两点:

  1. 事务过大,需要拆分
  2. 执行超时,可能会被回滚

另外可以参考:


建议按照时间分段读取,插入,减少事务大小,也可以保持一致性

1 个赞

dumpling lighting 逻辑迁

1 个赞

我也建议dumpling lighting迁

1 个赞

dumpling导出数据,官网视频中说一般操作小数据量的表,几十个g以内的,不知道几百个g的表行不行

可以按分区字段,分段插入直接写insert into xxx select * from tb where 分区条件

这种方式是可以的,我们领导想用现有的工具做,因为这种方式效率低,需要维护脚本。

:thinking:维护什么脚本?不是可以批量生成么?像这种只有条件不同的脚本,我都是用concat的方法批量生成,然后扔到查询分析器里执行的。

当然,楼上推荐的工具,如果平时也用的话,可以直接用工具。除了上面的工具,我还推荐用kettle这些etl工具

如果怕数据量多有风险的话,dumpling 导出的时候可以加上条件进行导出数据,

1 个赞

大佬,通过concat批量方式生成能给个案例吗?怎样commit呢?每条语句自动commit是吗?

这个是生成按日期范围插入的语句

select 
	concat("insert into 目标表 select * from 来源表 where c_datetime >= '",datelist,"' and c_datetime < date_add('",datelist,"', INTERVAL 1 day);") 
from calendar
where datelist < '2021-01-11'
order by datelist

calendar是个日历表,网上有很多生成日历表的方法。

语句都是自动commit的,没有额外加事务。我们一般都是初始化切换数据的时候用,不涉及事务一致性问题

1 个赞

对了,还有一种简单的方法,如果你们之前是用的mysql,可以直接用mysqldump做数据导出导入也可以,毕竟mysqldump是装mysql的时候自带的,不用额外安装。

300G应该还能忍受,mysqldump都能搞,dumpling lightning更没问题了

navicat的数据功能传输可以试试,但10亿可能不行

1 个赞

:wink:navicat有版权问题,公司已经要求不让用了。

问下,lightning导入可以指定目标库名和表名吗?因为dumpling导出的insert语句是有表名的,我想换一个表名

lightning 不支持route

  1. 手动改下导出文件里的表名
  2. 按楼下的方法配置route

[[routes]]
schema-pattern = “"
table-pattern = "

target-schema = “"
target-table = "
” 应该是支持的,上面是源端 下面是目标端,映射下

1 个赞

问下,concat生成insert语句后在tidb中怎样触发执行呢?tidb没有存储过程,触发器。

我们做过一个20多亿行的表迁移,和楼主一样的情况,是把普通表转为分区表,方便后面删除历史数据。

  • 我们这边经用flink比较多,所以我是直接用flink来做同步,QPS可以达到5万左右,同步起来很快,缺点是入门门槛高。
  • 如果对flink接触不多或者没接触过,建议还是使用工具导。好的工具一个是 dumpling + lightning,这个是支持多并发导出导入,比较高效,缺点是需要花点时间看下文档。而且 lightning导入是支持配置路由的,即将数据导入到不同表名的表中。上面其他大佬也提供了具体操作方法,我这里不再赘述。
  • 如果楼主时间比较充裕,比如可以花个几天慢慢导入,完全可以用最基础的mysqldump 导出,然后使用 sed 命令改下表名字,然后导入就行。这个方法优势是简单,好操作;缺点是单线程导出导入,比较慢,导出应该比较快,我这边使用mysqldump导出过800GB的表几个小时就导出了,将SQL文件导入10亿行数据预计要2~3天时间,起个后台任务慢慢跑就行。

具体使用哪个方案,根据实际情况来定

1 个赞