TiDB丨 从MySQL迁移至TiDB的常见问题及解决方案

news2024/9/26 3:31:04

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 一、前言
  • 二、GC设置过长的问题
    • 为什么在MySQL里可设置,保留更多的历史数据,而TiDB不行?
    • TiDB中历史版本过多问题及排查方法
  • 二、SQL调优方式对比和SQL调优方法
    • 日常SQL调优分析对比
    • MySQL迁移到TiDB后,可能会遇到的一些SQL调优的工作
  • 三、热点问题
    • 热点的排查与解决
    • 大范围热点处理
  • 四、总结


一、前言

集团有一套业务库,对接淘宝流量。据说每年双11的时候,流量过大都会导致各种问题,苦不堪言。

经过内部评估,我们决定将这套系统从MySQL迁移到更适合大数据量的TIDB上。

经过团队的共同努力,我们完成了迁移,并在2022年“双11”期间经受住了考验,所以本期就跟大家分享一些从MySQL迁移到TIDB,我们遇到的问题,以及最后是如何解决。


二、GC设置过长的问题

由于这套系统之前是跑在MySQL上,所以初期数据库的一些工作,是由MySQL的DBA和我们TiDB团队一起协作完成的。

某一天我们突然发现,集群的druation突然上升,并且是在没有更多请求的情况下,延迟上升了。

经排查发现,是MySQL的dba为了在数据库中保存最近7天的数据,并且实现误操作闪回,将 tidb_gc_life_time 这个参数由1h改成了7d,从而导致tikv中历史版本过多,导致每次磁盘读取会扫描过多的无用数据,导致的整体变慢。

为什么在MySQL里可设置,保留更多的历史数据,而TiDB不行?

基于 MySQL DBA 的操作,我思考了一下:为什么它直接就将GC保留的时间设置长了?

研究发现,MySQL的闪回是通过本地保存binlog日志实现的,且MySQL中,事务的一致性读是通过undo log实现的,所以这里并不会显著的影响正常数据的查询。

在TiDB中,闪回和一致性读是直接依赖本地保留的历史版本数据,直接保存各个版本数据,实现mvcc,再通过GC定期清除历史版本数据。

MySQL在进行mvcc控制的时候,读取历史的版本依赖的是:事务开始时间戳、当前的数据、undo log日志链。

在事务中在读取历史版本数据时,会先找到最新的数据,依靠每行数据自带的回滚指针,去undo log 中找到事务开始时间戳前最近的一个版本,按时间有序的链表查找历史数据。

在这里插入图片描述
而在TiDB中,所有的dml操作都转化为在磁盘中进行追加一行新的数据,最新的数据和历史版本的数据都保留在一起了

在读取数据时,会先将附近版本的数据全部读取,再根据所需版本进行过滤,这样当保留了过多版本的历史数据时,每次读取都会读取很多无用的数据,造成性能开销。

在这里插入图片描述
在这里插入图片描述

TiDB中历史版本过多问题及排查方法

在前面的推文中,我们分享过一期关于历史版本过多的排查方法,比较直观的描述了历史版本数据过多时,对于SQL执行直接的影响,大家有兴趣的可以回看→《一次TiDB GC阻塞引发的性能问题分析》

在这里插入图片描述


二、SQL调优方式对比和SQL调优方法

SQL作为和数据库交互的标准语言,SQL调优是DBA以及数据库使用者绕不开的东西。

这里我们看看相比于MySQL的SQL调优方式,在TiDB中的不同之处,以及将业务从MySQL迁移到TiDB后,SQL方面需要做的一些工作。

日常SQL调优分析对比

在MySQL数据库的日常调优中,免不了有类似需求:

#查询频率
show global status like 'com*'
#查看慢查询日志
cat slow_query.log
#查看sql耗时以及到底耗费在哪里
show profile for query query_id
#查看sql执行计划,分析效率
explain query

而在TiDB中,集群自带的监控dashboard,可以满足所有上述需求,并且还拥有统计功能、top功能、多种条件过滤功能,帮助分析异常以及SQL调优,非常方便。

在这里插入图片描述

MySQL迁移到TiDB后,可能会遇到的一些SQL调优的工作

在MySQL迁移至TiDB后,有一部分原来执行没有性能问题的SQL,在TiDB中出现了性能问题,主要有如下:

1. 偶发性的复杂SQL的连接算子不合理

这类SQL主要表现为比较复杂的SQL,且SQL中的表连接是隐式连接时,出现几率大。

**解决方案:**绑定执行计划,此方案对应用代码没有侵入性,且方便快捷。

2. SQL执行逻辑不佳

在部分复杂SQL中,在不影响SQL最终结果的前提下,先过滤计算某一部分结果作为临时表,会使整个SQL的效率提高。

在部分场景中,MySQL优化器能自动优化处理,TiDB的执行计划不太合理。

**解决方案:**这种通常只有改写SQL,在SQL中去显示的制作临时表。

3. 部分小bug

这种问题通常指某些SQL导致的异常行为,多在后续版本中被修复了。例如某些场景下index hash join算子会存在一些问题,通过hint其他算子可绕过。

解决方案:在github搜索相关issue或者pr,或者社区提问。


三、热点问题

相比于单机的MySQL数据库,分布式TiDB优势之一就是可以利用分布式集群多机器的能力,来突破单机的瓶颈。

但在某些时候,由于数据分布不合理,或者是业务专一的访问某一小部分的数据,这种时候可能会导致分布式集群中单机的瓶颈成为整个集群的瓶颈,这就是热点问题。

热点的排查与解决

通常我们排查热点最常见的方法就是dashboard中的热力图,来确认排查热点,越亮的区域,表示流量越高。

在这里插入图片描述
但是有时候,我们很难去确认哪些流量才是真正达到了某一单机器的瓶颈,我这里提供一个方法:

1、查询都热点,得到region_id和都流量数值
(在一般系统中,70%以上的请求为读请求)
SELECT DISTINCT region_id ,read_bytes 
FROM INFORMATION_SCHEMA.tikv_region_status WHERE ORDER BY READ_BYTES DESC

2、尝试去切分热点region
tiup ctl:v5.3.2 pd -u http://10.0.*.*:2379 operator add split-region $id --policy=scan

3、若观察到切分该region后duration有比较明显的下降,则说明该流量比较容易达到机器瓶颈
(当然一台机器肯定不止只有一个region被访问,所以这里其实是一个观察性质的经验,不是具体某一个数值)

结合确定的流量瓶颈,我写了个简单的脚本挂在crontab,每隔20分钟执行一次,效果不错!


#!/bin/bash

#打印当前时间
echo "############################################">>/home/tidb/log/split-hot-region.log
date>>/home/tidb/log/split-hot-region.log

#查找读流量大于5G的region
hot_id=`mysql -h10.0.*.* -P4000 -uroot -p* -e"SELECT DISTINCT region_id  FROM INFORMATION_SCHEMA.tikv_region_status WHERE  READ_BYTES >5368709120 ORDER BY READ_BYTES DESC"`

#打印热点region_id和读流量到日志
echo "当前读热点为:">>/home/tidb/log/split-hot-region.log
mysql -h10.0.*.* -P4000 -uroot -p**** -e"SELECT DISTINCT region_id ,read_bytes FROM INFORMATION_SCHEMA.tikv_region_status WHERE  READ_BYTES >5368709120 ORDER BY READ_BYTES DESC
">>/home/tidb/log/split-hot-region.log

source  /home/tidb/.bash_profile
for id in $hot_id
do
if [ $id != 'region_id' ];
then
tiup ctl:v5.3.2 pd -u http://10.0.*.*:2379 operator add split-region $id --policy=scan
sleep 1s
tiup ctl:v5.3.2 pd -u http://10.0.*.*:2379 operator add split-region $id --policy=scan
sleep 1s
tiup ctl:v5.3.2 pd -u http://10.0.*.*:2379 operator add split-region $id --policy=scan
sleep 1s
tiup ctl:v5.3.2 pd -u http://10.0.*.*:2379 operator add split-region $id --policy=scan
sleep 1s
tiup ctl:v5.3.2 pd -u http://10.0.*.*:2379 operator add split-region $id --policy=scan
    if [ $? -eq 0 ]; then
        echo "已成功切分region "$id>>/home/tidb/log/split-hot-region.log
    else
        echo "切分region"$id"失败">>/home/tidb/log/split-hot-region.log
    fi
fi
done

当然也可以通过调整系统参数实现。

在这里插入图片描述

大范围热点处理

有些时候,热点可能是由于SQL不合理所导致的,例如对某张表的查询没有建立索引,导致每次都是全表扫之后再过滤,导致大块热点。如果有索引,每次定向读取少量数据,就不会有热点。

排查与解决方案:

通常碰到这种类似问题之后,根据热力图中的表名去查询相关的SQL,去验证执行计划中是否走了索引,后续添加索引

也有一部分为SQL写的不合理,每次请求大量的数据,到应用服务器之后再进行过滤,这种就需要与开发进行讨论添加过滤条件。


四、总结

TiDB作为兼容MySQL的分布式数据库,未来必然会有越来越多的业务从MySQL上面迁移到TiDB,我希望有越来越多的案例和经验可以被分享出来,作为参考。

关于今天的迁移干货分享就到这里了,欢迎大家一起交流~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/140128.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python解题 - CSDN周赛第20期 - 逆波兰 / 后缀表达式

不知不觉已经参加了19场比赛了,由于参赛次数多,排名竟然稀里糊涂地上升到第一,受宠若惊,赶紧截图保存纪念一下。 正好又赶上元旦,新的2023年,希望CSDN的周赛能越办越好,尽量少出bug,…

P1047 [NOIP2005 普及组] 校门外的树

题目 [NOIP2005 普及组] 校门外的树 题目描述 某校大门外长度为 lll 的马路上有一排树,每两棵相邻的树之间的间隔都是 111 米。我们可以把马路看成一个数轴,马路的一端在数轴 000 的位置,另一端在 lll 的位置;数轴上的每个整数…

批量化工程项目的实施过程

最近的批量化项目存在方案设计上的问题,导致很严重的后果。 1、各个相关方都需要投入较大的精力来处理此事; 2、投入的时间、金钱及人员等均在其中; 3、方案需要进行重新的验证,总体项目工程的周期进一步被压缩; 4…

21-InnoDB引擎底层存储和缓存原理

到目前为止,MySQL对于我们来说还是一个黑盒,我们只负责使用客户端发送请求并等待服务器返回结果,表中的数据到底存到了哪里?以什么格式存放的?MySQL是以什么方式来访问的这些数据?这些问题我们统统不知道。…

【C++ Primer】阅读笔记(1):基础

目录 简介类型选择(经验准则)当一个算术表达式既有int,又有无符号数时,int会转换为无符号数对象初始化与赋值的区别声明与定义全局变量与局部变量示例引用指针与引用的区别不可以将int变量直接赋值给指针,即便这个int变量是0const对象必须初始化参考结语简介 Hello! 非常…

pdf转换器电脑版免费,好用的办公操作软件集合

工作中太多的文件格式需要我们进行操作了,各种各样的文件可以打开的软件经常是不同的。就像是PDF文件,如果没有在电脑安装对应的可以打开的软件,可能我们就没办法直接查看文件内容。而且这种情况也不是偶然出现,可能还会随着我们文…

信息系统项目管理师的论文如何提高?

简单点来说吧!也适合软考小白来看! 信息系统项目管理师论文要写几道题?没有参加过信息系统项目管理师考试的考生对于论文科目考试不是很了解,那么信息系统项目管理师论文到底要写几道题呢? 软考高级信息系统项目管理…

振弦采集模块辅助功能寄存器之低功耗休眠

振弦采集模块辅助功能寄存器之低功耗休眠 在收到休眠指令后,完成当次测量后立即进入低功耗的休眠模式,休眠模式下, VDD 电流可降至 1mA 左右,当收到数字接口任意数据后自动唤醒。此功能会使硬件看门狗失效,存在模块意…

关于项目型和职能型组织结构的思考和笔记

1、区别项目型还是职能型,最根本的要点在于,沟通渠道必须通过谁(负责人是谁,是项目经理还是职能经理,谁有沟通渠道控制权); 2、沟通渠道的控制权取决于利益的优先权(例如&#xff1…

前端常用处理时间方法

项目上用到很多时间格式,写了一些处理时间的方法,也可以用第三方库,下面是我自己项目封装的一下方法,命名瞎写的,有些方法是关联的,很多没有怎么完善,记录一下,兼容ios时间问题,时间太赶没有完善,将就用下,人和程序有一个人跑就行 获取当前时间戳 getTodayTomorrowTtem export…

求树的直径(史上最详细,匠心之作,限时免费看)

一,题目SPOJ PT07Z, Longest path in a tree一.定义树上任意两节点之间最长的简单路径即为树的「直径」。二,解法做法 1. 两次 DFS过程:首先从任意节点y, 开始进行第一次 DFS,到达距离其最远的节点,记为 z,然后再从 z开…

ARM S5PV210 中断体系与外部中断实战

一、中断体系介绍 1、什么是中断 中断的发明是用来解决宏观上的并行需要的。宏观就是从整体上来看,多件事情都完成了。微观上的并行,就是指的真正的并行,就是精确到每一秒甚至每一刻,多个事情都是在同时进行的。宏观上面的并行并…

OQC与Cyxtera将量子计算应用于数据中心

牛津量子电路(OQC)正与云服务公司Cyxtera合作,在数据中心安装量子计算机,方便用户在其本地数据集上运行量子算法。 在葡萄牙里本举行的网络峰会上,牛津量子电路(OQC)首席执行官ILana Wisby谈到了…

【力扣经典题目】环形链表,判断链表是否有环

题目描述: 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链…

【Unity】新手初学Animation实现人物移动

【Unity】新手初学Animation实现人物移动 需求:开发影院系统,希望加入Avatar人物,在其中行走和坐下 环境:Unity2021.3 新手初学Animation教程:BV1BW41187fL Avatar人物模型资源:学长网盘链接分享 Animation…

【电动汽车充电站有序充电调度的分散式优化】基于蒙特卡诺和拉格朗日的电动汽车优化调度(分时电价调度)(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

实习------SpringMVC 框架学习

Spring MVC 是什么 (了解)Spring MVC(全称 Spring Web MVC)是 Spring 框架提供的一款基于 MVC 模式的轻量级 Web 开发框架,是 Spring 为表示层(UI)开发提供的一整套完备的解决方案。注&#xff…

《Linux运维总结:使用旧版redis-shake2.x进行redis集群间的数据同步【方案二】》

一、redis-shake简介 redis-shake是阿里云开源的用于Redis数据迁移和过滤的工具。 Github参考:redis-shake简介 1.1、迁移工具对比 redis-migrate-tool redis-migrate-tool是唯品会开源的一款Redis异构集群之间的数据实时迁移工具,不过已经有两年没有更…

如何对【javaSE】语法阶段复习

下面是我对学习java阶段的总复习,我愿称之为【复习宝典】 如果你对java的部分语法阶段的知识有所困惑,进来看看吧! 文章目录 目录 文章目录 一、初始java 1.1java 的由来 1.2JDK安装 1.3main方法的介绍 二、数据类型和变量 2.1数据类型 三、运…

xxljob 里面 InheritableThreadLocal详解,XxlJobContext类的详解

目录 1 需求2 XxlJobContext类3 InheritableThreadLocal 类可以做什么1 需求 在xxljob 里面,有一个地方使用到了InheritableThreadLocal类 我们先说XxlJobContext类是干什么的,里面有什么东西 2 XxlJobContext类 这个类就是一个实体类,可以理解为实体类,里面有属性,有g…